diff --git a/app/src/main/kotlin/io/sakurasou/config/ExceptionHandler.kt b/app/src/main/kotlin/io/sakurasou/config/ExceptionHandler.kt new file mode 100644 index 00000000..664b908f --- /dev/null +++ b/app/src/main/kotlin/io/sakurasou/config/ExceptionHandler.kt @@ -0,0 +1,24 @@ +package io.sakurasou.config + +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.plugins.statuspages.* +import io.ktor.server.response.* +import io.ktor.util.logging.* +import io.sakurasou.exception.ServiceThrowable +import io.sakurasou.extension.failure +import org.jetbrains.exposed.sql.exposedLogger + +/** + * @author ShiinaKin + * 2024/10/6 17:26 + */ +fun StatusPagesConfig.exceptionHandler() { + exception { call, cause -> + exposedLogger.error(cause) + call.respondText(text = "500: $cause", status = HttpStatusCode.InternalServerError) + } + exception { call: ApplicationCall, cause -> + call.failure(cause) + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/io/sakurasou/config/InstanceCenter.kt b/app/src/main/kotlin/io/sakurasou/config/InstanceCenter.kt index 485774a0..f3ee60ca 100644 --- a/app/src/main/kotlin/io/sakurasou/config/InstanceCenter.kt +++ b/app/src/main/kotlin/io/sakurasou/config/InstanceCenter.kt @@ -29,6 +29,7 @@ import io.sakurasou.service.common.CommonServiceImpl import io.sakurasou.service.group.GroupService import io.sakurasou.service.group.GroupServiceImpl import io.sakurasou.service.image.ImageService +import io.sakurasou.service.image.ImageServiceImpl import io.sakurasou.service.role.RoleService import io.sakurasou.service.role.RoleServiceImpl import io.sakurasou.service.setting.SettingService @@ -88,6 +89,7 @@ object InstanceCenter { strategyService = StrategyServiceImpl(strategyDao) authService = AuthServiceImpl(userDao, relationDao) groupService = GroupServiceImpl(groupDao, relationDao) + imageService = ImageServiceImpl(imageDao, albumDao) commonService = CommonServiceImpl(userDao, albumDao, settingService) userService = UserServiceImpl(userDao, groupDao, albumDao, imageDao, settingService) diff --git a/app/src/main/kotlin/io/sakurasou/config/RoutingCenter.kt b/app/src/main/kotlin/io/sakurasou/config/RoutingCenter.kt new file mode 100644 index 00000000..0cda552d --- /dev/null +++ b/app/src/main/kotlin/io/sakurasou/config/RoutingCenter.kt @@ -0,0 +1,45 @@ +package io.sakurasou.config + +import io.github.smiley4.ktorswaggerui.dsl.routing.route +import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.routing.* +import io.sakurasou.config.InstanceCenter.albumService +import io.sakurasou.config.InstanceCenter.authService +import io.sakurasou.config.InstanceCenter.commonService +import io.sakurasou.config.InstanceCenter.groupService +import io.sakurasou.config.InstanceCenter.imageService +import io.sakurasou.config.InstanceCenter.roleService +import io.sakurasou.config.InstanceCenter.settingService +import io.sakurasou.config.InstanceCenter.strategyService +import io.sakurasou.config.InstanceCenter.userService +import io.sakurasou.controller.* +import io.sakurasou.exception.controller.status.SiteNotInitializationException +import io.sakurasou.extension.isSiteNotInitialized + +/** + * @author ShiinaKin + * 2024/10/6 17:22 + */ + +fun Route.apiRoute() { + route("api") { + siteInitRoute() + route { + intercept(ApplicationCallPipeline.Setup) { + if (isSiteNotInitialized()) throw SiteNotInitializationException() + } + authRoute(authService, userService) + commonRoute(commonService) + authenticate("auth-jwt") { + imageRoute(imageService) + albumRoute(albumService) + strategyRoute(strategyService) + settingRoute(settingService) + userRoute(userService) + groupRoute(groupService) + roleRoute(roleService) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/io/sakurasou/controller/AlbumController.kt b/app/src/main/kotlin/io/sakurasou/controller/AlbumController.kt index 4a6aeadf..d789ae68 100644 --- a/app/src/main/kotlin/io/sakurasou/controller/AlbumController.kt +++ b/app/src/main/kotlin/io/sakurasou/controller/AlbumController.kt @@ -19,23 +19,25 @@ import io.sakurasou.controller.vo.CommonResponse import io.sakurasou.controller.vo.PageResult import io.sakurasou.extension.pageRequest import io.sakurasou.plugins.AuthorizationPlugin +import io.sakurasou.service.album.AlbumService /** * @author Shiina Kin * 2024/9/9 08:58 */ -fun Route.albumRoute() { +fun Route.albumRoute(albumService: AlbumService) { + val controller = AlbumController(albumService) route("album") { - albumSelfRoute() - albumManageRoute() + albumSelfRoute(controller) + albumManageRoute(controller) } } -private fun Route.albumSelfRoute() { +private fun Route.albumSelfRoute(controller: AlbumController) { route({ protected = true }) { - albumSelfInsert() + albumSelfInsert(controller) route("{albumId}", { request { pathParameter("album id") { @@ -44,15 +46,15 @@ private fun Route.albumSelfRoute() { } } }) { - albumSelfDelete() - albumSelfUpdate() - albumSelfFetch() + albumSelfDelete(controller) + albumSelfUpdate(controller) + albumSelfFetch(controller) } - albumSelfPage() + albumSelfPage(controller) } } -private fun Route.albumSelfInsert() { +private fun Route.albumSelfInsert(controller: AlbumController) { route { install(AuthorizationPlugin) { permission = ALBUM_WRITE_SELF @@ -75,7 +77,7 @@ private fun Route.albumSelfInsert() { } } -private fun Route.albumSelfDelete() { +private fun Route.albumSelfDelete(controller: AlbumController) { route { install(AuthorizationPlugin) { permission = ALBUM_DELETE_SELF @@ -93,7 +95,7 @@ private fun Route.albumSelfDelete() { } } -private fun Route.albumSelfUpdate() { +private fun Route.albumSelfUpdate(controller: AlbumController) { route { install(AuthorizationPlugin) { permission = ALBUM_WRITE_SELF @@ -116,7 +118,7 @@ private fun Route.albumSelfUpdate() { } } -private fun Route.albumSelfFetch() { +private fun Route.albumSelfFetch(controller: AlbumController) { route { install(AuthorizationPlugin) { permission = ALBUM_READ_SELF_SINGLE @@ -134,7 +136,7 @@ private fun Route.albumSelfFetch() { } } -private fun Route.albumSelfPage() { +private fun Route.albumSelfPage(controller: AlbumController) { route { install(AuthorizationPlugin) { permission = ALBUM_READ_SELF_ALL @@ -153,14 +155,14 @@ private fun Route.albumSelfPage() { } } }) { - val pageVO = call.pageRequest() + val pageRequest = call.pageRequest() TODO() } } } -private fun Route.albumManageRoute() { +private fun Route.albumManageRoute(controller: AlbumController) { route("manage", { protected = true request { @@ -176,7 +178,7 @@ private fun Route.albumManageRoute() { } } }) { - albumManageInsert() + albumManageInsert(controller) route("{albumId}", { protected = true request { @@ -186,15 +188,15 @@ private fun Route.albumManageRoute() { } } }) { - albumManageDelete() - albumManageUpdate() - albumManageFetch() + albumManageDelete(controller) + albumManageUpdate(controller) + albumManageFetch(controller) } - albumManagePage() + albumManagePage(controller) } } -private fun Route.albumManageInsert() { +private fun Route.albumManageInsert(controller: AlbumController) { route { install(AuthorizationPlugin) { permission = ALBUM_WRITE_ALL @@ -217,7 +219,7 @@ private fun Route.albumManageInsert() { } } -private fun Route.albumManageDelete() { +private fun Route.albumManageDelete(controller: AlbumController) { route { install(AuthorizationPlugin) { permission = ALBUM_DELETE_ALL @@ -235,7 +237,7 @@ private fun Route.albumManageDelete() { } } -private fun Route.albumManageUpdate() { +private fun Route.albumManageUpdate(controller: AlbumController) { route { install(AuthorizationPlugin) { permission = ALBUM_WRITE_ALL @@ -258,7 +260,7 @@ private fun Route.albumManageUpdate() { } } -private fun Route.albumManageFetch() { +private fun Route.albumManageFetch(controller: AlbumController) { route { install(AuthorizationPlugin) { permission = ALBUM_READ_ALL_SINGLE @@ -276,7 +278,7 @@ private fun Route.albumManageFetch() { } } -private fun Route.albumManagePage() { +private fun Route.albumManagePage(controller: AlbumController) { route { install(AuthorizationPlugin) { permission = ALBUM_READ_ALL_ALL @@ -295,12 +297,15 @@ private fun Route.albumManagePage() { } } }) { - val pageVO = call.pageRequest() + val pageRequest = call.pageRequest() TODO() } } } -class AlbumController { +class AlbumController( + private val albumService: AlbumService +) { + } \ No newline at end of file diff --git a/app/src/main/kotlin/io/sakurasou/controller/ImageController.kt b/app/src/main/kotlin/io/sakurasou/controller/ImageController.kt index 5acb2d5e..e9012ace 100644 --- a/app/src/main/kotlin/io/sakurasou/controller/ImageController.kt +++ b/app/src/main/kotlin/io/sakurasou/controller/ImageController.kt @@ -15,21 +15,23 @@ import io.sakurasou.controller.vo.PageResult import io.sakurasou.exception.controller.param.FileSizeException import io.sakurasou.extension.pageRequest import io.sakurasou.plugins.AuthorizationPlugin +import io.sakurasou.service.image.ImageService import java.io.ByteArrayOutputStream /** * @author ShiinaKin * 2024/9/5 15:17 */ -fun Route.imageRoute() { +fun Route.imageRoute(imageService: ImageService) { + val controller = ImageController(imageService) route("image") { - imageSelfRoute() - imageManageRoute() + imageSelfRoute(controller) + imageManageRoute(controller) } } -private fun Route.imageSelfRoute() { - imageSelfUpload() +private fun Route.imageSelfRoute(controller: ImageController) { + imageSelfUpload(controller) route("{imageId}", { protected = true request { @@ -39,14 +41,14 @@ private fun Route.imageSelfRoute() { } } }) { - imageSelfDelete() - imageSelfUpdate() - imageSelfFetch() - imageSelfPage() + imageSelfDelete(controller) + imageSelfUpdate(controller) + imageSelfFetch(controller) + imageSelfPage(controller) } } -private fun Route.imageSelfUpload() { +private fun Route.imageSelfUpload(controller: ImageController) { route { install(AuthorizationPlugin) { permission = IMAGE_WRITE_SELF @@ -100,7 +102,7 @@ private fun Route.imageSelfUpload() { } } -private fun Route.imageSelfDelete() { +private fun Route.imageSelfDelete(controller: ImageController) { route { install(AuthorizationPlugin) { permission = IMAGE_DELETE_SELF @@ -118,7 +120,7 @@ private fun Route.imageSelfDelete() { } } -private fun Route.imageSelfUpdate() { +private fun Route.imageSelfUpdate(controller: ImageController) { route { install(AuthorizationPlugin) { permission = IMAGE_WRITE_SELF @@ -141,7 +143,7 @@ private fun Route.imageSelfUpdate() { } } -private fun Route.imageSelfFetch() { +private fun Route.imageSelfFetch(controller: ImageController) { route { install(AuthorizationPlugin) { permission = IMAGE_READ_SELF_SINGLE @@ -159,7 +161,7 @@ private fun Route.imageSelfFetch() { } } -private fun Route.imageSelfPage() { +private fun Route.imageSelfPage(controller: ImageController) { route { install(AuthorizationPlugin) { permission = IMAGE_READ_SELF_ALL @@ -183,7 +185,7 @@ private fun Route.imageSelfPage() { } } -private fun Route.imageManageRoute() { +private fun Route.imageManageRoute(controller: ImageController) { route("manage", { protected = true request { @@ -207,15 +209,15 @@ private fun Route.imageManageRoute() { } } }) { - imageManageDelete() - imageManageUpdate() - imageManageFetch() - imageManagePage() + imageManageDelete(controller) + imageManageUpdate(controller) + imageManageFetch(controller) + imageManagePage(controller) } } } -private fun Route.imageManageDelete() { +private fun Route.imageManageDelete(controller: ImageController) { route { install(AuthorizationPlugin) { permission = IMAGE_DELETE_ALL @@ -233,7 +235,7 @@ private fun Route.imageManageDelete() { } } -private fun Route.imageManageUpdate() { +private fun Route.imageManageUpdate(controller: ImageController) { route { install(AuthorizationPlugin) { permission = IMAGE_WRITE_ALL @@ -256,7 +258,7 @@ private fun Route.imageManageUpdate() { } } -private fun Route.imageManageFetch() { +private fun Route.imageManageFetch(controller: ImageController) { route { install(AuthorizationPlugin) { permission = IMAGE_READ_ALL_SINGLE @@ -280,7 +282,7 @@ private fun Route.imageManageFetch() { } } -private fun Route.imageManagePage() { +private fun Route.imageManagePage(controller: ImageController) { route { install(AuthorizationPlugin) { permission = IMAGE_READ_ALL_ALL @@ -304,5 +306,7 @@ private fun Route.imageManagePage() { } } -class ImageController { +class ImageController( + private val imageService: ImageService +) { } \ No newline at end of file diff --git a/app/src/main/kotlin/io/sakurasou/plugins/Routing.kt b/app/src/main/kotlin/io/sakurasou/plugins/Routing.kt index e65c1347..cfe7df58 100644 --- a/app/src/main/kotlin/io/sakurasou/plugins/Routing.kt +++ b/app/src/main/kotlin/io/sakurasou/plugins/Routing.kt @@ -1,65 +1,22 @@ package io.sakurasou.plugins -import io.github.smiley4.ktorswaggerui.dsl.routing.route -import io.ktor.http.* import io.ktor.server.application.* -import io.ktor.server.auth.* import io.ktor.server.http.content.* import io.ktor.server.plugins.autohead.* import io.ktor.server.plugins.doublereceive.* import io.ktor.server.plugins.statuspages.* import io.ktor.server.resources.* -import io.ktor.server.response.* import io.ktor.server.routing.* -import io.ktor.util.logging.* -import io.sakurasou.config.InstanceCenter.authService -import io.sakurasou.config.InstanceCenter.commonService -import io.sakurasou.config.InstanceCenter.groupService -import io.sakurasou.config.InstanceCenter.roleService -import io.sakurasou.config.InstanceCenter.settingService -import io.sakurasou.config.InstanceCenter.strategyService -import io.sakurasou.config.InstanceCenter.userService -import io.sakurasou.controller.* -import io.sakurasou.exception.ServiceThrowable -import io.sakurasou.exception.controller.status.SiteNotInitializationException -import io.sakurasou.extension.failure -import io.sakurasou.extension.isSiteNotInitialized -import org.jetbrains.exposed.sql.exposedLogger +import io.sakurasou.config.apiRoute +import io.sakurasou.config.exceptionHandler fun Application.configureRouting() { install(Resources) - install(StatusPages) { - exception { call, cause -> - exposedLogger.error(cause) - call.respondText(text = "500: $cause", status = HttpStatusCode.InternalServerError) - } - exception { call: ApplicationCall, cause -> - call.failure(cause) - } - } + install(StatusPages) { exceptionHandler() } install(AutoHeadResponse) install(DoubleReceive) routing { - route("api") { - siteInitRoute() - - route { - intercept(ApplicationCallPipeline.Setup) { - if (isSiteNotInitialized()) throw SiteNotInitializationException() - } - authRoute(authService, userService) - commonRoute(commonService) - authenticate("auth-jwt") { - imageRoute() - albumRoute() - strategyRoute(strategyService) - settingRoute(settingService) - userRoute(userService) - groupRoute(groupService) - roleRoute(roleService) - } - } - } + apiRoute() staticResources("", "static") // post("/double-receive") { // val first = call.receiveText() diff --git a/app/src/main/kotlin/io/sakurasou/service/image/ImageServiceImpl.kt b/app/src/main/kotlin/io/sakurasou/service/image/ImageServiceImpl.kt index 6a1c42cd..3d459f90 100644 --- a/app/src/main/kotlin/io/sakurasou/service/image/ImageServiceImpl.kt +++ b/app/src/main/kotlin/io/sakurasou/service/image/ImageServiceImpl.kt @@ -1,9 +1,15 @@ package io.sakurasou.service.image +import io.sakurasou.model.dao.album.AlbumDao +import io.sakurasou.model.dao.image.ImageDao + /** * @author ShiinaKin * 2024/9/5 15:12 */ -class ImageServiceImpl : ImageService { +class ImageServiceImpl( + private val imageDao: ImageDao, + private val albumDao: AlbumDao +) : ImageService { } \ No newline at end of file