Skip to content

Commit

Permalink
feat: unified management of service instantiation
Browse files Browse the repository at this point in the history
  • Loading branch information
ShiinaKin committed Sep 13, 2024
1 parent a1432fd commit 2057322
Show file tree
Hide file tree
Showing 15 changed files with 205 additions and 39 deletions.
2 changes: 2 additions & 0 deletions app/src/main/kotlin/io/sakurasou/Application.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.sakurasou

import io.ktor.server.application.*
import io.sakurasou.config.InstanceCenter
import io.sakurasou.config.configureDatabase
import io.sakurasou.config.configureJwt
import io.sakurasou.plugins.*
Expand All @@ -17,6 +18,7 @@ fun Application.module() {
val redisPort = environment.config.property("ktor.application.cache.redis.port").getString()

configureDatabase()
InstanceCenter.initService()
configureCache(redisHost, redisPort)
configureJwt()
configureSecurity()
Expand Down
32 changes: 32 additions & 0 deletions app/src/main/kotlin/io/sakurasou/config/InstanceCenter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ import io.sakurasou.model.dao.strategy.StrategyDao
import io.sakurasou.model.dao.strategy.StrategyDaoImpl
import io.sakurasou.model.dao.user.UserDao
import io.sakurasou.model.dao.user.UserDaoImpl
import io.sakurasou.service.album.AlbumService
import io.sakurasou.service.album.AlbumServiceImpl
import io.sakurasou.service.auth.AuthService
import io.sakurasou.service.auth.AuthServiceImpl
import io.sakurasou.service.common.CommonService
import io.sakurasou.service.common.CommonServiceImpl
import io.sakurasou.service.image.ImageService
import io.sakurasou.service.setting.SettingService
import io.sakurasou.service.setting.SettingServiceImpl
import io.sakurasou.service.user.UserService
import io.sakurasou.service.user.UserServiceImpl

/**
* @author Shiina Kin
Expand All @@ -34,6 +45,18 @@ object InstanceCenter {
lateinit var permissionDao: PermissionDao
lateinit var relationDao: RelationDao

lateinit var authService: AuthService
lateinit var userService: UserService
lateinit var imageService: ImageService
lateinit var albumService: AlbumService
// lateinit var strategyService: UserService
lateinit var settingService: SettingService
lateinit var commonService: CommonService
// lateinit var roleService: UserService
// lateinit var permissionService: UserService
// lateinit var relationService: UserService


fun initDao() {
userDao = UserDaoImpl()
imageDao = ImageDaoImpl()
Expand All @@ -45,4 +68,13 @@ object InstanceCenter {
permissionDao = PermissionDaoImpl()
relationDao = RelationDaoImpl()
}

fun initService() {
albumService = AlbumServiceImpl(albumDao)
settingService = SettingServiceImpl(settingDao)
authService = AuthServiceImpl(userDao, relationDao)

userService = UserServiceImpl(userDao, albumService, settingService)
commonService = CommonServiceImpl(userDao, albumService, settingService)
}
}
12 changes: 5 additions & 7 deletions app/src/main/kotlin/io/sakurasou/controller/AuthController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,15 @@ import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.sakurasou.controller.request.UserInsertRequest
import io.sakurasou.controller.request.UserLoginRequest
import io.sakurasou.model.dao.relation.RelationDao
import io.sakurasou.model.dao.user.UserDao
import io.sakurasou.service.auth.AuthService
import io.sakurasou.service.auth.AuthServiceImpl
import io.sakurasou.service.user.UserService

/**
* @author Shiina Kin
* 2024/9/12 10:14
*/
fun Route.authRoute(userDao: UserDao, relationDao: RelationDao) {
val authService = AuthServiceImpl(userDao, relationDao)
val authController = AuthController(authService)
fun Route.authRoute(authService: AuthService, userService: UserService) {
val authController = AuthController(authService, userService)
route("user", {
protected = false
}) {
Expand Down Expand Up @@ -49,7 +46,8 @@ fun Route.authRoute(userDao: UserDao, relationDao: RelationDao) {
}

class AuthController(
private val authService: AuthService
private val authService: AuthService,
private val userService: UserService
) {
suspend fun handleLogin(loginRequest: UserLoginRequest): String {
return authService.login(loginRequest)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import io.github.smiley4.ktorswaggerui.dsl.routing.route
import io.ktor.http.*
import io.ktor.server.routing.*
import io.sakurasou.controller.request.SiteInitRequest
import io.sakurasou.service.common.CommonService

/**
* @author Shiina Kin
* 2024/9/9 09:03
*/
fun Route.commonRoute() {
fun Route.commonRoute(commonService: CommonService) {
val commonController = CommonController(commonService)
route("site") {
post("init", {
request {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ import io.sakurasou.service.user.UserServiceImpl
* 2024/9/5 15:35
*/

fun Route.userRoute(userDao: UserDao) {
val userService = UserServiceImpl(userDao)
fun Route.userRoute(userService: UserService) {
val userController = UserController(userService)
route("user", {
protected = true
Expand Down
9 changes: 6 additions & 3 deletions app/src/main/kotlin/io/sakurasou/plugins/Routing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,11 @@ import io.ktor.server.resources.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.util.*
import io.sakurasou.config.InstanceCenter.authService
import io.sakurasou.config.InstanceCenter.commonService
import io.sakurasou.config.InstanceCenter.relationDao
import io.sakurasou.config.InstanceCenter.userDao
import io.sakurasou.config.InstanceCenter.userService
import io.sakurasou.controller.*
import io.sakurasou.exception.FileSizeException
import io.sakurasou.exception.UnauthorizedAccessException
Expand Down Expand Up @@ -45,8 +48,8 @@ fun Application.configureRouting() {
install(DoubleReceive)
routing {
route("api") {
authRoute(userDao, relationDao)
cacheOutput { commonRoute() }
authRoute(authService, userService)
cacheOutput { commonRoute(commonService) }
authenticate("auth-jwt") {
intercept(ApplicationCallPipeline.Call) {
val principal = call.principal<JWTPrincipal>()
Expand All @@ -62,7 +65,7 @@ fun Application.configureRouting() {
albumRoute()
strategyRoute()
settingRoute()
userRoute(userDao)
userRoute(userService)
groupRoute()
roleRoute()
}
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/kotlin/io/sakurasou/service/album/AlbumService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.sakurasou.service.album

/**
* @author Shiina Kin
* 2024/9/13 14:48
*/
interface AlbumService {
suspend fun initAlbumForUser(userId: Long)
suspend fun saveAlbum()
}
28 changes: 28 additions & 0 deletions app/src/main/kotlin/io/sakurasou/service/album/AlbumServiceImpl.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.sakurasou.service.album

import io.sakurasou.model.DatabaseSingleton.dbQuery
import io.sakurasou.model.dao.album.AlbumDao
import io.sakurasou.model.dto.AlbumInsertDTO
import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime

/**
* @author Shiina Kin
* 2024/9/13 14:48
*/
class AlbumServiceImpl(
private val albumDao: AlbumDao
) : AlbumService {
override suspend fun initAlbumForUser(userId: Long) {
val now = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
val uncategorizedAlbum = AlbumInsertDTO(userId, "uncategorized", "default, cannot delete", 0, now)
dbQuery {
albumDao.saveAlbum(uncategorizedAlbum)
}
}

override suspend fun saveAlbum() {
TODO("Not yet implemented")
}
}
2 changes: 0 additions & 2 deletions app/src/main/kotlin/io/sakurasou/service/auth/AuthService.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package io.sakurasou.service.auth

import io.sakurasou.controller.request.UserInsertRequest
import io.sakurasou.controller.request.UserLoginRequest

/**
Expand All @@ -9,5 +8,4 @@ import io.sakurasou.controller.request.UserLoginRequest
*/
interface AuthService {
suspend fun login(loginRequest: UserLoginRequest): String
suspend fun saveUser(userInsertRequest: UserInsertRequest)
}
22 changes: 0 additions & 22 deletions app/src/main/kotlin/io/sakurasou/service/auth/AuthServiceImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,14 @@ import com.auth0.jwt.algorithms.Algorithm
import io.sakurasou.config.JwtConfig.audience
import io.sakurasou.config.JwtConfig.issuer
import io.sakurasou.config.JwtConfig.jwkProvider
import io.sakurasou.controller.request.UserInsertRequest
import io.sakurasou.controller.request.UserLoginRequest
import io.sakurasou.exception.UnauthorizedAccessException
import io.sakurasou.exception.UserNotFoundException
import io.sakurasou.model.DatabaseSingleton.dbQuery
import io.sakurasou.model.dao.relation.RelationDao
import io.sakurasou.model.dao.user.UserDao
import io.sakurasou.model.dto.UserInsertDTO
import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toJavaInstant
import kotlinx.datetime.toLocalDateTime
import java.security.KeyFactory
import java.security.interfaces.RSAPrivateKey
import java.security.interfaces.RSAPublicKey
Expand Down Expand Up @@ -56,22 +52,4 @@ class AuthServiceImpl(
.sign(Algorithm.RSA256(publicKey as RSAPublicKey, privateKey as RSAPrivateKey))
return token
}

override suspend fun saveUser(userInsertRequest: UserInsertRequest) {
val rowPassword = userInsertRequest.password
val encodePassword = BCrypt.withDefaults().hashToString(12, rowPassword.toCharArray())

val now = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
val userInsertDTO = UserInsertDTO(
userInsertRequest.groupId,
userInsertRequest.username,
encodePassword,
userInsertRequest.email,
now,
now
)
dbQuery {
userDao.saveUser(userInsertDTO)
}
}
}
11 changes: 11 additions & 0 deletions app/src/main/kotlin/io/sakurasou/service/common/CommonService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.sakurasou.service.common

import io.sakurasou.controller.request.SiteInitRequest

/**
* @author Shiina Kin
* 2024/9/13 16:23
*/
interface CommonService {
suspend fun initSite(siteInitRequest: SiteInitRequest)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.sakurasou.service.common

import at.favre.lib.crypto.bcrypt.BCrypt
import io.sakurasou.controller.request.SiteInitRequest
import io.sakurasou.exception.SiteRepeatedInitializationException
import io.sakurasou.model.DatabaseSingleton.dbQuery
import io.sakurasou.model.dao.user.UserDao
import io.sakurasou.model.dto.UserInsertDTO
import io.sakurasou.model.setting.SiteSetting
import io.sakurasou.model.setting.SystemStatus
import io.sakurasou.service.album.AlbumService
import io.sakurasou.service.setting.SettingService
import kotlinx.datetime.Clock
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime

/**
* @author Shiina Kin
* 2024/9/13 15:34
*/
class CommonServiceImpl(
private val userDao: UserDao,
private val albumService: AlbumService,
private val settingService: SettingService
) : CommonService {
override suspend fun initSite(siteInitRequest: SiteInitRequest) {
val status = settingService.getSystemStatus()
if (status.isInit) throw SiteRepeatedInitializationException()

val rawPassword = siteInitRequest.password
val encodePassword = BCrypt.withDefaults().hashToString(12, rawPassword.toCharArray())

val now = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault())
val userInsertDTO = UserInsertDTO(
groupId = 1,
username = siteInitRequest.username,
password = encodePassword,
email = siteInitRequest.email,
createTime = now,
updateTime = now
)

val oldSiteSetting = settingService.getSiteSetting()
val siteSettingConfig = SiteSetting(
siteTitle = siteInitRequest.siteTitle,
siteSubtitle = siteInitRequest.siteSubtitle,
siteDescription = siteInitRequest.siteDescription,
siteKeyword = oldSiteSetting.siteKeyword,
homePageRandomPicDisplay = oldSiteSetting.homePageRandomPicDisplay
)

val systemStatus = SystemStatus(
isInit = true
)

dbQuery {
val userId = userDao.saveUser(userInsertDTO)
albumService.initAlbumForUser(userId)
settingService.updateSiteSetting(siteSettingConfig)
settingService.updateSystemStatus(systemStatus)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.sakurasou.service.group

/**
* @author Shiina Kin
* 2024/9/13 14:47
*/
interface GroupService {
fun saveGroup()
}
4 changes: 3 additions & 1 deletion app/src/main/kotlin/io/sakurasou/service/user/UserService.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package io.sakurasou.service.user

import io.sakurasou.controller.request.UserInsertRequest

/**
* @author ShiinaKin
* 2024/9/5 15:30
*/
interface UserService {

suspend fun saveUser(userInsertRequest: UserInsertRequest)
}
Loading

0 comments on commit 2057322

Please sign in to comment.