合并token校验逻辑

社团注册表增加创建人
社团注册逻辑完善
master
pan 4 years ago
parent 1b5c6cb58a
commit 9fe8fcad7b
  1. 38
      src/Controller.kt
  2. 4
      src/Dao.kt
  3. 48
      src/Service.kt
  4. 31
      src/Vo.kt
  5. 2
      test/ApplicationTest.kt

@ -6,9 +6,9 @@ import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
suspend inline fun <reified T : BaseVo> withToken(call: ApplicationCall, callback: (vo: T) -> Unit) {
suspend inline fun <reified T : ClientBaseVo> withToken(call: ApplicationCall, callback: (vo: T) -> Unit) {
val levelVo = call.receive<T>()
if (AccountService.validToken(levelVo.token)) {
if (AccountService.validToken(levelVo)) {
callback(levelVo)
} else {
call.respond(Simple.error("token校验失败"))
@ -52,7 +52,7 @@ fun Application.AccountController() {
//TODO 封装前后台登录逻辑
route(path = "/login") {
route(path = ReceiverType.Foreground.name.toLowerCase()){
route(path = ClientType.Foreground.name.toLowerCase()){
post {
val userLoginVo = call.receive<UserLoginVo>()
val token = AccountService.login(userLoginVo, call.request.host())
@ -60,12 +60,12 @@ fun Application.AccountController() {
}
post("/token"){
val tokenVo = call.receive<Token>()
val isValid = AccountService.validToken(tokenVo)
val isValid = AccountService.validUserToken(tokenVo)
call.respond(ApiResponse(message = if (isValid) "令牌合法" else "令牌不合法", body = isValid))
}
}
route(path = ReceiverType.Background.name.toLowerCase()){
route(path = ClientType.Background.name.toLowerCase()){
post{
val managerLoginVo = call.receive<ManagerLoginVo>()
val token = AccountService.login(managerLoginVo, call.request.host())
@ -83,9 +83,9 @@ fun Application.AccountController() {
post(path = "/logout") {
environment.log.info("退出登录")
val userLogoutVo = call.receive<UserLogoutVo>()
environment.log.info("$userLogoutVo")
val flag = AccountService.logout(userLogoutVo.userId)
val onlyToken = call.receive<OnlyToken>()
environment.log.info("$onlyToken")
val flag = AccountService.logout(onlyToken)
call.respond(ApiResponse(message = if (flag) "退出成功" else "退出失败", body = flag))
}
}
@ -146,8 +146,16 @@ fun Application.AssociationController() {
}
post("/register"){
withToken<RegAssociationVo>(call = call){
val flag=AssociationService.register(vo=it)
call.respond(ApiResponse(message = if(flag) "社团注册资料已保存,请等待受理" else "社团注册资料保存失败",body=flag))
try {
val flag=AssociationService.register(vo=it)
call.respond(ApiResponse(message = if(flag) "社团注册资料已提交,请等待受理" else "社团注册资料提交失败",body=flag))
} catch (e: UserIdError) {
call.respond(ApiResponse(message = "社团资料提交失败,请联系管理员",body = false))
} catch (e:FileIdError){
call.respond(ApiResponse(message = "社团资料提交失败,请联系管理员",body = false))
}catch (e:HasAssociationError){
call.respond(ApiResponse(message = e.message?:"发生未知错误,请联系管理员",body = false))
}
}
}
}
@ -163,10 +171,10 @@ enum class NotificationType{
}
/**
* 通知接收客户端
* 客户端类型
*
*/
enum class ReceiverType{
enum class ClientType{
//前台
Foreground,
//后台
@ -179,7 +187,7 @@ enum class ReceiverType{
*/
sealed class Receiver{
protected abstract val id:Int
abstract val target:ReceiverType
abstract val target:ClientType
}
/**
@ -187,14 +195,14 @@ sealed class Receiver{
*
* @property managerId 管理员id
*/
data class BackgroundReceiver(val managerId:Int,override val id: Int=managerId, override val target: ReceiverType=ReceiverType.Background):Receiver()
data class BackgroundReceiver(val managerId:Int,override val id: Int=managerId, override val target: ClientType=ClientType.Background):Receiver()
/**
* 前台客户端接收
*
* @property userId 用户id
*/
data class ForegroundReceiver(val userId:Int, override val id:Int=userId, override val target: ReceiverType=ReceiverType.Foreground):Receiver()
data class ForegroundReceiver(val userId:Int, override val id:Int=userId, override val target: ClientType=ClientType.Foreground):Receiver()
sealed class BaseNotification{
abstract val type:NotificationType

@ -131,6 +131,9 @@ object Associations:IntIdTable(){
@TableComment("社团审核状态")
val status:Column<Boolean> = bool(name="status").default(false)
@TableComment("创建人")
val user:Column<EntityID<Int>> = reference("user_id",Users)
}
class Association(id:EntityID<Int>):IntEntity(id){
@ -139,6 +142,7 @@ class Association(id:EntityID<Int>):IntEntity(id){
var desc by Associations.desc
var logo by ImageFile referencedOn Associations.logo
var status by Associations.status
var user by User referencedOn Associations.user
}
@TableComment("后台管理员")

@ -124,7 +124,7 @@ object AccountService:AbstractService() {
}
}
fun validToken(token: Token):Boolean{
fun validUserToken(token: Token):Boolean{
return transaction {
!UserToken.find {
UserTokens.userId eq token.id
@ -133,9 +133,20 @@ object AccountService:AbstractService() {
}
}
fun logout(userId:Int):Boolean{
fun <T : ClientBaseVo> validToken(vo:T):Boolean{
return if(vo.clientType==ClientType.Foreground){
validUserToken(vo.token)
}else{
validManagerToken(vo.token)
}
}
fun logout(vo:OnlyToken):Boolean{
return transaction {
UserTokens.deleteWhere { UserTokens.userId eq userId }>0
if(vo.clientType==ClientType.Foreground)
UserTokens.deleteWhere { UserTokens.userId eq vo.token.id }>0
else
ManagerTokens.deleteWhere { ManagerTokens.managerId eq vo.token.id }>0
}
}
@ -264,7 +275,7 @@ object FileService:AbstractService(){
val token= getPartData<PartData.FormItem>(map,"token").value
val createTime= getPartData<PartData.FormItem>(map,"createTime").value
val tokenVo=Token(token=token,id=userId.toInt(),createTime=createTime.toLong())
if(AccountService.validToken(tokenVo)){
if(AccountService.validUserToken(tokenVo)){
map.remove("id")
map.remove("token")
val fileIds= mutableListOf<Int>()
@ -292,6 +303,11 @@ object FileService:AbstractService(){
}
class UserIdError(id: Int): IllegalArgumentException("用户id${id}不存在")
class FileIdError(id:Int): IllegalArgumentException("文件id${id}不存在!")
class HasAssociationError(s: String) : IllegalArgumentException(s)
/**
* 社团服务
@ -307,24 +323,27 @@ object AssociationService: AbstractService() {
fun register(vo:RegAssociationVo):Boolean{
return try {
transaction {
val user=User.findById(vo.token.id)?:throw UserIdError(vo.token.id)
Association.find { Associations.user eq vo.token.id }.apply {
when{
count()!=0L && first().status ->throw HasAssociationError("您是社团团长不能再创建其他社团")
count()!=0L->throw HasAssociationError("您已经提交过社团注册资料,请耐心等待后台管理员处理")
}
}
Association.new {
name=vo.name
desc=vo.desc
logo=ImageFile.findById(vo.fileId) ?: throw IllegalArgumentException("文件id不存在!")
logo=ImageFile.findById(vo.fileId) ?: throw FileIdError(vo.fileId)
this.user=user
}
Notification.new {
title="注册社团"
content="您成功提交了一份社团注册资料,请耐心等待后台受理"
receiverId=vo.token.id
receiverClient=ReceiverType.Foreground.name
}
val user=User.findById(vo.token.id)
if(user!=null) {
BackgroundService.createBackgroundNotification(title = "审核注册社团",content = "用户${user.name}提交了一份社团资料需要您进行受理",
duty = Duty.PamphaBhusal)
}else{
log.warn("无法根据token id:${vo.token.id}查找到用户名")
receiverClient=ClientType.Foreground.name
}
BackgroundService.createBackgroundNotification(title = "审核注册社团",content = "用户${user.name}提交了一份社团资料需要您进行受理",
duty = Duty.PamphaBhusal)
return@transaction true
}
log.info("未审核社团创建成功")
@ -360,6 +379,7 @@ object NotificationService:AbstractService(){
*/
fun pull(vo:NotificationDto):List<NotificationVo>{
return transaction {
log.info("通知查询条件[receiverId=${vo.receiverId},receiverClient=${vo.receiverClient.name},pull=false]")
val notifications=Notification.find { Notifications.pull eq false and
(Notifications.receiverId eq vo.receiverId) and
(Notifications.receiverClient eq vo.receiverClient.name) }
@ -437,7 +457,7 @@ object BackgroundService:AbstractService(){
this.title = title
this.content = content
receiverId= it.id.value
receiverClient=ReceiverType.Background.name
receiverClient=ClientType.Background.name
}
}
}

@ -21,36 +21,40 @@ data class UserVo(val studentId:String,val name:String)
sealed class BaseLoginVo{
abstract val password: String
abstract val device: String
abstract val clientType:ReceiverType
abstract val clientType:ClientType
}
sealed class ClientBaseVo {
abstract val token:Token
abstract val clientType:ClientType
}
data class UserLoginVo(val studentId: String,
override val password: String, override val device: String,
override val clientType: ReceiverType=ReceiverType.Foreground
override val clientType: ClientType=ClientType.Foreground
):BaseLoginVo()
data class UserLogoutVo(val userId:Int)
data class UserResDto(val password:String)
data class ManagerLoginVo(val account:String,
override val password:String, override val device:String):BaseLoginVo() {
override val clientType: ReceiverType=ReceiverType.Background
override val clientType: ClientType=ClientType.Background
}
data class Token(val token:String, val createTime:Long, val id:Int)
sealed class BaseVo{
abstract val token:Token
}
data class LeaveMessageVo(val message: String, override val token:Token):BaseVo()
data class LeaveMessageVo(val message: String, override val token:Token,
override val clientType: ClientType=ClientType.Foreground):ClientBaseVo()
data class OnlyToken(override val token: Token):BaseVo()
data class OnlyToken(override val token: Token, override val clientType: ClientType):ClientBaseVo()
data class LeaveMessageDto(val message: String,val user: UserVo)
data class RegAssociationVo(val name:String, val desc:String,val fileId:Int, override val token: Token):BaseVo()
data class RegAssociationVo(val name:String, val desc:String, val fileId:Int, override val token: Token,
override val clientType: ClientType=ClientType.Foreground
):ClientBaseVo()
data class ImageFileDto(val filepath:String,val md5:String,val createTime: Long,val url:String)
@ -60,7 +64,8 @@ data class InitManagerDto(val account: String, val originPassword: String, val d
data class PageDto(val currentPage:Long,val pageSize:Int=10)
data class NotificationDto(val receiverId:Int, val receiverClient:ReceiverType, override val token: Token,
val page:PageDto?):BaseVo()
data class NotificationDto(val receiverId:Int, val receiverClient:ClientType, override val token: Token,
val page:PageDto?, override val clientType: ClientType=receiverClient
):ClientBaseVo()
data class NotificationVo(val title:String,val content:String,val id:Int,val createTime: Long)

@ -95,7 +95,7 @@ class ApplicationTest {
@Test
fun testLowerCase(){
println(ReceiverType.Foreground.name.toLowerCase())
println(ClientType.Foreground.name.toLowerCase())
}
/**

Loading…
Cancel
Save