添加权限表
This commit is contained in:
parent
e2b56a654c
commit
b0616a1098
@ -47,6 +47,7 @@ dependencies {
|
|||||||
implementation "org.noelware.charted.snowflake:snowflake:0.1-beta"
|
implementation "org.noelware.charted.snowflake:snowflake:0.1-beta"
|
||||||
implementation 'org.springframework.boot:spring-boot-starter-security'
|
implementation 'org.springframework.boot:spring-boot-starter-security'
|
||||||
implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
|
implementation 'io.jsonwebtoken:jjwt-api:0.12.6'
|
||||||
|
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
|
||||||
testImplementation 'org.springframework.security:spring-security-test'
|
testImplementation 'org.springframework.security:spring-security-test'
|
||||||
compileOnly 'org.projectlombok:lombok'
|
compileOnly 'org.projectlombok:lombok'
|
||||||
annotationProcessor 'org.projectlombok:lombok'
|
annotationProcessor 'org.projectlombok:lombok'
|
||||||
|
21
src/main/java/dev/surl/surl/cfg/BaseConfig.kt
Normal file
21
src/main/java/dev/surl/surl/cfg/BaseConfig.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package dev.surl.surl.cfg
|
||||||
|
|
||||||
|
import dev.surl.surl.util.numberToKey
|
||||||
|
import io.jsonwebtoken.security.Keys
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import java.util.Date
|
||||||
|
import javax.crypto.SecretKey
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties(prefix = "base.configs")
|
||||||
|
class BaseConfig(
|
||||||
|
/**
|
||||||
|
* 站点域名
|
||||||
|
*/
|
||||||
|
var site: String = "https://surl.org",
|
||||||
|
var expire: Long = 24 * 60 * 60 * 1000, // token expire time
|
||||||
|
private var secret: String = numberToKey(Date().time),
|
||||||
|
var secretKey: SecretKey = Keys.hmacShaKeyFor(secret.toByteArray()),
|
||||||
|
var tokenHead: String = "token"
|
||||||
|
)
|
@ -1,14 +0,0 @@
|
|||||||
package dev.surl.surl.cfg
|
|
||||||
|
|
||||||
import io.jsonwebtoken.security.Keys
|
|
||||||
import org.springframework.context.annotation.Configuration
|
|
||||||
import javax.crypto.SecretKey
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
open class BaseConfiguration(
|
|
||||||
val site: String = "https://surl.org",
|
|
||||||
val expire: Long = 24 * 60 * 60 * 1000,
|
|
||||||
private val secret: String = "6244a108c0599980e7971845baeb3120",
|
|
||||||
val secretKey: SecretKey = Keys.hmacShaKeyFor(secret.toByteArray()),
|
|
||||||
val tokenHead: String = "token"
|
|
||||||
)
|
|
9
src/main/java/dev/surl/surl/cfg/PatternConfig.kt
Normal file
9
src/main/java/dev/surl/surl/cfg/PatternConfig.kt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package dev.surl.surl.cfg
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
open class PatternConfig {
|
||||||
|
val usernamePattern = Regex("""\w{6,20}""")
|
||||||
|
val passwordPattern = Regex("""^((?=\S*?[A-Z])(?=\S*?[a-z])(?=\S*?[0-9])(?=\S*?)).{10,}\S$""")
|
||||||
|
}
|
17
src/main/java/dev/surl/surl/cfg/security/EncoderConfig.kt
Normal file
17
src/main/java/dev/surl/surl/cfg/security/EncoderConfig.kt
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package dev.surl.surl.cfg.security
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
open class EncoderConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 装载BCrypt密码编码器
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
open fun passwordEncoder(): BCryptPasswordEncoder {
|
||||||
|
return BCryptPasswordEncoder(BCryptPasswordEncoder.BCryptVersion.`$2B`)
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package dev.surl.surl.cfg.security
|
package dev.surl.surl.cfg.security
|
||||||
|
|
||||||
import dev.surl.surl.cfg.Logging
|
|
||||||
import jakarta.servlet.FilterChain
|
import jakarta.servlet.FilterChain
|
||||||
import jakarta.servlet.http.HttpServletRequest
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
import jakarta.servlet.http.HttpServletResponse
|
import jakarta.servlet.http.HttpServletResponse
|
||||||
@ -10,8 +9,6 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity
|
|||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity
|
||||||
import org.springframework.security.web.SecurityFilterChain
|
import org.springframework.security.web.SecurityFilterChain
|
||||||
import org.springframework.security.config.annotation.web.invoke
|
import org.springframework.security.config.annotation.web.invoke
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder
|
|
||||||
import org.springframework.web.filter.OncePerRequestFilter
|
import org.springframework.web.filter.OncePerRequestFilter
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ -30,29 +27,20 @@ open class WebSecurityConfig {
|
|||||||
headers {
|
headers {
|
||||||
cacheControl { } // 禁用缓存
|
cacheControl { } // 禁用缓存
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return http.build()
|
return http.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 装载BCrypt密码编码器
|
|
||||||
*/
|
|
||||||
@Bean
|
@Bean
|
||||||
open fun passwordEncoder(): BCryptPasswordEncoder {
|
open fun authenticationTokenFilter(): OncePerRequestFilter {
|
||||||
return BCryptPasswordEncoder()
|
return object: OncePerRequestFilter() {
|
||||||
|
override fun doFilterInternal(
|
||||||
|
request: HttpServletRequest,
|
||||||
|
response: HttpServletResponse,
|
||||||
|
filterChain: FilterChain
|
||||||
|
) {
|
||||||
|
filterChain.doFilter(request, response)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Bean
|
|
||||||
// open fun authenticationTokenFilter(): OncePerRequestFilter {
|
|
||||||
// return object: OncePerRequestFilter() {
|
|
||||||
// override fun doFilterInternal(
|
|
||||||
// request: HttpServletRequest,
|
|
||||||
// response: HttpServletResponse,
|
|
||||||
// filterChain: FilterChain
|
|
||||||
// ) {
|
|
||||||
// filterChain.doFilter(request, response)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
5
src/main/java/dev/surl/surl/common/Access.kt
Normal file
5
src/main/java/dev/surl/surl/common/Access.kt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package dev.surl.surl.common
|
||||||
|
|
||||||
|
enum class Access {
|
||||||
|
ADMIN, READ, WRITE
|
||||||
|
}
|
@ -1,3 +1,3 @@
|
|||||||
package dev.surl.surl.common.exception
|
package dev.surl.surl.common.exception
|
||||||
|
|
||||||
class UserRegistException(message: String? = null, cause: Throwable? = null): Throwable(message, cause)
|
class UserRegistException(message: String? = null, cause: Throwable? = null): Exception(message, cause)
|
@ -1,6 +1,6 @@
|
|||||||
package dev.surl.surl.controller
|
package dev.surl.surl.controller
|
||||||
|
|
||||||
import dev.surl.surl.cfg.BaseConfiguration
|
import dev.surl.surl.cfg.BaseConfig
|
||||||
import dev.surl.surl.service.SurlService
|
import dev.surl.surl.service.SurlService
|
||||||
import jakarta.validation.Valid
|
import jakarta.validation.Valid
|
||||||
import org.hibernate.validator.constraints.Length
|
import org.hibernate.validator.constraints.Length
|
||||||
@ -15,9 +15,9 @@ import java.net.URI
|
|||||||
class RedirectController {
|
class RedirectController {
|
||||||
@GetMapping("/{key}")
|
@GetMapping("/{key}")
|
||||||
fun redirect(
|
fun redirect(
|
||||||
@PathVariable @Valid @Length(min = 11, max = 11, message = "Key must be 11 characters long") key: String,
|
@PathVariable @Valid @Length(min = 1, max = 11, message = "Key length is not valid") key: String,
|
||||||
@Autowired service: SurlService,
|
@Autowired service: SurlService,
|
||||||
@Autowired cfg: BaseConfiguration
|
@Autowired cfg: BaseConfig
|
||||||
): ResponseEntity<Any> {
|
): ResponseEntity<Any> {
|
||||||
val redirectUrl = service.getUrlByKey(key)
|
val redirectUrl = service.getUrlByKey(key)
|
||||||
return if(redirectUrl.isBlank()) {
|
return if(redirectUrl.isBlank()) {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package dev.surl.surl.controller
|
package dev.surl.surl.controller
|
||||||
|
|
||||||
import dev.surl.surl.cfg.BaseConfiguration
|
import dev.surl.surl.cfg.BaseConfig
|
||||||
import dev.surl.surl.common.Msg
|
import dev.surl.surl.common.Msg
|
||||||
import dev.surl.surl.dto.Surl
|
import dev.surl.surl.dto.SurlDto
|
||||||
import dev.surl.surl.service.SurlService
|
import dev.surl.surl.service.SurlService
|
||||||
import jakarta.validation.Valid
|
import jakarta.validation.Valid
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.beans.factory.annotation.Autowired
|
||||||
@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.RestController
|
|||||||
class SurlAddController {
|
class SurlAddController {
|
||||||
@RequestMapping("/surl/add")
|
@RequestMapping("/surl/add")
|
||||||
fun addSurl(
|
fun addSurl(
|
||||||
@Valid @RequestBody body: Surl, @Autowired service: SurlService, @Autowired cfg: BaseConfiguration
|
@Valid @RequestBody body: SurlDto, @Autowired service: SurlService, @Autowired cfg: BaseConfig
|
||||||
): Any {
|
): Any {
|
||||||
return ResponseEntity(Msg(code = 0, value = "${cfg.site}/${service.addSurl(body.url ?: "")}"), HttpStatus.OK)
|
return ResponseEntity(Msg(code = 0, value = "${cfg.site}/${service.addSurl(body.url ?: "")}"), HttpStatus.OK)
|
||||||
}
|
}
|
||||||
|
18
src/main/java/dev/surl/surl/dao/UserAccess.kt
Normal file
18
src/main/java/dev/surl/surl/dao/UserAccess.kt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package dev.surl.surl.dao
|
||||||
|
|
||||||
|
import dev.surl.surl.common.Access
|
||||||
|
import dev.surl.surl.dao.Surl.Companion.referrersOn
|
||||||
|
import dev.surl.surl.dsl.UserAccesses
|
||||||
|
import org.jetbrains.exposed.dao.LongEntity
|
||||||
|
import org.jetbrains.exposed.dao.LongEntityClass
|
||||||
|
import org.jetbrains.exposed.dao.id.EntityID
|
||||||
|
|
||||||
|
class UserAccess(id: EntityID<Long>): LongEntity(id) {
|
||||||
|
companion object EntityClass: LongEntityClass<UserAccess>(UserAccesses)
|
||||||
|
var access by UserAccesses.access.transform(toColumn = {
|
||||||
|
it.ordinal.toShort()
|
||||||
|
}, toReal = {
|
||||||
|
Access.entries[it.toInt()]
|
||||||
|
})
|
||||||
|
var user by User referencedOn UserAccesses.user
|
||||||
|
}
|
@ -5,6 +5,6 @@ import org.jetbrains.exposed.dao.id.IdTable
|
|||||||
object Surls: IdTable<Long>("surl") {
|
object Surls: IdTable<Long>("surl") {
|
||||||
override val id = long("id").entityId()
|
override val id = long("id").entityId()
|
||||||
val url = varchar("url", 2048).uniqueIndex()
|
val url = varchar("url", 2048).uniqueIndex()
|
||||||
val user = reference("user", Users).nullable()
|
val user = reference("user", Users).index().nullable()
|
||||||
override val primaryKey = PrimaryKey(id, name = "PK_surl_id")
|
override val primaryKey = PrimaryKey(id, name = "PK_surl_id")
|
||||||
}
|
}
|
9
src/main/java/dev/surl/surl/dsl/UserAccesses.kt
Normal file
9
src/main/java/dev/surl/surl/dsl/UserAccesses.kt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package dev.surl.surl.dsl
|
||||||
|
|
||||||
|
import org.jetbrains.exposed.dao.id.IdTable
|
||||||
|
|
||||||
|
object UserAccesses: IdTable<Long>("user_access") {
|
||||||
|
override val id = long("id").entityId()
|
||||||
|
val user = reference("user", Users).index()
|
||||||
|
val access = short("access")
|
||||||
|
}
|
@ -5,6 +5,6 @@ import org.jetbrains.exposed.dao.id.IdTable
|
|||||||
object Users: IdTable<Long>("users") {
|
object Users: IdTable<Long>("users") {
|
||||||
override val id = long("id").entityId()
|
override val id = long("id").entityId()
|
||||||
val username = varchar("username", 256).uniqueIndex()
|
val username = varchar("username", 256).uniqueIndex()
|
||||||
val password = varchar("password", 256)
|
val password = char("password", 60)
|
||||||
override val primaryKey = PrimaryKey(id, name = "PK_user_id")
|
override val primaryKey = PrimaryKey(id, name = "PK_user_id")
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
|
|||||||
import jakarta.validation.constraints.NotNull
|
import jakarta.validation.constraints.NotNull
|
||||||
import org.hibernate.validator.constraints.Length
|
import org.hibernate.validator.constraints.Length
|
||||||
|
|
||||||
data class Surl(
|
data class SurlDto(
|
||||||
@JsonProperty("url")
|
@JsonProperty("url")
|
||||||
@get:NotNull(message = "url cannot be empty")
|
@get:NotNull(message = "url cannot be empty")
|
||||||
@get:Length(min = 11, max = 2048, message = "url length invalid")
|
@get:Length(min = 11, max = 2048, message = "url length invalid")
|
||||||
|
@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty
|
|||||||
import jakarta.validation.constraints.NotNull
|
import jakarta.validation.constraints.NotNull
|
||||||
import org.hibernate.validator.constraints.Length
|
import org.hibernate.validator.constraints.Length
|
||||||
|
|
||||||
class UserDto (
|
data class UserDto (
|
||||||
@JsonProperty("username")
|
@JsonProperty("username")
|
||||||
@get:Length(max = 16, min = 4, message = "username length must be between 4 and 16")
|
@get:Length(max = 16, min = 4, message = "username length must be between 4 and 16")
|
||||||
@get:NotNull(message = "username cannot be null")
|
@get:NotNull(message = "username cannot be null")
|
||||||
|
@ -38,7 +38,7 @@ class DefaultExceptionHandler : ResponseEntityExceptionHandler() {
|
|||||||
return ResponseEntity(Msg<String>(code = -1, msg = ex.message ?: "unknown error"), status)
|
return ResponseEntity(Msg<String>(code = -1, msg = ex.message ?: "unknown error"), status)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(value = [Exception::class])
|
@ExceptionHandler(value = [IllegalStateException::class ,Exception::class])
|
||||||
fun handleException(
|
fun handleException(
|
||||||
ex: Exception
|
ex: Exception
|
||||||
): ResponseEntity<Msg<String>> {
|
): ResponseEntity<Msg<String>> {
|
||||||
@ -46,8 +46,8 @@ class DefaultExceptionHandler : ResponseEntityExceptionHandler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@ExceptionHandler(value = [UserRegistException::class])
|
@ExceptionHandler(value = [UserRegistException::class])
|
||||||
fun handleUserRegistException(ex: Exception, headers: HttpHeaders, status: HttpStatusCode, request: WebRequest
|
fun handleUserRegistException(ex: Exception
|
||||||
): ResponseEntity<Msg<String>>{
|
): ResponseEntity<Msg<String>>{
|
||||||
return ResponseEntity(Msg(code = -1, msg = ex.message ?: "unknown regist error"), status)
|
return ResponseEntity(Msg(code = -1, msg = ex.message ?: "unknown regist error"), HttpStatus.BAD_REQUEST)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -16,19 +16,14 @@ class SurlService {
|
|||||||
url = baseurl
|
url = baseurl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return@runBlocking numberToKey(id)
|
numberToKey(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUrlByKey(key: String): String {
|
fun getUrlByKey(key: String): String {
|
||||||
return transaction {
|
return transaction {
|
||||||
val results = Surls.select(Surls.url).where {
|
Surls.select(Surls.url).where {
|
||||||
Surls.id eq keyToNumber(key)
|
Surls.id eq keyToNumber(key)
|
||||||
}.toList()
|
}.firstOrNull()?.get(Surls.url) ?: ""
|
||||||
if (results.isNotEmpty()) {
|
|
||||||
return@transaction results.first()[Surls.url]
|
|
||||||
} else {
|
|
||||||
return@transaction ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,43 +1,77 @@
|
|||||||
package dev.surl.surl.service
|
package dev.surl.surl.service
|
||||||
|
|
||||||
import dev.surl.surl.SurlApplication
|
import dev.surl.surl.common.Access
|
||||||
import dev.surl.surl.common.Msg
|
import dev.surl.surl.common.Msg
|
||||||
import dev.surl.surl.common.exception.UserRegistException
|
import dev.surl.surl.common.exception.UserRegistException
|
||||||
import dev.surl.surl.dao.User
|
import dev.surl.surl.dao.User
|
||||||
|
import dev.surl.surl.dao.UserAccess
|
||||||
import dev.surl.surl.dsl.Users
|
import dev.surl.surl.dsl.Users
|
||||||
|
import dev.surl.surl.util.autowired
|
||||||
import dev.surl.surl.util.genSnowflakeUID
|
import dev.surl.surl.util.genSnowflakeUID
|
||||||
import dev.surl.surl.util.numberToKey
|
import dev.surl.surl.util.numberToKey
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.jetbrains.exposed.sql.transactions.transaction
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
import org.springframework.beans.factory.annotation.Autowired
|
import org.springframework.security.core.authority.SimpleGrantedAuthority
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
|
|
||||||
|
typealias AUser = org.springframework.security.core.userdetails.User
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class UserService(@Autowired private val passwordEncoder: BCryptPasswordEncoder) {
|
class UserService: UserDetailsService {
|
||||||
|
private val passwordEncoder: BCryptPasswordEncoder by autowired()
|
||||||
fun addUser(username: String, password: String): Msg<Any> {
|
fun addUser(username: String, password: String): Msg<Any> {
|
||||||
// if (passwordEncoder == null) throw Exception("password encoder is null")
|
|
||||||
// val passwordEncoder = SurlApplication.context.getBean("bcryptor") as PasswordEncoder
|
val (id, accessId) = runBlocking {
|
||||||
val id = runBlocking {
|
Pair(genSnowflakeUID(), genSnowflakeUID())
|
||||||
genSnowflakeUID()
|
|
||||||
}
|
}
|
||||||
val encryptedPassword = passwordEncoder.encode(password)
|
val encryptedPassword = passwordEncoder.encode(password)
|
||||||
transaction {
|
transaction {
|
||||||
if (isUserExist(username)) {
|
if (isUserExist(username)) {
|
||||||
throw UserRegistException("user is existed")
|
throw UserRegistException("user is existed")
|
||||||
}
|
}
|
||||||
User.new(id) {
|
val user = User.new(id) {
|
||||||
this.username = username
|
this.username = username
|
||||||
this.password = encryptedPassword
|
this.password = encryptedPassword
|
||||||
}
|
}
|
||||||
|
addDefaultAccess(accessId, user)
|
||||||
}
|
}
|
||||||
@Suppress("unused") return Msg(value = object {
|
return Msg(value = mapOf(
|
||||||
val id = numberToKey(id)
|
"id" to numberToKey(id),
|
||||||
val username = username
|
"username" to username
|
||||||
})
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isUserExist(username: String) = User.find {
|
private fun getUserByUsername(username: String): User? {
|
||||||
|
return transaction {
|
||||||
|
User.find {
|
||||||
|
Users.username eq username
|
||||||
|
}.firstOrNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isUserExist(username: String) = !User.find {
|
||||||
Users.username eq username
|
Users.username eq username
|
||||||
}.toList().isNotEmpty()
|
}.empty()
|
||||||
|
|
||||||
|
private fun addDefaultAccess(id: Long, user: User) {
|
||||||
|
UserAccess.new(id) {
|
||||||
|
this.access = Access.READ
|
||||||
|
this.user = user
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadUserByUsername(username: String): UserDetails {
|
||||||
|
val user = getUserByUsername(username) ?: throw UsernameNotFoundException("user '$username' not found")
|
||||||
|
return AUser.builder().apply {
|
||||||
|
username(user.username)
|
||||||
|
password(passwordEncoder.encode(user.password))
|
||||||
|
authorities(listOf(
|
||||||
|
SimpleGrantedAuthority("ROLE_USER")
|
||||||
|
))
|
||||||
|
}.build()
|
||||||
|
}
|
||||||
}
|
}
|
18
src/main/java/dev/surl/surl/util/Autowired.kt
Normal file
18
src/main/java/dev/surl/surl/util/Autowired.kt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package dev.surl.surl.util
|
||||||
|
|
||||||
|
import dev.surl.surl.SurlApplication
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
class Autowired<T : Any>(private val type: KClass<T>, private val name: String?) {
|
||||||
|
private val value: T by lazy {
|
||||||
|
if (name == null) {
|
||||||
|
SurlApplication.context.getBean(type.java) as T
|
||||||
|
} else {
|
||||||
|
SurlApplication.context.getBean(name, type.java) as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun getValue(thisRef: Any?, property: KProperty<*>): T = value
|
||||||
|
}
|
||||||
|
inline fun <reified T : Any> autowired(name: String? = null) = Autowired(T::class, name)
|
@ -1,6 +1,6 @@
|
|||||||
package dev.surl.surl.util
|
package dev.surl.surl.util
|
||||||
|
|
||||||
import dev.surl.surl.cfg.BaseConfiguration
|
import dev.surl.surl.cfg.BaseConfig
|
||||||
import dev.surl.surl.cfg.Logging
|
import dev.surl.surl.cfg.Logging
|
||||||
import io.jsonwebtoken.Claims
|
import io.jsonwebtoken.Claims
|
||||||
import io.jsonwebtoken.Jwts
|
import io.jsonwebtoken.Jwts
|
||||||
@ -15,7 +15,7 @@ import java.util.Date
|
|||||||
@ConfigurationProperties(prefix = "jwt")
|
@ConfigurationProperties(prefix = "jwt")
|
||||||
class JwtTokenUtil {
|
class JwtTokenUtil {
|
||||||
@Autowired
|
@Autowired
|
||||||
private lateinit var cfg: BaseConfiguration
|
private lateinit var cfg: BaseConfig
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private lateinit var logging: Logging
|
private lateinit var logging: Logging
|
||||||
|
@ -4,19 +4,16 @@ import org.noelware.charted.snowflake.Snowflake
|
|||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
private val CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!*().-_~".toCharArray()
|
private val CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!*().-_~".toCharArray()
|
||||||
private const val LENGTH = 11
|
|
||||||
private val snowflake = Snowflake()
|
private val snowflake = Snowflake()
|
||||||
|
|
||||||
fun numberToKey(number: Long): String {
|
fun numberToKey(number: Long): String {
|
||||||
|
if(number == 0L) throw Exception("serial number cannot be zero")
|
||||||
var num = number
|
var num = number
|
||||||
val sb = StringBuilder()
|
val sb = StringBuilder()
|
||||||
for(i in LENGTH - 1 downTo 0) {
|
while(num != 0L) {
|
||||||
val remainder = num % CHARS.size
|
val remainder = num % CHARS.size
|
||||||
sb.append(CHARS[remainder.toInt()])
|
sb.append(CHARS[remainder.toInt()])
|
||||||
num /= CHARS.size
|
num /= CHARS.size
|
||||||
if(num == 0L) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return sb.reverse().toString()
|
return sb.reverse().toString()
|
||||||
}
|
}
|
||||||
|
16
src/main/java/dev/surl/surl/util/redis/RedisUtil.kt
Normal file
16
src/main/java/dev/surl/surl/util/redis/RedisUtil.kt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package dev.surl.surl.util.redis
|
||||||
|
|
||||||
|
import org.springframework.data.redis.core.StringRedisTemplate
|
||||||
|
|
||||||
|
|
||||||
|
class RedisUtil {
|
||||||
|
private val template = StringRedisTemplate()
|
||||||
|
fun get(key: String): String? {
|
||||||
|
return template.opsForValue().get(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun batchSet(map: Map<String, String>) {
|
||||||
|
template.executePipelined {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -32,4 +32,7 @@ spring:
|
|||||||
logging:
|
logging:
|
||||||
level:
|
level:
|
||||||
root: info
|
root: info
|
||||||
Exposed: warn
|
Exposed: debug
|
||||||
|
base:
|
||||||
|
configs:
|
||||||
|
expire: 1000
|
Loading…
Reference in New Issue
Block a user