From b0616a1098e644015af9a1bc05b602edf16e65ba Mon Sep 17 00:00:00 2001 From: 05412 Date: Fri, 12 Jul 2024 17:43:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=9D=83=E9=99=90=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../java/dev/surl/surl/SurlApplication.kt | 2 +- src/main/java/dev/surl/surl/cfg/BaseConfig.kt | 21 +++++++ .../dev/surl/surl/cfg/BaseConfiguration.kt | 14 ----- .../java/dev/surl/surl/cfg/PatternConfig.kt | 9 +++ .../surl/surl/cfg/security/EncoderConfig.kt | 17 +++++ .../surl/cfg/security/WebSecurityConfig.kt | 32 +++------- src/main/java/dev/surl/surl/common/Access.kt | 5 ++ .../common/exception/UserRegistException.kt | 2 +- .../surl/controller/RedirectController.kt | 6 +- .../surl/surl/controller/SurlAddController.kt | 6 +- src/main/java/dev/surl/surl/dao/UserAccess.kt | 18 ++++++ src/main/java/dev/surl/surl/dsl/Surls.kt | 2 +- .../java/dev/surl/surl/dsl/UserAccesses.kt | 9 +++ src/main/java/dev/surl/surl/dsl/Users.kt | 2 +- src/main/java/dev/surl/surl/dto/SurlDto.kt | 2 +- src/main/java/dev/surl/surl/dto/UserDto.kt | 2 +- .../surl/handler/DefaultExceptionHandler.kt | 6 +- .../java/dev/surl/surl/service/SurlService.kt | 11 +--- .../java/dev/surl/surl/service/UserService.kt | 62 ++++++++++++++----- src/main/java/dev/surl/surl/util/Autowired.kt | 18 ++++++ .../java/dev/surl/surl/util/JwtTokenUtil.kt | 4 +- src/main/java/dev/surl/surl/util/UIDUtil.kt | 7 +-- .../dev/surl/surl/util/redis/RedisUtil.kt | 16 +++++ src/main/resources/application.yml | 5 +- 25 files changed, 198 insertions(+), 81 deletions(-) create mode 100644 src/main/java/dev/surl/surl/cfg/BaseConfig.kt delete mode 100644 src/main/java/dev/surl/surl/cfg/BaseConfiguration.kt create mode 100644 src/main/java/dev/surl/surl/cfg/PatternConfig.kt create mode 100644 src/main/java/dev/surl/surl/cfg/security/EncoderConfig.kt create mode 100644 src/main/java/dev/surl/surl/common/Access.kt create mode 100644 src/main/java/dev/surl/surl/dao/UserAccess.kt create mode 100644 src/main/java/dev/surl/surl/dsl/UserAccesses.kt create mode 100644 src/main/java/dev/surl/surl/util/Autowired.kt create mode 100644 src/main/java/dev/surl/surl/util/redis/RedisUtil.kt diff --git a/build.gradle b/build.gradle index 728c46c..98dad62 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,7 @@ dependencies { implementation "org.noelware.charted.snowflake:snowflake:0.1-beta" implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'io.jsonwebtoken:jjwt-api:0.12.6' + implementation 'org.springframework.boot:spring-boot-starter-data-redis' testImplementation 'org.springframework.security:spring-security-test' compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/src/main/java/dev/surl/surl/SurlApplication.kt b/src/main/java/dev/surl/surl/SurlApplication.kt index 48414d6..95c0aa5 100644 --- a/src/main/java/dev/surl/surl/SurlApplication.kt +++ b/src/main/java/dev/surl/surl/SurlApplication.kt @@ -13,4 +13,4 @@ open class SurlApplication { fun main(args: Array) { SurlApplication.context = runApplication(*args) -} +} \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/cfg/BaseConfig.kt b/src/main/java/dev/surl/surl/cfg/BaseConfig.kt new file mode 100644 index 0000000..3e82050 --- /dev/null +++ b/src/main/java/dev/surl/surl/cfg/BaseConfig.kt @@ -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" +) \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/cfg/BaseConfiguration.kt b/src/main/java/dev/surl/surl/cfg/BaseConfiguration.kt deleted file mode 100644 index 6622b85..0000000 --- a/src/main/java/dev/surl/surl/cfg/BaseConfiguration.kt +++ /dev/null @@ -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" -) diff --git a/src/main/java/dev/surl/surl/cfg/PatternConfig.kt b/src/main/java/dev/surl/surl/cfg/PatternConfig.kt new file mode 100644 index 0000000..e92767f --- /dev/null +++ b/src/main/java/dev/surl/surl/cfg/PatternConfig.kt @@ -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$""") +} \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/cfg/security/EncoderConfig.kt b/src/main/java/dev/surl/surl/cfg/security/EncoderConfig.kt new file mode 100644 index 0000000..a24a16d --- /dev/null +++ b/src/main/java/dev/surl/surl/cfg/security/EncoderConfig.kt @@ -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`) + } +} \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/cfg/security/WebSecurityConfig.kt b/src/main/java/dev/surl/surl/cfg/security/WebSecurityConfig.kt index 16ada58..8a823fe 100644 --- a/src/main/java/dev/surl/surl/cfg/security/WebSecurityConfig.kt +++ b/src/main/java/dev/surl/surl/cfg/security/WebSecurityConfig.kt @@ -1,6 +1,5 @@ package dev.surl.surl.cfg.security -import dev.surl.surl.cfg.Logging import jakarta.servlet.FilterChain import jakarta.servlet.http.HttpServletRequest 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.web.SecurityFilterChain 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 @Configuration @@ -30,29 +27,20 @@ open class WebSecurityConfig { headers { cacheControl { } // 禁用缓存 } - } return http.build() } - /** - * 装载BCrypt密码编码器 - */ @Bean - open fun passwordEncoder(): BCryptPasswordEncoder { - return BCryptPasswordEncoder() + open fun authenticationTokenFilter(): OncePerRequestFilter { + 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) -// } -// } -// } } diff --git a/src/main/java/dev/surl/surl/common/Access.kt b/src/main/java/dev/surl/surl/common/Access.kt new file mode 100644 index 0000000..a4bdbb4 --- /dev/null +++ b/src/main/java/dev/surl/surl/common/Access.kt @@ -0,0 +1,5 @@ +package dev.surl.surl.common + +enum class Access { + ADMIN, READ, WRITE +} \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/common/exception/UserRegistException.kt b/src/main/java/dev/surl/surl/common/exception/UserRegistException.kt index 4c0efee..1ba5479 100644 --- a/src/main/java/dev/surl/surl/common/exception/UserRegistException.kt +++ b/src/main/java/dev/surl/surl/common/exception/UserRegistException.kt @@ -1,3 +1,3 @@ package dev.surl.surl.common.exception -class UserRegistException(message: String? = null, cause: Throwable? = null): Throwable(message, cause) \ No newline at end of file +class UserRegistException(message: String? = null, cause: Throwable? = null): Exception(message, cause) \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/controller/RedirectController.kt b/src/main/java/dev/surl/surl/controller/RedirectController.kt index 2dd3370..83b655f 100644 --- a/src/main/java/dev/surl/surl/controller/RedirectController.kt +++ b/src/main/java/dev/surl/surl/controller/RedirectController.kt @@ -1,6 +1,6 @@ package dev.surl.surl.controller -import dev.surl.surl.cfg.BaseConfiguration +import dev.surl.surl.cfg.BaseConfig import dev.surl.surl.service.SurlService import jakarta.validation.Valid import org.hibernate.validator.constraints.Length @@ -15,9 +15,9 @@ import java.net.URI class RedirectController { @GetMapping("/{key}") 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 cfg: BaseConfiguration + @Autowired cfg: BaseConfig ): ResponseEntity { val redirectUrl = service.getUrlByKey(key) return if(redirectUrl.isBlank()) { diff --git a/src/main/java/dev/surl/surl/controller/SurlAddController.kt b/src/main/java/dev/surl/surl/controller/SurlAddController.kt index 77ff86e..544249c 100644 --- a/src/main/java/dev/surl/surl/controller/SurlAddController.kt +++ b/src/main/java/dev/surl/surl/controller/SurlAddController.kt @@ -1,8 +1,8 @@ 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.dto.Surl +import dev.surl.surl.dto.SurlDto import dev.surl.surl.service.SurlService import jakarta.validation.Valid import org.springframework.beans.factory.annotation.Autowired @@ -19,7 +19,7 @@ import org.springframework.web.bind.annotation.RestController class SurlAddController { @RequestMapping("/surl/add") fun addSurl( - @Valid @RequestBody body: Surl, @Autowired service: SurlService, @Autowired cfg: BaseConfiguration + @Valid @RequestBody body: SurlDto, @Autowired service: SurlService, @Autowired cfg: BaseConfig ): Any { return ResponseEntity(Msg(code = 0, value = "${cfg.site}/${service.addSurl(body.url ?: "")}"), HttpStatus.OK) } diff --git a/src/main/java/dev/surl/surl/dao/UserAccess.kt b/src/main/java/dev/surl/surl/dao/UserAccess.kt new file mode 100644 index 0000000..e146c04 --- /dev/null +++ b/src/main/java/dev/surl/surl/dao/UserAccess.kt @@ -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): LongEntity(id) { + companion object EntityClass: LongEntityClass(UserAccesses) + var access by UserAccesses.access.transform(toColumn = { + it.ordinal.toShort() + }, toReal = { + Access.entries[it.toInt()] + }) + var user by User referencedOn UserAccesses.user +} \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/dsl/Surls.kt b/src/main/java/dev/surl/surl/dsl/Surls.kt index b0afdd7..6b2a682 100644 --- a/src/main/java/dev/surl/surl/dsl/Surls.kt +++ b/src/main/java/dev/surl/surl/dsl/Surls.kt @@ -5,6 +5,6 @@ import org.jetbrains.exposed.dao.id.IdTable object Surls: IdTable("surl") { override val id = long("id").entityId() 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") } \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/dsl/UserAccesses.kt b/src/main/java/dev/surl/surl/dsl/UserAccesses.kt new file mode 100644 index 0000000..711688a --- /dev/null +++ b/src/main/java/dev/surl/surl/dsl/UserAccesses.kt @@ -0,0 +1,9 @@ +package dev.surl.surl.dsl + +import org.jetbrains.exposed.dao.id.IdTable + +object UserAccesses: IdTable("user_access") { + override val id = long("id").entityId() + val user = reference("user", Users).index() + val access = short("access") +} \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/dsl/Users.kt b/src/main/java/dev/surl/surl/dsl/Users.kt index 5dd2cfe..645835c 100644 --- a/src/main/java/dev/surl/surl/dsl/Users.kt +++ b/src/main/java/dev/surl/surl/dsl/Users.kt @@ -5,6 +5,6 @@ import org.jetbrains.exposed.dao.id.IdTable object Users: IdTable("users") { override val id = long("id").entityId() 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") } \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/dto/SurlDto.kt b/src/main/java/dev/surl/surl/dto/SurlDto.kt index 799942d..f09c814 100644 --- a/src/main/java/dev/surl/surl/dto/SurlDto.kt +++ b/src/main/java/dev/surl/surl/dto/SurlDto.kt @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty import jakarta.validation.constraints.NotNull import org.hibernate.validator.constraints.Length -data class Surl( +data class SurlDto( @JsonProperty("url") @get:NotNull(message = "url cannot be empty") @get:Length(min = 11, max = 2048, message = "url length invalid") diff --git a/src/main/java/dev/surl/surl/dto/UserDto.kt b/src/main/java/dev/surl/surl/dto/UserDto.kt index aa1c538..18539c2 100644 --- a/src/main/java/dev/surl/surl/dto/UserDto.kt +++ b/src/main/java/dev/surl/surl/dto/UserDto.kt @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty import jakarta.validation.constraints.NotNull import org.hibernate.validator.constraints.Length -class UserDto ( +data class UserDto ( @JsonProperty("username") @get:Length(max = 16, min = 4, message = "username length must be between 4 and 16") @get:NotNull(message = "username cannot be null") diff --git a/src/main/java/dev/surl/surl/handler/DefaultExceptionHandler.kt b/src/main/java/dev/surl/surl/handler/DefaultExceptionHandler.kt index 2057108..1c9e8e3 100644 --- a/src/main/java/dev/surl/surl/handler/DefaultExceptionHandler.kt +++ b/src/main/java/dev/surl/surl/handler/DefaultExceptionHandler.kt @@ -38,7 +38,7 @@ class DefaultExceptionHandler : ResponseEntityExceptionHandler() { return ResponseEntity(Msg(code = -1, msg = ex.message ?: "unknown error"), status) } - @ExceptionHandler(value = [Exception::class]) + @ExceptionHandler(value = [IllegalStateException::class ,Exception::class]) fun handleException( ex: Exception ): ResponseEntity> { @@ -46,8 +46,8 @@ class DefaultExceptionHandler : ResponseEntityExceptionHandler() { } @ExceptionHandler(value = [UserRegistException::class]) - fun handleUserRegistException(ex: Exception, headers: HttpHeaders, status: HttpStatusCode, request: WebRequest + fun handleUserRegistException(ex: Exception ): ResponseEntity>{ - 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) } } \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/service/SurlService.kt b/src/main/java/dev/surl/surl/service/SurlService.kt index 370eb1c..682a66b 100644 --- a/src/main/java/dev/surl/surl/service/SurlService.kt +++ b/src/main/java/dev/surl/surl/service/SurlService.kt @@ -16,19 +16,14 @@ class SurlService { url = baseurl } } - return@runBlocking numberToKey(id) + numberToKey(id) } fun getUrlByKey(key: String): String { return transaction { - val results = Surls.select(Surls.url).where { + Surls.select(Surls.url).where { Surls.id eq keyToNumber(key) - }.toList() - if (results.isNotEmpty()) { - return@transaction results.first()[Surls.url] - } else { - return@transaction "" - } + }.firstOrNull()?.get(Surls.url) ?: "" } } } \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/service/UserService.kt b/src/main/java/dev/surl/surl/service/UserService.kt index 9e0cc99..2d643be 100644 --- a/src/main/java/dev/surl/surl/service/UserService.kt +++ b/src/main/java/dev/surl/surl/service/UserService.kt @@ -1,43 +1,77 @@ 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.exception.UserRegistException import dev.surl.surl.dao.User +import dev.surl.surl.dao.UserAccess import dev.surl.surl.dsl.Users +import dev.surl.surl.util.autowired import dev.surl.surl.util.genSnowflakeUID import dev.surl.surl.util.numberToKey import kotlinx.coroutines.runBlocking 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.stereotype.Service +typealias AUser = org.springframework.security.core.userdetails.User + @Service -class UserService(@Autowired private val passwordEncoder: BCryptPasswordEncoder) { +class UserService: UserDetailsService { + private val passwordEncoder: BCryptPasswordEncoder by autowired() fun addUser(username: String, password: String): Msg { -// if (passwordEncoder == null) throw Exception("password encoder is null") -// val passwordEncoder = SurlApplication.context.getBean("bcryptor") as PasswordEncoder - val id = runBlocking { - genSnowflakeUID() + + val (id, accessId) = runBlocking { + Pair(genSnowflakeUID(), genSnowflakeUID()) } val encryptedPassword = passwordEncoder.encode(password) transaction { if (isUserExist(username)) { throw UserRegistException("user is existed") } - User.new(id) { + val user = User.new(id) { this.username = username this.password = encryptedPassword } + addDefaultAccess(accessId, user) } - @Suppress("unused") return Msg(value = object { - val id = numberToKey(id) - val username = username - }) + return Msg(value = mapOf( + "id" to numberToKey(id), + "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 - }.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() + } } \ No newline at end of file diff --git a/src/main/java/dev/surl/surl/util/Autowired.kt b/src/main/java/dev/surl/surl/util/Autowired.kt new file mode 100644 index 0000000..85c7721 --- /dev/null +++ b/src/main/java/dev/surl/surl/util/Autowired.kt @@ -0,0 +1,18 @@ +package dev.surl.surl.util + +import dev.surl.surl.SurlApplication +import kotlin.reflect.KClass +import kotlin.reflect.KProperty + +class Autowired(private val type: KClass, 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 autowired(name: String? = null) = Autowired(T::class, name) diff --git a/src/main/java/dev/surl/surl/util/JwtTokenUtil.kt b/src/main/java/dev/surl/surl/util/JwtTokenUtil.kt index 36fa18d..b40d9e4 100644 --- a/src/main/java/dev/surl/surl/util/JwtTokenUtil.kt +++ b/src/main/java/dev/surl/surl/util/JwtTokenUtil.kt @@ -1,6 +1,6 @@ package dev.surl.surl.util -import dev.surl.surl.cfg.BaseConfiguration +import dev.surl.surl.cfg.BaseConfig import dev.surl.surl.cfg.Logging import io.jsonwebtoken.Claims import io.jsonwebtoken.Jwts @@ -15,7 +15,7 @@ import java.util.Date @ConfigurationProperties(prefix = "jwt") class JwtTokenUtil { @Autowired - private lateinit var cfg: BaseConfiguration + private lateinit var cfg: BaseConfig @Autowired private lateinit var logging: Logging diff --git a/src/main/java/dev/surl/surl/util/UIDUtil.kt b/src/main/java/dev/surl/surl/util/UIDUtil.kt index dc2b32f..5409fe4 100644 --- a/src/main/java/dev/surl/surl/util/UIDUtil.kt +++ b/src/main/java/dev/surl/surl/util/UIDUtil.kt @@ -4,19 +4,16 @@ import org.noelware.charted.snowflake.Snowflake import kotlin.math.pow private val CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!*().-_~".toCharArray() -private const val LENGTH = 11 private val snowflake = Snowflake() fun numberToKey(number: Long): String { + if(number == 0L) throw Exception("serial number cannot be zero") var num = number val sb = StringBuilder() - for(i in LENGTH - 1 downTo 0) { + while(num != 0L) { val remainder = num % CHARS.size sb.append(CHARS[remainder.toInt()]) num /= CHARS.size - if(num == 0L) { - break - } } return sb.reverse().toString() } diff --git a/src/main/java/dev/surl/surl/util/redis/RedisUtil.kt b/src/main/java/dev/surl/surl/util/redis/RedisUtil.kt new file mode 100644 index 0000000..c7429fb --- /dev/null +++ b/src/main/java/dev/surl/surl/util/redis/RedisUtil.kt @@ -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) { + template.executePipelined { + } + } +} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index a6a3c1d..e11f5c3 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -32,4 +32,7 @@ spring: logging: level: root: info - Exposed: warn \ No newline at end of file + Exposed: debug +base: + configs: + expire: 1000 \ No newline at end of file