Merge pull request #1 from synebula-myths/dev

Dev
This commit is contained in:
2022-08-26 10:47:38 +08:00
committed by GitHub
66 changed files with 618 additions and 455 deletions

View File

@@ -1,11 +1,11 @@
buildscript { buildscript {
ext { ext {
kotlin_version = '1.3.72' kotlin_version = '1.6.10'
} }
repositories { repositories {
mavenLocal() mavenLocal()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral() mavenCentral()
} }
@@ -14,42 +14,39 @@ buildscript {
} }
} }
allprojects { subprojects {
group 'com.synebula' group 'com.synebula'
version version version version
}
subprojects {
ext { ext {
version '0.5.2' version '0.9.0'
gaea_version = '0.6.1' gaea_version = '1.4.0'
spring_version = "2.3.0.RELEASE" spring_version = "2.7.0"
} }
buildscript { buildscript {
repositories { repositories {
mavenLocal() mavenLocal()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral() mavenCentral()
} }
} }
repositories { repositories {
mavenLocal() mavenLocal()
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
mavenCentral() mavenCentral()
} }
apply plugin: 'idea' apply plugin: 'idea'
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'kotlin' apply plugin: 'kotlin'
apply plugin: 'maven'
apply plugin: 'maven-publish' apply plugin: 'maven-publish'
dependencies { dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" api "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" api "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
testCompile group: 'junit', name: 'junit', version: '4.12' testApi group: 'junit', name: 'junit', version: '4.12'
} }
sourceCompatibility = 1.8 sourceCompatibility = 1.8

View File

@@ -4,3 +4,5 @@ include 'src:zeus.app'
include 'src:zeus.domain' include 'src:zeus.domain'
include 'src:zeus.query' include 'src:zeus.query'
include 'src:zeus.env' include 'src:zeus.env'
include 'src:zeus.repository'

View File

@@ -1,20 +1,23 @@
buildscript { buildscript {
dependencies { dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:$spring_version") classpath("org.springframework.boot:spring-boot-gradle-plugin:$spring_version")
classpath("org.jetbrains.kotlin:kotlin-allopen:$kotlin_version")
} }
} }
apply plugin: 'org.springframework.boot' apply plugin: 'org.springframework.boot'
apply plugin: 'kotlin-spring'
jar.enabled = true //jar SKIPPED问题,不设置可能会无法打jar jar.enabled = true //jar SKIPPED问题,不设置可能会无法打jar
dependencies { dependencies {
compile project(":src:zeus.domain") api project(":src:zeus.domain")
compile project(":src:zeus.query") api project(":src:zeus.query")
compile "com.synebula:gaea.app:$gaea_version" api project(":src:zeus.repository")
compile "com.synebula:gaea.mongo:$gaea_version" api "com.synebula:gaea.app:$gaea_version"
api "com.synebula:gaea.spring:$gaea_version"
api "com.synebula:gaea.mongodb:$gaea_version"
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
} }
publishing { publishing {

View File

@@ -0,0 +1,15 @@
package com.synebula.zeus.app.component
import com.synebula.gaea.spring.aop.AppAspect
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Pointcut
import org.springframework.stereotype.Component
@Aspect
@Component
class ZeusAspect : AppAspect() {
@Pointcut("target(com.synebula.gaea.app.IApplication)")
override fun func() {
}
}

View File

@@ -1,37 +1,42 @@
package com.synebula.zeus.app.config package com.synebula.zeus.app.config
import com.google.gson.Gson import com.google.gson.Gson
import com.synebula.gaea.app.component.security.WebSecurity
import com.synebula.gaea.data.serialization.json.IJsonSerializer import com.synebula.gaea.data.serialization.json.IJsonSerializer
import com.synebula.gaea.domain.model.IAggregateRoot import com.synebula.gaea.domain.repository.IRepositoryFactory
import com.synebula.gaea.domain.repository.IRepository import com.synebula.gaea.mongodb.query.MongodbQueryFactory
import com.synebula.gaea.log.ILogger import com.synebula.gaea.mongodb.repository.MongodbRepositoryFactory
import com.synebula.gaea.mongo.query.MongoQuery import com.synebula.gaea.query.IQueryFactory
import com.synebula.gaea.mongo.repository.MongoRepository
import com.synebula.gaea.query.IQuery
import com.synebula.zeus.domain.service.contr.component.IUserNotifier
import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.ComponentScan.Filter
import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Primary import org.springframework.context.annotation.FilterType
import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.data.mongodb.core.MongoTemplate
@Configuration @Configuration
open class ZeusBeans { @ComponentScan(
@Bean basePackages = ["com.synebula.gaea.app.component"],
@Primary excludeFilters = [Filter(type = FilterType.ASSIGNABLE_TYPE, classes = [WebSecurity::class])]
open fun <T : IAggregateRoot<String>> repository(template: MongoTemplate) )
: IRepository = MongoRepository(template) class ZeusBeans {
@Bean @Bean
@Primary fun repoFactory(template: MongoTemplate): IRepositoryFactory {
open fun <T> query(template: MongoTemplate, logger: ILogger? = null) return MongodbRepositoryFactory(template)
: IQuery = MongoQuery(template, logger) }
@Bean @Bean
open fun gson(): Gson = Gson() fun queryFactory(template: MongoTemplate): IQueryFactory {
return MongodbQueryFactory(template)
}
@Bean @Bean
open fun serializer(gson: Gson): IJsonSerializer { fun gson(): Gson = Gson()
@Bean
fun serializer(gson: Gson): IJsonSerializer {
return object : IJsonSerializer { return object : IJsonSerializer {
override fun <S> serialize(src: S): String { override fun <S> serialize(src: S): String {
return gson.toJson(src) return gson.toJson(src)

View File

@@ -0,0 +1,10 @@
package com.synebula.zeus.app.config
import com.synebula.gaea.app.autoconfig.service.ServiceScan
import com.synebula.gaea.mongodb.autoconfig.MongodbRepositoryScan
import org.springframework.stereotype.Component
@Component
@ServiceScan(basePackages = ["com.synebula.zeus.domain.service"])
@MongodbRepositoryScan(basePackages = ["com.synebula.zeus.domain.repository", "com.synebula.zeus.repository", "com.synebula.zeus.query"])
class ZeusServices

View File

@@ -1,18 +0,0 @@
package com.synebula.zeus.app.config
import com.synebula.gaea.app.component.AllTypeFilter
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.ComponentScan.Filter
import org.springframework.context.annotation.FilterType
import org.springframework.stereotype.Component
@Component
@ComponentScan(
basePackages = [
"com.synebula.gaea.app.component",
"com.synebula.zeus.domain.service.impl",
"com.synebula.zeus.query.impl"
],
includeFilters = [Filter(type = FilterType.CUSTOM, classes = [AllTypeFilter::class])]
)
class ZeusSpring

View File

@@ -1,31 +1,73 @@
package com.synebula.zeus.app.controller package com.synebula.zeus.app.controller
import com.synebula.gaea.app.IApplication import com.synebula.gaea.app.IApplication
import com.synebula.gaea.app.component.HttpMessage import com.synebula.gaea.app.component.security.TokenManager
import com.synebula.gaea.data.message.HttpMessage
import com.synebula.gaea.data.message.Status
import com.synebula.gaea.data.serialization.json.IJsonSerializer
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import com.synebula.gaea.spring.aop.annotation.Method
import com.synebula.zeus.domain.service.cmd.rbac.UserCmd
import com.synebula.zeus.domain.service.contr.rbac.IUserService
import com.synebula.zeus.query.contr.IUserQuery import com.synebula.zeus.query.contr.IUserQuery
import com.synebula.zeus.query.impl.UserQuery import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController import org.springframework.web.bind.annotation.RestController
@RestController @RestController
@RequestMapping("/sign") @RequestMapping("/sign")
class SignInOutApp(template: MongoTemplate, override var logger: ILogger?) : IApplication { class SignInOutApp(override var logger: ILogger) : IApplication {
var query: IUserQuery = UserQuery(template)
@Autowired
lateinit var userQuery: IUserQuery
@Autowired
lateinit var userService: IUserService
@Autowired
lateinit var tokenHelper: TokenManager
@Autowired
lateinit var serializer: IJsonSerializer
override var name: String = "用户登录管理" override var name: String = "用户登录管理"
@Method("用户登录")
@PostMapping("/in") @PostMapping("/in")
fun signIn(name: String, password: String): HttpMessage { fun signIn(name: String, password: String, remember: Boolean?): HttpMessage {
return this.safeExecute("用户登录出现异常") { return this.safeExecute("用户登录出现异常") {
it.load(this.query.signIn(name, password)) val message = this.userQuery.signIn(name, password)
if (message.data != null) {
val user = message.data
user!!.remember = remember ?: false
val token = tokenHelper.sign(message.data!!)
it.data = token
} else {
it.load(message)
}
} }
} }
@Method("用户登出")
@PostMapping("/out") @PostMapping("/out")
fun signOut(user: String): HttpMessage { fun signOut(user: String): HttpMessage {
return HttpMessage(user) return HttpMessage(user)
} }
@Method("用户注册")
@PostMapping("/up")
fun signUp(@RequestBody command: UserCmd): HttpMessage {
return this.safeExecute("用户注册出错, 用户信息: ${serializer.serialize(command)}") {
val list = this.userQuery.list(mapOf(Pair("name", command.name)))
if (list.isEmpty()) {
val message = userService.add(command)
it.data = message.data
} else {
it.status = Status.Failure
it.message = "系统中已存在该用户"
}
}
}
} }

View File

@@ -0,0 +1,41 @@
package com.synebula.zeus.app.controller.rbac
import com.synebula.gaea.app.Application
import com.synebula.gaea.data.message.HttpMessage
import com.synebula.gaea.log.ILogger
import com.synebula.gaea.spring.aop.annotation.Method
import com.synebula.zeus.domain.service.cmd.rbac.AuthorityBatchAddCmd
import com.synebula.zeus.domain.service.cmd.rbac.AuthorityCmd
import com.synebula.zeus.domain.service.contr.rbac.IAuthorityService
import com.synebula.zeus.env.ResourceType
import com.synebula.zeus.query.contr.IAuthorityQuery
import com.synebula.zeus.query.view.AuthorityView
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/authorities")
class AuthorityApp(
query: IAuthorityQuery,
logger: ILogger,
private var authorityService: IAuthorityService
) : Application<AuthorityCmd, AuthorityView, String>(
"权限信息", authorityService, query, logger
) {
@Method("批量添加权限信息")
@PostMapping("/batch")
fun add(@RequestBody cmd: AuthorityBatchAddCmd): HttpMessage {
this.authorityService.add(cmd)
return HttpMessage()
}
@Method("根据资源和角色删除权限")
@DeleteMapping("/{type}/role/{role}")
fun removeByResourceRole(
@PathVariable type: ResourceType,
@PathVariable role: String,
@RequestBody resource: List<String>
): HttpMessage {
this.authorityService.removeByResourceRole(type, resource, role)
return HttpMessage()
}
}

View File

@@ -2,7 +2,7 @@ package com.synebula.zeus.app.controller.rbac
import com.synebula.gaea.app.Application import com.synebula.gaea.app.Application
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import com.synebula.gaea.query.IQuery import com.synebula.gaea.query.IQueryFactory
import com.synebula.zeus.domain.service.cmd.rbac.GroupCmd import com.synebula.zeus.domain.service.cmd.rbac.GroupCmd
import com.synebula.zeus.domain.service.contr.rbac.IGroupService import com.synebula.zeus.domain.service.contr.rbac.IGroupService
import com.synebula.zeus.query.view.GroupView import com.synebula.zeus.query.view.GroupView
@@ -13,9 +13,8 @@ import org.springframework.web.bind.annotation.RestController
@RequestMapping("/groups") @RequestMapping("/groups")
class GroupApp( class GroupApp(
service: IGroupService, service: IGroupService,
query: IQuery, factory: IQueryFactory,
logger: ILogger logger: ILogger
) : Application<GroupCmd, GroupView, String>( ) : Application<GroupCmd, GroupView, String>(
"组信息", GroupView::class.java, "用户组信息", service, factory.createQuery(GroupView::class.java), logger
service, query, logger
) )

View File

@@ -2,7 +2,7 @@ package com.synebula.zeus.app.controller.rbac
import com.synebula.gaea.app.Application import com.synebula.gaea.app.Application
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import com.synebula.gaea.query.IQuery import com.synebula.gaea.query.IQueryFactory
import com.synebula.zeus.domain.service.cmd.rbac.RoleCmd import com.synebula.zeus.domain.service.cmd.rbac.RoleCmd
import com.synebula.zeus.domain.service.contr.rbac.IRoleService import com.synebula.zeus.domain.service.contr.rbac.IRoleService
import com.synebula.zeus.query.view.RoleView import com.synebula.zeus.query.view.RoleView
@@ -13,9 +13,8 @@ import org.springframework.web.bind.annotation.RestController
@RequestMapping("/roles") @RequestMapping("/roles")
class RoleApp( class RoleApp(
service: IRoleService, service: IRoleService,
query: IQuery, factory: IQueryFactory,
logger: ILogger logger: ILogger
) : Application<RoleCmd, RoleView, String>( ) : Application<RoleCmd, RoleView, String>(
"用户信息", RoleView::class.java, "用户信息", service, factory.createQuery(RoleView::class.java), logger
service, query, logger
) )

View File

@@ -1,13 +1,13 @@
package com.synebula.zeus.app.controller.rbac package com.synebula.zeus.app.controller.rbac
import com.synebula.gaea.app.Application import com.synebula.gaea.app.Application
import com.synebula.gaea.app.component.HttpMessage import com.synebula.gaea.data.message.HttpMessage
import com.synebula.gaea.data.message.Status import com.synebula.gaea.data.message.Status
import com.synebula.gaea.data.serialization.json.IJsonSerializer import com.synebula.gaea.data.serialization.json.IJsonSerializer
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import com.synebula.gaea.query.IQuery
import com.synebula.zeus.domain.service.cmd.rbac.UserCmd import com.synebula.zeus.domain.service.cmd.rbac.UserCmd
import com.synebula.zeus.domain.service.contr.rbac.IUserService import com.synebula.zeus.domain.service.contr.rbac.IUserService
import com.synebula.zeus.query.contr.IUserQuery
import com.synebula.zeus.query.view.UserView import com.synebula.zeus.query.view.UserView
import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.* import org.springframework.web.bind.annotation.*
@@ -16,11 +16,10 @@ import org.springframework.web.bind.annotation.*
@RequestMapping("/users") @RequestMapping("/users")
class UserApp( class UserApp(
service: IUserService, service: IUserService,
query: IQuery, query: IUserQuery,
logger: ILogger logger: ILogger
) : Application<UserCmd, UserView, String>( ) : Application<UserCmd, UserView, String>(
"用户信息", UserView::class.java, "用户信息", service, query, logger
service, query, logger
) { ) {
@Autowired @Autowired
@@ -28,8 +27,8 @@ class UserApp(
override fun add(command: UserCmd): HttpMessage { override fun add(command: UserCmd): HttpMessage {
return this.safeExecute("查询重复用户信息出错, 用户信息: ${serializer.serialize(command)}") { return this.safeExecute("查询重复用户信息出错, 用户信息: ${serializer.serialize(command)}") {
val list = this.query!!.list(mapOf(Pair("name", command.name)), UserView::class.java) val list = this.query.list(mapOf(Pair("name", command.name)))
if (list.count() == 0) if (list.isEmpty())
it.from(super.add(command)) it.from(super.add(command))
else { else {
it.status = Status.Failure it.status = Status.Failure
@@ -54,8 +53,8 @@ class UserApp(
@GetMapping("/{name}/forgot") @GetMapping("/{name}/forgot")
fun forgot(@PathVariable name: String): HttpMessage { fun forgot(@PathVariable name: String): HttpMessage {
return this.safeExecute("遗忘用户密码出现异常") { return this.safeExecute("遗忘用户密码出现异常") {
val users = this.query?.list(mapOf(Pair("name", name)), UserView::class.java) val users = this.query.list(mapOf(Pair("name", name)))
if (users != null && users.isNotEmpty()) { if (users.isNotEmpty()) {
it.load((this.service as IUserService).forgotPassword(users[0].id)) it.load((this.service as IUserService).forgotPassword(users[0].id))
} else { } else {

View File

@@ -1,8 +1,9 @@
package com.synebula.zeus.app.controller.rbac.resource package com.synebula.zeus.app.controller.rbac.resource
import com.synebula.gaea.app.Application import com.synebula.gaea.app.Application
import com.synebula.gaea.app.component.HttpMessage import com.synebula.gaea.data.message.HttpMessage
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import com.synebula.gaea.spring.aop.annotation.Method
import com.synebula.zeus.domain.service.cmd.rbac.resource.InterfaceCmd import com.synebula.zeus.domain.service.cmd.rbac.resource.InterfaceCmd
import com.synebula.zeus.domain.service.contr.rbac.resource.IInterfaceService import com.synebula.zeus.domain.service.contr.rbac.resource.IInterfaceService
import com.synebula.zeus.query.contr.resouce.IInterfaceQuery import com.synebula.zeus.query.contr.resouce.IInterfaceQuery
@@ -19,28 +20,30 @@ class InterfaceApp(
logger: ILogger, logger: ILogger,
var interfaceQuery: IInterfaceQuery var interfaceQuery: IInterfaceQuery
) : Application<InterfaceCmd, InterfaceView, String>( ) : Application<InterfaceCmd, InterfaceView, String>(
"接口信息", InterfaceView::class.java, "接口信息", service, interfaceQuery, logger
service, interfaceQuery, logger
) { ) {
@GetMapping("/in-system/{system}/permission/{role}") @Method("获取角色系统下有权接口")
fun withSystemPermission(@PathVariable system: String, @PathVariable role: String): HttpMessage { @GetMapping("/in-system/{system}/authorized/{role}")
fun authorized(@PathVariable system: String, @PathVariable role: String): HttpMessage {
return this.safeExecute("获取有权资源列表失败") { msg -> return this.safeExecute("获取有权资源列表失败") { msg ->
msg.data = this.interfaceQuery.withPermission(role, system) msg.data = this.interfaceQuery.authorized(role, system)
} }
} }
@GetMapping("/permission/{role}") @Method("获取角色全部有权接口")
fun withPermission(@PathVariable role: String): HttpMessage { @GetMapping("/authorized/{role}")
fun authorized(@PathVariable role: String): HttpMessage {
return this.safeExecute("获取有权资源列表失败") { msg -> return this.safeExecute("获取有权资源列表失败") { msg ->
msg.data = this.interfaceQuery.withPermission(role) msg.data = this.interfaceQuery.authorized(role)
} }
} }
@GetMapping("/{api}/authentication/{role}") @Method("验证角色接口权限")
fun authentication(@PathVariable api: String, @PathVariable role: String): HttpMessage { @GetMapping("/{api}/authorize/{role}")
fun authorize(@PathVariable api: String, @PathVariable role: String): HttpMessage {
return this.safeExecute("获取权限信息失败") { msg -> return this.safeExecute("获取权限信息失败") { msg ->
msg.data = this.interfaceQuery.authentication(api, role) msg.data = this.interfaceQuery.authorize(api, role)
} }
} }
} }

View File

@@ -1,8 +1,10 @@
package com.synebula.zeus.app.controller.rbac.resource package com.synebula.zeus.app.controller.rbac.resource
import com.synebula.gaea.app.Application import com.synebula.gaea.app.Application
import com.synebula.gaea.app.component.HttpMessage import com.synebula.gaea.data.message.HttpMessage
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import com.synebula.gaea.spring.aop.annotation.Method
import com.synebula.gaea.spring.aop.annotation.Module
import com.synebula.zeus.domain.service.cmd.rbac.resource.PageCmd import com.synebula.zeus.domain.service.cmd.rbac.resource.PageCmd
import com.synebula.zeus.domain.service.contr.rbac.resource.IPageService import com.synebula.zeus.domain.service.contr.rbac.resource.IPageService
import com.synebula.zeus.query.contr.resouce.IPageQuery import com.synebula.zeus.query.contr.resouce.IPageQuery
@@ -14,40 +16,44 @@ import org.springframework.web.bind.annotation.RestController
@RestController @RestController
@RequestMapping("/pages") @RequestMapping("/pages")
@Module("页面")
class PageApp( class PageApp(
service: IPageService, service: IPageService,
logger: ILogger, logger: ILogger,
var pageQuery: IPageQuery var pageQuery: IPageQuery
) : Application<PageCmd, PageView, String>( ) : Application<PageCmd, PageView, String>(
"页面信息", PageView::class.java, "页面信息", service, pageQuery, logger
service, pageQuery, logger
) { ) {
@GetMapping("/in-system/{system}/permission/{role}") @Method("获取角色系统下有权页面")
fun withSystemPermission(@PathVariable system: String, @PathVariable role: String): HttpMessage { @GetMapping("/in-system/{system}/authorized/{role}")
fun authorized(@PathVariable system: String, @PathVariable role: String): HttpMessage {
val msg = HttpMessage()
msg.data = this.pageQuery.authorized(role, system)
return msg
}
@Method("获取角色全部有权页面")
@GetMapping("/authorized/{role}")
fun authorized(@PathVariable role: String): HttpMessage {
return this.safeExecute("获取有权资源列表失败") { msg -> return this.safeExecute("获取有权资源列表失败") { msg ->
msg.data = this.pageQuery.withPermission(role, system) msg.data = this.pageQuery.authorized(role)
} }
} }
@GetMapping("/permission/{role}") @Method("验证角色页面权限")
fun withPermission(@PathVariable role: String): HttpMessage { @GetMapping("/{page}/authorize/{role}")
return this.safeExecute("获取有权资源列表失败") { msg -> fun authorize(@PathVariable page: String, @PathVariable role: String): HttpMessage {
msg.data = this.pageQuery.withPermission(role)
}
}
@GetMapping("/{page}/authentication/{role}")
fun authentication(@PathVariable page: String, @PathVariable role: String): HttpMessage {
return this.safeExecute("获取权限信息失败") { msg -> return this.safeExecute("获取权限信息失败") { msg ->
msg.data = this.pageQuery.authentication(page, role) msg.data = this.pageQuery.authorize(page, role)
} }
} }
@GetMapping("/authentication/{role}") @Method("验证角色URL权限")
fun uriAuthentication(@PathVariable role: String, uri: String): HttpMessage { @GetMapping("/authorize/{role}")
fun uriAuthorize(@PathVariable role: String, uri: String): HttpMessage {
return this.safeExecute("获取权限信息失败") { msg -> return this.safeExecute("获取权限信息失败") { msg ->
msg.data = this.pageQuery.uriAuthentication(uri, role) msg.data = this.pageQuery.uriAuthorize(uri, role)
} }
} }

View File

@@ -1,21 +0,0 @@
package com.synebula.zeus.app.controller.rbac.resource
import com.synebula.gaea.app.Application
import com.synebula.gaea.log.ILogger
import com.synebula.zeus.domain.service.cmd.rbac.resource.PermissionCmd
import com.synebula.zeus.domain.service.contr.rbac.resource.IPermissionService
import com.synebula.zeus.query.contr.resouce.IPermissionQuery
import com.synebula.zeus.query.view.resource.PermissionView
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/permissions")
class PermissionApp(
service: IPermissionService,
query: IPermissionQuery,
logger: ILogger
) : Application<PermissionCmd, PermissionView, String>(
"权限信息", PermissionView::class.java,
service, query, logger
)

View File

@@ -1,8 +1,9 @@
package com.synebula.zeus.app.controller.rbac.resource package com.synebula.zeus.app.controller.rbac.resource
import com.synebula.gaea.app.Application import com.synebula.gaea.app.Application
import com.synebula.gaea.app.component.HttpMessage import com.synebula.gaea.data.message.HttpMessage
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import com.synebula.gaea.spring.aop.annotation.Method
import com.synebula.zeus.domain.service.cmd.rbac.resource.SystemCmd import com.synebula.zeus.domain.service.cmd.rbac.resource.SystemCmd
import com.synebula.zeus.domain.service.contr.rbac.resource.ISystemService import com.synebula.zeus.domain.service.contr.rbac.resource.ISystemService
import com.synebula.zeus.query.contr.resouce.ISystemQuery import com.synebula.zeus.query.contr.resouce.ISystemQuery
@@ -19,20 +20,21 @@ class SystemApp(
logger: ILogger, logger: ILogger,
var systemQuery: ISystemQuery var systemQuery: ISystemQuery
) : Application<SystemCmd, SystemView, String>( ) : Application<SystemCmd, SystemView, String>(
"系统信息", SystemView::class.java, "系统信息", service, systemQuery, logger
service, systemQuery, logger
) { ) {
@GetMapping("/permission/{role}") @Method("获取角色有权系统")
fun withPermission(@PathVariable role: String): HttpMessage { @GetMapping("/authorized/{role}")
fun authorized(@PathVariable role: String): HttpMessage {
return this.safeExecute("获取有权资源列表失败") { msg -> return this.safeExecute("获取有权资源列表失败") { msg ->
msg.data = this.systemQuery.withPermission(role) msg.data = this.systemQuery.authorized(role)
} }
} }
@GetMapping("/{system}/authentication/{role}") @Method("验证角色系统权限")
fun authentication(@PathVariable system: String, @PathVariable role: String): HttpMessage { @GetMapping("/{system}/authorize/{role}")
fun authorize(@PathVariable system: String, @PathVariable role: String): HttpMessage {
return this.safeExecute("获取权限信息失败") { msg -> return this.safeExecute("获取权限信息失败") { msg ->
msg.data = this.systemQuery.authentication(system, role) msg.data = this.systemQuery.authorize(system, role)
} }
} }
} }

View File

@@ -1,6 +1,6 @@
dependencies { dependencies {
compile project(":src:zeus.env") api project(":src:zeus.env")
compile "com.synebula:gaea:$gaea_version" api "com.synebula:gaea:$gaea_version"
} }
publishing { publishing {

View File

@@ -0,0 +1,19 @@
package com.synebula.zeus.domain.model.rbac
import com.synebula.gaea.domain.model.AggregateRoot
import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.env.ResourceType
class Authority(override var id: String? = null) : AggregateRoot<String>() {
var role = ""
var resource = ""
var type: ResourceType? = null
var authority = AuthorityType.Allow
constructor(role: String, resource: String, type: ResourceType?, authority: AuthorityType) : this() {
this.role = role
this.resource = resource
this.type = type
this.authority = authority
}
}

View File

@@ -4,4 +4,5 @@ import com.synebula.gaea.domain.model.AggregateRoot
class Group(override var id: String? = null) : AggregateRoot<String>() { class Group(override var id: String? = null) : AggregateRoot<String>() {
var name = "" var name = ""
var desc = ""
} }

View File

@@ -2,6 +2,7 @@ package com.synebula.zeus.domain.model.rbac
import com.synebula.gaea.domain.model.AggregateRoot import com.synebula.gaea.domain.model.AggregateRoot
class Role(override var id: String?) : AggregateRoot<String>() { class Role(override var id: String? = null) : AggregateRoot<String>() {
var name = "" var name = ""
var desc = ""
} }

View File

@@ -1,12 +0,0 @@
package com.synebula.zeus.domain.model.rbac.resource
import com.synebula.gaea.domain.model.AggregateRoot
import com.synebula.zeus.env.PermissionType
import com.synebula.zeus.env.ResourceType
class Permission(override var id: String? = null) : AggregateRoot<String>() {
var role = ""
var resource = ""
var type: ResourceType? = null
var authority = PermissionType.Allow
}

View File

@@ -0,0 +1,9 @@
package com.synebula.zeus.domain.repository.rbac
import com.synebula.gaea.domain.repository.IRepository
import com.synebula.zeus.domain.model.rbac.Authority
import com.synebula.zeus.env.ResourceType
interface IAuthorityRepository : IRepository<Authority, String> {
fun removeByResourceRole(type: ResourceType, resource: List<String>, role: String)
}

View File

@@ -0,0 +1,7 @@
package com.synebula.zeus.domain.repository.rbac
import com.synebula.gaea.domain.repository.IRepository
import com.synebula.zeus.domain.model.rbac.User
interface IUserRepository : IRepository<User, String> {
}

View File

@@ -0,0 +1,12 @@
package com.synebula.zeus.domain.service.cmd.rbac
import com.synebula.gaea.domain.service.Command
import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.env.ResourceType
class AuthorityBatchAddCmd : Command() {
var role = ""
var resource = listOf<String>()
var type: ResourceType? = null
var authority = AuthorityType.Allow
}

View File

@@ -1,13 +1,13 @@
package com.synebula.zeus.domain.service.cmd.rbac.resource package com.synebula.zeus.domain.service.cmd.rbac
import com.synebula.gaea.domain.service.Command import com.synebula.gaea.domain.service.Command
import com.synebula.zeus.env.PermissionType import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.env.ResourceType import com.synebula.zeus.env.ResourceType
class PermissionCmd : Command() { class AuthorityCmd : Command() {
var id: String? = null var id: String? = null
var role = "" var role = ""
var resource = "" var resource = ""
var type: ResourceType? = null var type: ResourceType? = null
var authority = PermissionType.Allow var authority = AuthorityType.Allow
} }

View File

@@ -5,4 +5,5 @@ import com.synebula.gaea.domain.service.Command
class GroupCmd : Command() { class GroupCmd : Command() {
var id: String? = null var id: String? = null
var name = "" var name = ""
var desc = ""
} }

View File

@@ -5,4 +5,5 @@ import com.synebula.gaea.domain.service.Command
class RoleCmd : Command() { class RoleCmd : Command() {
var id: String? = null var id: String? = null
var name = "" var name = ""
var desc = ""
} }

View File

@@ -1,4 +1,4 @@
package com.synebula.zeus.domain.service.contr.component package com.synebula.zeus.domain.service.component
interface IUserNotifier { interface IUserNotifier {
fun added(id: String, name: String, token: String) fun added(id: String, name: String, token: String)

View File

@@ -0,0 +1,13 @@
package com.synebula.zeus.domain.service.contr.rbac
import com.synebula.gaea.domain.service.IService
import com.synebula.zeus.domain.service.cmd.rbac.AuthorityBatchAddCmd
import com.synebula.zeus.env.ResourceType
interface IAuthorityService : IService<String> {
fun add(cmd: AuthorityBatchAddCmd)
fun removeByResourceRole(type: ResourceType, resource: List<String>, role: String)
}

View File

@@ -1,7 +1,8 @@
package com.synebula.zeus.domain.service.contr.rbac package com.synebula.zeus.domain.service.contr.rbac
import com.synebula.gaea.domain.service.Domain
import com.synebula.gaea.domain.service.IService import com.synebula.gaea.domain.service.IService
import com.synebula.zeus.domain.model.rbac.Group
interface IGroupService : IService<String> { @Domain(clazz = Group::class)
interface IGroupService : IService<String>
}

View File

@@ -1,7 +1,8 @@
package com.synebula.zeus.domain.service.contr.rbac package com.synebula.zeus.domain.service.contr.rbac
import com.synebula.gaea.domain.service.Domain
import com.synebula.gaea.domain.service.IService import com.synebula.gaea.domain.service.IService
import com.synebula.zeus.domain.model.rbac.Role
interface IRoleService : IService<String> { @Domain(clazz = Role::class)
interface IRoleService : IService<String>
}

View File

@@ -1,7 +1,8 @@
package com.synebula.zeus.domain.service.contr.rbac.resource package com.synebula.zeus.domain.service.contr.rbac.resource
import com.synebula.gaea.domain.service.Domain
import com.synebula.gaea.domain.service.IService import com.synebula.gaea.domain.service.IService
import com.synebula.zeus.domain.model.rbac.resource.Interface
interface IInterfaceService : IService<String> { @Domain(clazz = Interface::class)
interface IInterfaceService : IService<String>
}

View File

@@ -1,7 +1,8 @@
package com.synebula.zeus.domain.service.contr.rbac.resource package com.synebula.zeus.domain.service.contr.rbac.resource
import com.synebula.gaea.domain.service.Domain
import com.synebula.gaea.domain.service.IService import com.synebula.gaea.domain.service.IService
import com.synebula.zeus.domain.model.rbac.resource.Page
interface IPageService : IService<String> { @Domain(clazz = Page::class)
interface IPageService : IService<String>
}

View File

@@ -1,7 +0,0 @@
package com.synebula.zeus.domain.service.contr.rbac.resource
import com.synebula.gaea.domain.service.IService
interface IPermissionService : IService<String> {
}

View File

@@ -1,7 +1,8 @@
package com.synebula.zeus.domain.service.contr.rbac.resource package com.synebula.zeus.domain.service.contr.rbac.resource
import com.synebula.gaea.domain.service.Domain
import com.synebula.gaea.domain.service.IService import com.synebula.gaea.domain.service.IService
import com.synebula.zeus.domain.model.rbac.resource.System
interface ISystemService : IService<String> { @Domain(clazz = System::class)
interface ISystemService : IService<String>
}

View File

@@ -0,0 +1,25 @@
package com.synebula.zeus.domain.service.impl.rbac
import com.synebula.gaea.data.serialization.IObjectMapper
import com.synebula.gaea.domain.service.Service
import com.synebula.zeus.domain.model.rbac.Authority
import com.synebula.zeus.domain.repository.rbac.IAuthorityRepository
import com.synebula.zeus.domain.service.cmd.rbac.AuthorityBatchAddCmd
import com.synebula.zeus.domain.service.contr.rbac.IAuthorityService
import com.synebula.zeus.env.ResourceType
class AuthorityService(
private var authorityRepository: IAuthorityRepository,
mapper: IObjectMapper
) : Service<Authority, String>(Authority::class.java, authorityRepository, mapper),
IAuthorityService {
override fun add(cmd: AuthorityBatchAddCmd) {
val authorities = cmd.resource.map { Authority(cmd.role, it, cmd.type, cmd.authority) }
this.repository.add(authorities)
}
override fun removeByResourceRole(type: ResourceType, resource: List<String>, role: String) {
this.authorityRepository.removeByResourceRole(type, resource, role)
}
}

View File

@@ -1,13 +0,0 @@
package com.synebula.zeus.domain.service.impl.rbac
import com.synebula.gaea.data.IObjectConverter
import com.synebula.gaea.domain.repository.IRepository
import com.synebula.gaea.domain.service.Service
import com.synebula.gaea.log.ILogger
import com.synebula.zeus.domain.model.rbac.Group
import com.synebula.zeus.domain.service.contr.rbac.IGroupService
class GroupService(
repository: IRepository,
converter: IObjectConverter, logger: ILogger
) : Service<Group, String>(Group::class.java, repository, converter, logger), IGroupService

View File

@@ -1,13 +0,0 @@
package com.synebula.zeus.domain.service.impl.rbac
import com.synebula.gaea.data.IObjectConverter
import com.synebula.gaea.domain.repository.IRepository
import com.synebula.gaea.domain.service.Service
import com.synebula.gaea.log.ILogger
import com.synebula.zeus.domain.model.rbac.Role
import com.synebula.zeus.domain.service.contr.rbac.IRoleService
class RoleService(
repository: IRepository,
converter: IObjectConverter, logger: ILogger
) : Service<Role, String>(Role::class.java, repository, converter, logger), IRoleService

View File

@@ -1,56 +1,49 @@
package com.synebula.zeus.domain.service.impl.rbac package com.synebula.zeus.domain.service.impl.rbac
import com.synebula.gaea.data.IObjectConverter import com.synebula.gaea.bus.Subscribe
import com.synebula.gaea.data.message.DataMessage import com.synebula.gaea.data.message.DataMessage
import com.synebula.gaea.data.message.Message
import com.synebula.gaea.data.message.Status import com.synebula.gaea.data.message.Status
import com.synebula.gaea.domain.repository.IRepository import com.synebula.gaea.data.serialization.IObjectMapper
import com.synebula.gaea.domain.event.BeforeRemoveEvent
import com.synebula.gaea.domain.repository.IRepositoryFactory
import com.synebula.gaea.domain.service.ICommand import com.synebula.gaea.domain.service.ICommand
import com.synebula.gaea.domain.service.Service import com.synebula.gaea.domain.service.Service
import com.synebula.gaea.exception.NoticeUserException
import com.synebula.gaea.ext.toMd5 import com.synebula.gaea.ext.toMd5
import com.synebula.gaea.log.ILogger import com.synebula.gaea.log.ILogger
import com.synebula.zeus.domain.model.rbac.Group
import com.synebula.zeus.domain.model.rbac.Role
import com.synebula.zeus.domain.model.rbac.User import com.synebula.zeus.domain.model.rbac.User
import com.synebula.zeus.domain.service.contr.component.IUserNotifier import com.synebula.zeus.domain.service.component.IUserNotifier
import com.synebula.zeus.domain.service.contr.rbac.IGroupService
import com.synebula.zeus.domain.service.contr.rbac.IRoleService
import com.synebula.zeus.domain.service.contr.rbac.IUserService import com.synebula.zeus.domain.service.contr.rbac.IUserService
import java.util.* import java.util.*
class UserService( class UserService(
repository: IRepository, factory: IRepositoryFactory,
converter: IObjectConverter, mapper: IObjectMapper,
logger: ILogger, var userNotifier: IUserNotifier?,
groupService: IGroupService, var logger: ILogger
roleService: IRoleService, ) : Service<User, String>(User::class.java, factory.createRepository(User::class.java), mapper), IUserService {
var userNotifier: IUserNotifier
) : Service<User, String>(User::class.java, repository, converter, logger), IUserService {
init { @Subscribe(["groupBeforeRemoveEvent"])
groupService.addBeforeRemoveListener(this.clazz.name) { id -> fun beforeRoleRemove(event: BeforeRemoveEvent<Role, String>) {
val msg = Message() if (this.repository.count(mapOf(Pair("role", event.id!!))) > 0)
if (this.repository.count(mapOf(Pair("group", id)), this.clazz) > 0) { throw NoticeUserException("角色下还有用户")
msg.status = Status.Failure }
msg.message = "组下还有用户"
} @Subscribe(["groupBeforeRemoveEvent"])
msg fun beforeGroupRemove(event: BeforeRemoveEvent<Group, String>) {
} if (this.repository.count(mapOf(Pair("group", event.id!!))) > 0)
roleService.addBeforeRemoveListener(this.clazz.name) { id -> throw NoticeUserException("用户组下还有用户")
val msg = Message()
if (this.repository.count(mapOf(Pair("role", id)), this.clazz) > 0) {
msg.status = Status.Failure
msg.message = "角色下还有用户"
}
msg
}
} }
override fun add(command: ICommand): DataMessage<String> { override fun add(command: ICommand): DataMessage<String> {
val user = this.convert(command) val user = this.map(command)
user.password = user.password.toMd5() user.password = user.password.toMd5()
user.token = UUID.randomUUID().toString() user.token = UUID.randomUUID().toString()
user.alive = false user.alive = false
this.repository.add(user, this.clazz) this.repository.add(user)
userNotifier.added(user.id!!, user.name, user.token!!) userNotifier?.added(user.id!!, user.name, user.token!!)
return DataMessage(user.id!!) return DataMessage(user.id!!)
} }
@@ -60,28 +53,28 @@ class UserService(
* @param key 用户ID * @param key 用户ID
*/ */
override fun active(key: String, token: String): DataMessage<Any> { override fun active(key: String, token: String): DataMessage<Any> {
val user = this.repository.get(key, this.clazz) val user = this.repository.get(key)!!
return if (user.alive) { return if (user.alive) {
DataMessage("用户${user.name}无需重复激活") DataMessage("用户${user.name}无需重复激活")
} else { } else {
if (token == user.token) { if (token == user.token) {
user.alive = true user.alive = true
user.token = null user.token = null
this.repository.update(user, this.clazz) this.repository.update(user)
DataMessage(Status.Success, "用户${user.name}激活成功") DataMessage(Status.Success, "用户${user.name}激活成功")
} else { } else {
logger.warn(this, "用户${user.name}激活失败, {key: ${key}, token: ${token}") logger.warn(this, "用户${user.name}激活失败, {key: ${key}, token: $token")
DataMessage(Status.Failure, "用户${user.name}激活失败, 请从系统发送的邮件链接激活用户") DataMessage(Status.Failure, "用户${user.name}激活失败, 请从系统发送的邮件链接激活用户")
} }
} }
} }
override fun changePassword(key: String, password: String, newPassword: String): DataMessage<Any> { override fun changePassword(key: String, password: String, newPassword: String): DataMessage<Any> {
val user = this.repository.get(key, this.clazz) val user = this.repository.get(key)!!
return if (user.password == password.toMd5()) { return if (user.password == password.toMd5()) {
user.password = newPassword.toMd5() user.password = newPassword.toMd5()
user.token = null user.token = null
this.repository.update(user, this.clazz) this.repository.update(user)
DataMessage() DataMessage()
} else { } else {
logger.warn(this, "用户修改${user.name}密码失败, 旧密码验证不通过") logger.warn(this, "用户修改${user.name}密码失败, 旧密码验证不通过")
@@ -91,24 +84,27 @@ class UserService(
override fun resetPassword(key: String, password: String, token: String?): DataMessage<Any> { override fun resetPassword(key: String, password: String, token: String?): DataMessage<Any> {
val user = this.repository.get(key, this.clazz) val user = this.repository.get(key)!!
return if (token == user.token) { return if (token == user.token) {
user.password = password.toMd5() user.password = password.toMd5()
user.token = null user.token = null
this.repository.update(user, this.clazz) this.repository.update(user)
DataMessage() DataMessage()
} else { } else {
logger.warn(this, "用户重置${user.name}密码失败, 系统密码修改令牌:${user.token}, {key: ${key} , token: ${token}") logger.warn(
this,
"用户重置${user.name}密码失败, 系统密码修改令牌:${user.token}, {key: $key , token: $token"
)
DataMessage(Status.Failure, "用户重置密码失败, 如需重置密码请从系统发送的邮件链接中重置") DataMessage(Status.Failure, "用户重置密码失败, 如需重置密码请从系统发送的邮件链接中重置")
} }
} }
override fun forgotPassword(key: String): DataMessage<String> { override fun forgotPassword(key: String): DataMessage<String> {
val user = this.repository.get(key, this.clazz) val user = this.repository.get(key)!!
return if (user.alive) { return if (user.alive) {
user.token = UUID.randomUUID().toString() user.token = UUID.randomUUID().toString()
this.repository.update(user, this.clazz) this.repository.update(user)
userNotifier.forgot(user.id!!, user.name, user.token!!) userNotifier?.forgot(user.id!!, user.name, user.token!!)
DataMessage() DataMessage()
} else } else
DataMessage(Status.Failure, "用户还未激活, 请先激活用户") DataMessage(Status.Failure, "用户还未激活, 请先激活用户")

View File

@@ -1,13 +0,0 @@
package com.synebula.zeus.domain.service.impl.rbac.resource
import com.synebula.gaea.data.IObjectConverter
import com.synebula.gaea.domain.repository.IRepository
import com.synebula.gaea.domain.service.Service
import com.synebula.gaea.log.ILogger
import com.synebula.zeus.domain.model.rbac.resource.Interface
import com.synebula.zeus.domain.service.contr.rbac.resource.IInterfaceService
class InterfaceService(
repository: IRepository,
converter: IObjectConverter, logger: ILogger
) : Service<Interface, String>(Interface::class.java, repository, converter, logger), IInterfaceService

View File

@@ -1,13 +0,0 @@
package com.synebula.zeus.domain.service.impl.rbac.resource
import com.synebula.gaea.data.IObjectConverter
import com.synebula.gaea.domain.repository.IRepository
import com.synebula.gaea.domain.service.Service
import com.synebula.gaea.log.ILogger
import com.synebula.zeus.domain.model.rbac.resource.Page
import com.synebula.zeus.domain.service.contr.rbac.resource.IPageService
class PageService(
repository: IRepository,
converter: IObjectConverter, logger: ILogger
) : Service<Page, String>(Page::class.java, repository, converter, logger), IPageService

View File

@@ -1,13 +0,0 @@
package com.synebula.zeus.domain.service.impl.rbac.resource
import com.synebula.gaea.data.IObjectConverter
import com.synebula.gaea.domain.repository.IRepository
import com.synebula.gaea.domain.service.Service
import com.synebula.gaea.log.ILogger
import com.synebula.zeus.domain.model.rbac.resource.Permission
import com.synebula.zeus.domain.service.contr.rbac.resource.IPermissionService
class PermissionService(
repository: IRepository,
converter: IObjectConverter, logger: ILogger
) : Service<Permission, String>(Permission::class.java, repository, converter, logger), IPermissionService

View File

@@ -1,13 +0,0 @@
package com.synebula.zeus.domain.service.impl.rbac.resource
import com.synebula.gaea.data.IObjectConverter
import com.synebula.gaea.domain.repository.IRepository
import com.synebula.gaea.domain.service.Service
import com.synebula.gaea.log.ILogger
import com.synebula.zeus.domain.model.rbac.resource.System
import com.synebula.zeus.domain.service.contr.rbac.resource.ISystemService
class SystemService(
repository: IRepository,
converter: IObjectConverter, logger: ILogger
) : Service<System, String>(System::class.java, repository, converter, logger), ISystemService

View File

@@ -1,5 +1,5 @@
dependencies { dependencies {
compile "com.synebula:gaea:$gaea_version" api "com.synebula:gaea:$gaea_version"
} }
publishing { publishing {

View File

@@ -1,6 +1,6 @@
package com.synebula.zeus.env package com.synebula.zeus.env
enum class PermissionType { enum class AuthorityType {
Default, Default,
Deny, Deny,
Allow Allow

View File

@@ -1,13 +1,13 @@
dependencies { dependencies {
compile project(":src:zeus.env") api project(":src:zeus.env")
compile "com.synebula:gaea.mongo:$gaea_version" api "com.synebula:gaea.mongodb:$gaea_version"
} }
publishing { publishing {
publications { publications {
publish(MavenPublication) { publish(MavenPublication) {
group 'com.synebula' group 'com.synebula'
artifactId 'zeus.view' artifactId 'zeus.query'
version "$version" version "$version"
from components.java from components.java
} }

View File

@@ -0,0 +1,26 @@
package com.synebula.zeus.query.contr
import com.synebula.gaea.query.IQuery
import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.env.ResourceType
import com.synebula.zeus.query.view.AuthorityView
interface IAuthorityQuery : IQuery<AuthorityView, String> {
/**
* 获取角色已授权的资源
*
* @param resourceType 资源类型
* @param role 角色id
*/
fun authorized(resourceType: ResourceType, role: String): List<AuthorityView>
/**
* 获取角色资源的授权信息
*
* @param resourceType 资源里欸选哪个
* @param resource 资源id
* @param role 角色id
*/
fun authorize(resourceType: ResourceType, resource: String, role: String): AuthorityType
}

View File

@@ -1,10 +1,11 @@
package com.synebula.zeus.query.contr package com.synebula.zeus.query.contr
import com.synebula.gaea.data.message.DataMessage import com.synebula.gaea.data.message.DataMessage
import com.synebula.gaea.query.IQuery
import com.synebula.zeus.query.view.SignUserView import com.synebula.zeus.query.view.SignUserView
import com.synebula.zeus.query.view.UserView import com.synebula.zeus.query.view.UserView
interface IUserQuery { interface IUserQuery : IQuery<UserView, String> {
/** /**
* 登录接口 * 登录接口
* *

View File

@@ -1,14 +1,14 @@
package com.synebula.zeus.query.contr.resouce package com.synebula.zeus.query.contr.resouce
import com.synebula.gaea.query.IQuery import com.synebula.gaea.query.IQuery
import com.synebula.zeus.env.PermissionType import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.query.view.resource.InterfaceView import com.synebula.zeus.query.view.resource.InterfaceView
interface IInterfaceQuery : IQuery { interface IInterfaceQuery : IQuery<InterfaceView, String> {
fun withPermission(role: String): List<InterfaceView> fun authorized(role: String): List<InterfaceView>
fun withPermission(role: String, system: String?): List<InterfaceView> fun authorized(role: String, system: String?): List<InterfaceView>
fun authentication(resource: String, role: String): PermissionType? fun authorize(resource: String, role: String): AuthorityType?
} }

View File

@@ -1,16 +1,16 @@
package com.synebula.zeus.query.contr.resouce package com.synebula.zeus.query.contr.resouce
import com.synebula.gaea.query.IQuery import com.synebula.gaea.query.IQuery
import com.synebula.zeus.env.PermissionType import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.query.view.resource.PageView import com.synebula.zeus.query.view.resource.PageView
interface IPageQuery : IQuery { interface IPageQuery : IQuery<PageView, String> {
fun withPermission(role: String): List<PageView> fun authorized(role: String): List<PageView>
fun withPermission(role: String, system: String? ): List<PageView> fun authorized(role: String, system: String? ): List<PageView>
fun authentication(resource: String, role: String): PermissionType? fun authorize(resource: String, role: String): AuthorityType?
fun uriAuthentication(path: String, role: String): PermissionType? fun uriAuthorize(path: String, role: String): AuthorityType?
} }

View File

@@ -1,13 +0,0 @@
package com.synebula.zeus.query.contr.resouce
import com.synebula.gaea.query.IQuery
import com.synebula.zeus.env.PermissionType
import com.synebula.zeus.env.ResourceType
import com.synebula.zeus.query.view.resource.PermissionView
interface IPermissionQuery : IQuery {
fun resourcePermissions(resourceType: ResourceType, role: String): List<PermissionView>
fun authentication(resourceType: ResourceType, resource: String, role: String): PermissionType
}

View File

@@ -1,12 +1,12 @@
package com.synebula.zeus.query.contr.resouce package com.synebula.zeus.query.contr.resouce
import com.synebula.gaea.query.IQuery import com.synebula.gaea.query.IQuery
import com.synebula.zeus.env.PermissionType import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.query.view.resource.SystemView import com.synebula.zeus.query.view.resource.SystemView
interface ISystemQuery : IQuery { interface ISystemQuery : IQuery<SystemView, String> {
fun withPermission(role: String): List<SystemView> fun authorized(role: String): List<SystemView>
fun authentication(resource: String, role: String): PermissionType? fun authorize(resource: String, role: String): AuthorityType?
} }

View File

@@ -0,0 +1,35 @@
package com.synebula.zeus.query.impl
import com.synebula.gaea.mongodb.query.MongodbQuery
import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.env.ResourceType
import com.synebula.zeus.query.contr.IAuthorityQuery
import com.synebula.zeus.query.view.AuthorityView
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query
class AuthorityQuery(template: MongoTemplate) :
MongodbQuery<AuthorityView, String>(AuthorityView::class.java, template), IAuthorityQuery {
var collection = this.collection(this.clazz)
override fun authorized(resourceType: ResourceType, role: String): List<AuthorityView> {
return this.template.find(
Query.query(
Criteria.where("type").`is`(resourceType)
.and("role").`is`(role)
), this.clazz, this.collection
)
}
override fun authorize(resourceType: ResourceType, resource: String, role: String): AuthorityType {
val authority = this.template.findOne(
Query.query(
Criteria.where("type").`is`(resourceType)
.and("resource").`is`(resource)
.and("role").`is`(role)
), this.clazz, this.collection
)
return authority?.authority ?: AuthorityType.Default
}
}

View File

@@ -3,7 +3,8 @@ package com.synebula.zeus.query.impl
import com.synebula.gaea.data.message.DataMessage import com.synebula.gaea.data.message.DataMessage
import com.synebula.gaea.data.message.Status import com.synebula.gaea.data.message.Status
import com.synebula.gaea.ext.toMd5 import com.synebula.gaea.ext.toMd5
import com.synebula.gaea.mongo.whereId import com.synebula.gaea.mongodb.query.MongodbQuery
import com.synebula.gaea.mongodb.whereId
import com.synebula.zeus.query.contr.IUserQuery import com.synebula.zeus.query.contr.IUserQuery
import com.synebula.zeus.query.view.GroupView import com.synebula.zeus.query.view.GroupView
import com.synebula.zeus.query.view.RoleView import com.synebula.zeus.query.view.RoleView
@@ -14,8 +15,8 @@ import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query import org.springframework.data.mongodb.core.query.Query
import org.springframework.data.mongodb.core.query.isEqualTo import org.springframework.data.mongodb.core.query.isEqualTo
class UserQuery(var template: MongoTemplate) : IUserQuery { class UserQuery(template: MongoTemplate) :
private val clazz = UserView::class.java MongodbQuery<UserView, String>(UserView::class.java, template), IUserQuery {
override fun signIn(name: String, password: String): DataMessage<SignUserView> { override fun signIn(name: String, password: String): DataMessage<SignUserView> {
val query = Query.query( val query = Query.query(
@@ -29,7 +30,7 @@ class UserQuery(var template: MongoTemplate) : IUserQuery {
val group = this.template.findOne(whereId(user.group), GroupView::class.java, "group") val group = this.template.findOne(whereId(user.group), GroupView::class.java, "group")
DataMessage( DataMessage(
SignUserView( SignUserView(
user.id, user.name, user.realName ?: "", user.id, user.realName ?: "",
user.role ?: "", role?.name ?: "", user.role ?: "", role?.name ?: "",
user.group ?: "", group?.name ?: "" user.group ?: "", group?.name ?: ""
) )

View File

@@ -1,42 +1,42 @@
package com.synebula.zeus.query.impl.resouce package com.synebula.zeus.query.impl.resouce
import com.synebula.gaea.mongo.query.MongoQuery import com.synebula.gaea.mongodb.query.MongodbQuery
import com.synebula.zeus.env.PermissionType import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.env.ResourceType import com.synebula.zeus.env.ResourceType
import com.synebula.zeus.query.contr.IAuthorityQuery
import com.synebula.zeus.query.contr.resouce.IInterfaceQuery import com.synebula.zeus.query.contr.resouce.IInterfaceQuery
import com.synebula.zeus.query.contr.resouce.IPermissionQuery
import com.synebula.zeus.query.contr.resouce.ISystemQuery import com.synebula.zeus.query.contr.resouce.ISystemQuery
import com.synebula.zeus.query.view.resource.InterfaceView import com.synebula.zeus.query.view.resource.InterfaceView
import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.data.mongodb.core.MongoTemplate
class InterfaceQuery(template: MongoTemplate, var permissionQuery: IPermissionQuery, var systemQuery: ISystemQuery) : class InterfaceQuery(
MongoQuery(template), template: MongoTemplate,
IInterfaceQuery { var authorityQuery: IAuthorityQuery,
var systemQuery: ISystemQuery
) : MongodbQuery<InterfaceView, String>(InterfaceView::class.java, template), IInterfaceQuery {
private val clazz = InterfaceView::class.java override fun authorized(role: String): List<InterfaceView> {
return this.authorized(role, null)
override fun withPermission(role: String): List<InterfaceView> {
return this.withPermission(role, null)
} }
override fun withPermission(role: String, system: String?): List<InterfaceView> { override fun authorized(role: String, system: String?): List<InterfaceView> {
if (system != null) { if (system != null) {
val permission = this.systemQuery.authentication(system, role) val authority = this.systemQuery.authorize(system, role)
if (permission == PermissionType.Deny) if (authority == AuthorityType.Deny)
return listOf() return listOf()
} }
val params = mutableMapOf<String, Any>() val params = mutableMapOf<String, String>()
if (system != null) params["system"] = system if (system != null) params["system"] = system
val interfaces = this.list(params, this.clazz) val interfaces = this.list(params)
val permissions = this.permissionQuery.resourcePermissions(ResourceType.Interface, role) val authorities = this.authorityQuery.authorized(ResourceType.Interface, role)
return interfaces.filter { i -> return interfaces.filter { i ->
val permission = permissions.find { p -> i.id == p.resource } val authority = authorities.find { p -> i.id == p.resource }
permission == null || permission.authority == PermissionType.Allow authority == null || authority.authority == AuthorityType.Allow
} }
} }
override fun authentication(resource: String, role: String): PermissionType? { override fun authorize(resource: String, role: String): AuthorityType {
return this.permissionQuery.authentication(ResourceType.Interface, resource, role) return this.authorityQuery.authorize(ResourceType.Interface, resource, role)
} }
} }

View File

@@ -1,47 +1,48 @@
package com.synebula.zeus.query.impl.resouce package com.synebula.zeus.query.impl.resouce
import com.synebula.gaea.mongo.query.MongoQuery import com.synebula.gaea.mongodb.query.MongodbQuery
import com.synebula.zeus.env.PermissionType import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.env.ResourceType import com.synebula.zeus.env.ResourceType
import com.synebula.zeus.query.contr.IAuthorityQuery
import com.synebula.zeus.query.contr.resouce.IPageQuery import com.synebula.zeus.query.contr.resouce.IPageQuery
import com.synebula.zeus.query.contr.resouce.IPermissionQuery
import com.synebula.zeus.query.contr.resouce.ISystemQuery import com.synebula.zeus.query.contr.resouce.ISystemQuery
import com.synebula.zeus.query.view.resource.PageView import com.synebula.zeus.query.view.resource.PageView
import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.query.Criteria import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query import org.springframework.data.mongodb.core.query.Query
class PageQuery(template: MongoTemplate, var permissionQuery: IPermissionQuery, var systemQuery: ISystemQuery) : class PageQuery(template: MongoTemplate, var authorityQuery: IAuthorityQuery, var systemQuery: ISystemQuery) :
MongoQuery(template), IPageQuery { MongodbQuery<PageView, String>(PageView::class.java, template), IPageQuery {
private val clazz = PageView::class.java
override fun withPermission(role: String): List<PageView> { override fun authorized(role: String): List<PageView> {
return this.withPermission(role, null) return this.authorized(role, null)
} }
override fun withPermission(role: String, system: String?): List<PageView> { override fun authorized(role: String, system: String?): List<PageView> {
if (system != null) { if (system != null) {
val permission = this.systemQuery.authentication(system, role) val authority = this.systemQuery.authorize(system, role)
if (permission == PermissionType.Deny) if (authority == AuthorityType.Deny)
return listOf() return listOf()
} }
val params = mutableMapOf<String, Any>() val params = mutableMapOf<String, String>()
if (system != null) params["system"] = system if (system != null) params["system"] = system
val pages = this.list(params, this.clazz) val pages = this.list(params)
val permissions = this.permissionQuery.resourcePermissions(ResourceType.Page, role) val authorities = this.authorityQuery.authorized(ResourceType.Page, role)
return pages.filter { i -> return pages.filter { i ->
val permission = permissions.find { p -> i.id == p.resource } val authority = authorities.find { p -> i.id == p.resource }
permission != null && permission.authority == PermissionType.Allow authority != null && authority.authority == AuthorityType.Allow
} }
} }
override fun authentication(resource: String, role: String): PermissionType? { override fun authorize(resource: String, role: String): AuthorityType {
return this.permissionQuery.authentication(ResourceType.Page, resource, role) return this.authorityQuery.authorize(ResourceType.Page, resource, role)
} }
override fun uriAuthentication(path: String, role: String): PermissionType? { override fun uriAuthorize(path: String, role: String): AuthorityType? {
val page = this.template.findOne(Query.query(Criteria.where("uri").`is`(path)), val page = this.template.findOne(
this.clazz, this.collection(this.clazz)) ?: return null Query.query(Criteria.where("uri").`is`(path)),
return this.authentication(page.id!!, role) this.clazz, this.collection(this.clazz)
) ?: return null
return this.authorize(page.id!!, role)
} }
} }

View File

@@ -1,33 +0,0 @@
package com.synebula.zeus.query.impl.resouce
import com.synebula.gaea.mongo.query.MongoQuery
import com.synebula.zeus.env.PermissionType
import com.synebula.zeus.env.ResourceType
import com.synebula.zeus.query.contr.resouce.IPermissionQuery
import com.synebula.zeus.query.view.resource.PermissionView
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query
class PermissionQuery(template: MongoTemplate) : MongoQuery(template), IPermissionQuery {
var clazz = PermissionView::class.java
var collection = this.collection(this.clazz)
override fun resourcePermissions(resourceType: ResourceType, role: String): List<PermissionView> {
return this.template.find(
Query.query(
Criteria.where("type").`is`(resourceType)
.and("role").`is`(role)
), this.clazz, this.collection)
}
override fun authentication(resourceType: ResourceType, resource: String, role: String): PermissionType {
val permission = this.template.findOne(
Query.query(
Criteria.where("type").`is`(resourceType)
.and("resource").`is`(resource)
.and("role").`is`(role)
), this.clazz, this.collection)
return permission?.authority ?: PermissionType.Default
}
}

View File

@@ -1,22 +1,23 @@
package com.synebula.zeus.query.impl.resouce package com.synebula.zeus.query.impl.resouce
import com.synebula.gaea.mongo.query.MongoQuery import com.synebula.gaea.mongodb.query.MongodbQuery
import com.synebula.zeus.env.PermissionType import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.env.ResourceType import com.synebula.zeus.env.ResourceType
import com.synebula.zeus.query.contr.IAuthorityQuery
import com.synebula.zeus.query.contr.resouce.ISystemQuery import com.synebula.zeus.query.contr.resouce.ISystemQuery
import com.synebula.zeus.query.view.resource.SystemView import com.synebula.zeus.query.view.resource.SystemView
import org.springframework.data.mongodb.core.MongoTemplate import org.springframework.data.mongodb.core.MongoTemplate
class SystemQuery(template: MongoTemplate, var permissionQuery: PermissionQuery) : MongoQuery(template), ISystemQuery { class SystemQuery(template: MongoTemplate, var authorityQuery: IAuthorityQuery) :
private val clazz = SystemView::class.java MongodbQuery<SystemView, String>(SystemView::class.java, template), ISystemQuery {
override fun withPermission(role: String): List<SystemView> { override fun authorized(role: String): List<SystemView> {
val systems = this.list(mapOf(), this.clazz) val systems = this.list(mapOf())
val permissions = this.permissionQuery.resourcePermissions(ResourceType.System, role) val authorities = this.authorityQuery.authorized(ResourceType.System, role)
return systems.filter { i -> permissions.find { p -> i.id == p.resource }?.authority == PermissionType.Allow } return systems.filter { i -> authorities.find { p -> i.id == p.resource }?.authority == AuthorityType.Allow }
} }
override fun authentication(resource: String, role: String): PermissionType? { override fun authorize(resource: String, role: String): AuthorityType {
return this.permissionQuery.authentication(ResourceType.System, resource, role) return this.authorityQuery.authorize(ResourceType.System, resource, role)
} }
} }

View File

@@ -0,0 +1,12 @@
package com.synebula.zeus.query.view
import com.synebula.zeus.env.AuthorityType
import com.synebula.zeus.env.ResourceType
class AuthorityView() {
var id: String? = null
var role = ""
var resource = ""
var type: ResourceType? = null
var authority = AuthorityType.Allow
}

View File

@@ -1,13 +1,16 @@
package com.synebula.zeus.query.view package com.synebula.zeus.query.view
import com.synebula.gaea.query.annotation.Table import com.synebula.gaea.query.Operator
import com.synebula.gaea.query.annotation.Where import com.synebula.gaea.query.Table
import com.synebula.gaea.query.type.Operator import com.synebula.gaea.query.Where
@Table("group") @Table("group")
class GroupView { class GroupView {
var id: String? = null var id: String? = null
@Where(Operator.like) @Where(Operator.Like)
var name = "" var name = ""
var desc = ""
} }

View File

@@ -1,9 +1,10 @@
package com.synebula.zeus.query.view package com.synebula.zeus.query.view
import com.synebula.gaea.query.annotation.Table import com.synebula.gaea.query.Table
@Table("role") @Table("role")
class RoleView { class RoleView {
var id: String? = null var id: String? = null
var name = "" var name = ""
var desc = ""
} }

View File

@@ -1,11 +1,34 @@
package com.synebula.zeus.query.view package com.synebula.zeus.query.view
class SignUserView( class SignUserView(
var id: String = "", /**
var name: String = "", * 用户id
var realName: String = "", */
var role: String = "", var uid: String = "",
var roleName: String = "",
var group: String = "", /**
var groupName: String = "" * 用户名称
*/
var uname: String = "",
/**
* 角色id
*/
var rid: String = "",
/**
* 角色名称
*/
var rname: String = "",
/**
* 组id
*/
var gid: String = "",
/**
* 组名称
*/
var gname: String = "",
var remember: Boolean = false
) )

View File

@@ -1,8 +1,8 @@
package com.synebula.zeus.query.view package com.synebula.zeus.query.view
import com.synebula.gaea.query.annotation.Table import com.synebula.gaea.query.Operator
import com.synebula.gaea.query.annotation.Where import com.synebula.gaea.query.Table
import com.synebula.gaea.query.type.Operator import com.synebula.gaea.query.Where
@Table("user") @Table("user")
class UserView { class UserView {
@@ -12,7 +12,7 @@ class UserView {
var password: String = "" var password: String = ""
@Where(Operator.like) @Where(Operator.Like)
var realName: String? = null var realName: String? = null
var phone: String? = null var phone: String? = null

View File

@@ -1,12 +0,0 @@
package com.synebula.zeus.query.view.resource
import com.synebula.zeus.env.PermissionType
import com.synebula.zeus.env.ResourceType
class PermissionView() {
var id: String? = null
var role = ""
var resource = ""
var type: ResourceType? = null
var authority = PermissionType.Allow
}

View File

@@ -0,0 +1,17 @@
dependencies {
api project(":src:zeus.env")
api project(":src:zeus.domain")
api "com.synebula:gaea.mongodb:$gaea_version"
}
publishing {
publications {
publish(MavenPublication) {
group 'com.synebula'
artifactId 'zeus.repository'
version "$version"
from components.java
}
}
}

View File

@@ -0,0 +1,23 @@
package com.synebula.zeus.repository
import com.synebula.gaea.mongodb.repository.MongodbRepository
import com.synebula.zeus.domain.model.rbac.Authority
import com.synebula.zeus.domain.repository.rbac.IAuthorityRepository
import com.synebula.zeus.env.ResourceType
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query
class AuthorityRepository(var template: MongoTemplate) :
MongodbRepository<Authority, String>(Authority::class.java, template), IAuthorityRepository {
override fun removeByResourceRole(type: ResourceType, resource: List<String>, role: String) {
this.template.remove(
Query.query(
Criteria.where("type").`is`(type)
.and("resource").`in`(resource)
.and("role").`is`(role)
),
Authority::class.java
)
}
}