Skip to content

Commit

Permalink
feat: 接入SSubitO
Browse files Browse the repository at this point in the history
  • Loading branch information
nullaqua committed Aug 14, 2024
1 parent 11f5091 commit baec3cb
Show file tree
Hide file tree
Showing 30 changed files with 234 additions and 1,291 deletions.
89 changes: 1 addition & 88 deletions src/main/kotlin/subit/JWTAuth.kt
Original file line number Diff line number Diff line change
@@ -1,104 +1,17 @@
package subit

import at.favre.lib.crypto.bcrypt.BCrypt
import com.auth0.jwt.JWT
import com.auth0.jwt.JWTVerifier
import com.auth0.jwt.algorithms.Algorithm
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.util.pipeline.*
import kotlinx.serialization.Serializable
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import subit.console.SimpleAnsiColor.Companion.CYAN
import subit.console.SimpleAnsiColor.Companion.RED
import subit.dataClasses.SsoUserFull
import subit.dataClasses.UserFull
import subit.dataClasses.UserId
import subit.database.Users
import subit.logger.ForumLogger
import java.util.*

/**
* JWT验证
*/
@Suppress("MemberVisibilityCanBePrivate")
object JWTAuth: KoinComponent
{
private val logger = ForumLogger.getLogger()
@Serializable
data class Token(val token: String)

/**
* JWT密钥
*/
private lateinit var SECRET_KEY: String

/**
* JWT算法
*/
private lateinit var algorithm: Algorithm

/**
* JWT有效期
*/
private const val VALIDITY: Long = 1000L/*ms*/*60/*s*/*60/*m*/*24/*h*/*7/*d*/
fun Application.initJwtAuth()
{
// 从配置文件中读取密钥
val key = environment.config.propertyOrNull("jwt.secret")?.getString()
if (key == null)
{
logger.info("${CYAN}jwt.secret${RED} not found in config file, use random secret key")
SECRET_KEY = UUID.randomUUID().toString()
}
else
{
SECRET_KEY = key
}
// 初始化JWT算法
algorithm = Algorithm.HMAC512(SECRET_KEY)
}

/**
* 生成验证器
*/
fun makeJwtVerifier(): JWTVerifier = JWT.require(algorithm).build()

/**
* 生成Token
* @param id 用户ID
* @param encryptedPassword 用户密码(加密后)
*/
private fun makeTokenByEncryptedPassword(id: UserId, encryptedPassword: String): Token = JWT.create()
.withSubject("Authentication")
.withClaim("id", id.value)
.withClaim("password", encryptedPassword)
.withExpiresAt(getExpiration())
.sign(algorithm)
.let(::Token)

private val users: Users by inject()

suspend fun checkLoginByEncryptedPassword(id: UserId, encryptedPassword: String): Boolean =
users.getEncryptedPassword(id) == encryptedPassword

suspend fun checkLogin(id: UserId, password: String): Boolean =
users.getEncryptedPassword(id)?.let { verifyPassword(password, it) } ?: false
suspend fun checkLogin(email: String, password: String): Boolean =
users.getEncryptedPassword(email)?.let { verifyPassword(password, it) } ?: false

suspend fun makeToken(id: UserId): Token? =
users.getEncryptedPassword(id)?.let { makeTokenByEncryptedPassword(id, it) }

private fun getExpiration() = Date(System.currentTimeMillis()+VALIDITY)
fun PipelineContext<*, ApplicationCall>.getLoginUser(): UserFull? = call.principal<UserFull>()

private val hasher = BCrypt.with(BCrypt.Version.VERSION_2B)
private val verifier = BCrypt.verifyer(BCrypt.Version.VERSION_2B)

/**
* 在数据库中保存密码的加密
*/
fun encryptPassword(password: String): String = hasher.hashToString(12, password.toCharArray())
fun verifyPassword(password: String, hash: String): Boolean = verifier.verify(password.toCharArray(), hash).verified
}
1 change: 0 additions & 1 deletion src/main/kotlin/subit/config/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ class ConfigLoader<T: Any> private constructor(
fun init() // 初始化所有配置
{
apiDocsConfig
emailConfig
filesConfig
loggerConfig
systemConfig
Expand Down
44 changes: 0 additions & 44 deletions src/main/kotlin/subit/config/EmailConfig.kt

This file was deleted.

10 changes: 8 additions & 2 deletions src/main/kotlin/subit/config/SystemConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ import net.mamoe.yamlkt.Comment
@Serializable
data class SystemConfig(
@Comment("是否在系统维护中")
val systemMaintaining: Boolean
val systemMaintaining: Boolean,
@Comment("SSO服务器地址, 请不要以/结尾, 例如: https://ssubito.subit.org.cn/api " +
"而不是 https://ssubito.subit.org.cn/api/")
val ssoServer: String,
)

var systemConfig: SystemConfig by config("system.yml", SystemConfig(false))
var systemConfig: SystemConfig by config(
"system.yml",
SystemConfig(false, "https://ssubito.subit.org.cn/api")
)
1 change: 0 additions & 1 deletion src/main/kotlin/subit/console/command/CommandSet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ object CommandSet: TreeCommand(
Logger,
Shell,
Color,
Whitelist,
Maintain,
TestDatabase
)
Expand Down
2 changes: 0 additions & 2 deletions src/main/kotlin/subit/console/command/TestDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ object TestDatabase: Command, KoinComponent
"BannedWords" to dao<BannedWords>(),
"Blocks" to dao<Blocks>(),
"Comments" to dao<Comments>(),
"EmailCodes" to dao<EmailCodes>(),
"Likes" to dao<Likes>(),
"Notices" to dao<Notices>(),
"Operations" to dao<Operations>(),
Expand All @@ -37,7 +36,6 @@ object TestDatabase: Command, KoinComponent
"Reports" to dao<Reports>(),
"Stars" to dao<Stars>(),
"Users" to dao<Users>(),
"Whitelists" to dao<Whitelists>(),
)
}

Expand Down
79 changes: 0 additions & 79 deletions src/main/kotlin/subit/console/command/Whitelist.kt

This file was deleted.

Loading

0 comments on commit baec3cb

Please sign in to comment.