diff --git a/backend/build.gradle.kts b/backend/build.gradle.kts index 9091c07..faa8d89 100644 --- a/backend/build.gradle.kts +++ b/backend/build.gradle.kts @@ -29,9 +29,8 @@ dependencies { implementation(libs.exposed) implementation(libs.exposed.dao) implementation(libs.exposed.jdbc) + implementation(libs.migration) implementation(libs.postgres) - implementation(libs.koin) - implementation(libs.koin.logger) implementation(libs.random) implementation(libs.otp) implementation(libs.kdf) diff --git a/backend/gradle/libs.versions.toml b/backend/gradle/libs.versions.toml index 3024f99..05e0555 100644 --- a/backend/gradle/libs.versions.toml +++ b/backend/gradle/libs.versions.toml @@ -2,8 +2,8 @@ kotlin = "2.2.10" ktor = "3.2.3" exposed = "0.60.0" +migration = "1.0.0" postgres = "42.7.5" -koin = "4.1.0" random = "1.0.0" otp = "1.1.1" kdf = "1.0.3" @@ -30,11 +30,9 @@ ktor-server-validation = { module = "io.ktor:ktor-server-request-validation", ve exposed = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" } exposed-dao = { module = "org.jetbrains.exposed:exposed-dao", version.ref = "exposed" } exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" } +migration = { module = "com.infendro:ktor-migration", version.ref = "migration" } postgres = { module = "org.postgresql:postgresql", version.ref = "postgres" } -koin = { module = "io.insert-koin:koin-ktor", version.ref = "koin" } -koin-logger = { module = "io.insert-koin:koin-logger-slf4j", version.ref = "koin" } - random = { module = "com.infendro:random", version.ref = "random" } otp = { module = "com.infendro:otp", version.ref = "otp" } kdf = { module = "com.infendro:kdf", version.ref = "kdf" } diff --git a/backend/src/main/kotlin/com/infendro/account/Application.kt b/backend/src/main/kotlin/com/infendro/account/Application.kt index 8be6978..466b066 100644 --- a/backend/src/main/kotlin/com/infendro/account/Application.kt +++ b/backend/src/main/kotlin/com/infendro/account/Application.kt @@ -9,8 +9,6 @@ fun main( ) = EngineMain.main(args) fun Application.module() { - configureDependencyInjection() - configureDatabase() configureSerialization() diff --git a/backend/src/main/kotlin/com/infendro/account/config/Database.kt b/backend/src/main/kotlin/com/infendro/account/config/Database.kt index 167520a..056c8e5 100644 --- a/backend/src/main/kotlin/com/infendro/account/config/Database.kt +++ b/backend/src/main/kotlin/com/infendro/account/config/Database.kt @@ -1,15 +1,11 @@ package com.infendro.account.config import com.infendro.account.model.Role -import com.infendro.account.model.entity.MigrationTable -import com.infendro.account.model.migration import com.infendro.account.model.repository.AccountRepository import com.infendro.account.util.SecureHasher +import com.infendro.migration.Migration import io.ktor.server.application.* import org.jetbrains.exposed.sql.Database -import org.jetbrains.exposed.sql.SchemaUtils -import org.jetbrains.exposed.sql.transactions.transaction -import org.koin.ktor.ext.inject fun Application.configureDatabase() { val config = environment.config.database @@ -19,19 +15,11 @@ fun Application.configureDatabase() { user = config.username, password = config.password, ) - migrate() -} -fun Application.migrate() { - transaction { - SchemaUtils.create(MigrationTable) - } - - val accounts by inject() - - migration("initial") { - exec( - """ + install(Migration) { + migration("initial") { + exec( + """ CREATE TABLE access ( id BIGSERIAL @@ -68,16 +56,17 @@ fun Application.migrate() { NOT NULL ); """.trimIndent() - ) + ) - accounts.insert { - val salt = SecureHasher.generateSalt() + AccountRepository.insert { + val salt = SecureHasher.generateSalt() - this.username = "infendro" - this.passwordHash = SecureHasher.hash("password", salt) - this.passwordSalt = salt - this.secret = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA====" - this.role = Role.OWNER + this.username = "infendro" + this.passwordHash = SecureHasher.hash("password", salt) + this.passwordSalt = salt + this.secret = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA====" + this.role = Role.OWNER + } } } } diff --git a/backend/src/main/kotlin/com/infendro/account/config/DependencyInjection.kt b/backend/src/main/kotlin/com/infendro/account/config/DependencyInjection.kt deleted file mode 100644 index adf927c..0000000 --- a/backend/src/main/kotlin/com/infendro/account/config/DependencyInjection.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.infendro.account.config - -import com.infendro.account.model.repository.AccessRepository -import com.infendro.account.model.repository.AccountRepository -import com.infendro.account.model.repository.MigrationRepository -import com.infendro.account.model.repository.SessionRepository -import com.infendro.account.service.AccessService -import com.infendro.account.service.AccountService -import com.infendro.account.service.RoleService -import com.infendro.account.service.SessionService -import io.ktor.server.application.* -import org.koin.core.module.dsl.singleOf -import org.koin.dsl.module -import org.koin.ktor.plugin.Koin -import org.koin.logger.slf4jLogger - -fun Application.configureDependencyInjection() { - install(Koin) { - slf4jLogger() - modules(module) - } -} - -private val module = module { - singleOf(::MigrationRepository) - singleOf(::AccessRepository) - singleOf(::AccountRepository) - singleOf(::SessionRepository) - - singleOf(::AccessService) - singleOf(::AccountService) - singleOf(::RoleService) - singleOf(::SessionService) -} diff --git a/backend/src/main/kotlin/com/infendro/account/config/Security.kt b/backend/src/main/kotlin/com/infendro/account/config/Security.kt index 0ebc692..33d9eee 100644 --- a/backend/src/main/kotlin/com/infendro/account/config/Security.kt +++ b/backend/src/main/kotlin/com/infendro/account/config/Security.kt @@ -7,15 +7,12 @@ import com.infendro.account.model.entity.SessionEntity import com.infendro.account.model.entity.SessionTable import com.infendro.account.model.repository.SessionRepository import com.infendro.account.util.Hasher -import io.ktor.server.application.Application -import io.ktor.server.application.install -import io.ktor.server.auth.Authentication -import io.ktor.server.auth.session +import io.ktor.server.application.* +import io.ktor.server.auth.* import io.ktor.server.sessions.* -import kotlin.time.Duration.Companion.days import kotlinx.serialization.Serializable import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.koin.ktor.ext.inject +import kotlin.time.Duration.Companion.days @Serializable data class AuthenticationSession( @@ -46,9 +43,7 @@ fun Application.configureSecurity() { install(Authentication) { session { validate { authenticationSession -> - val sessionRepository by inject() - - val session = sessionRepository + val session = SessionRepository .singleOrNull { SessionTable.tokenHash eq Hasher.hash(authenticationSession.token) } ?: return@validate null diff --git a/backend/src/main/kotlin/com/infendro/account/model/Migration.kt b/backend/src/main/kotlin/com/infendro/account/model/Migration.kt deleted file mode 100644 index 642adfd..0000000 --- a/backend/src/main/kotlin/com/infendro/account/model/Migration.kt +++ /dev/null @@ -1,34 +0,0 @@ -package com.infendro.account.model - -import com.infendro.account.model.entity.MigrationTable -import com.infendro.account.model.repository.MigrationRepository -import io.ktor.server.application.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.Transaction -import org.jetbrains.exposed.sql.transactions.transaction -import org.koin.ktor.ext.inject - -fun Application.migration( - name: String, - block: Transaction.() -> Unit, -) { - val migrations by inject() - - migrations - .singleOrNull { MigrationTable.name eq name } - ?.run { return } - - transaction { - try { - block() - log.info("""Migration "$name" successful""") - } catch (e: Exception) { - log.error("""Migration "$name" failed""") - throw e - } - } - - migrations.insert { - this.name = name - } -} diff --git a/backend/src/main/kotlin/com/infendro/account/model/entity/Migration.kt b/backend/src/main/kotlin/com/infendro/account/model/entity/Migration.kt deleted file mode 100644 index af75afa..0000000 --- a/backend/src/main/kotlin/com/infendro/account/model/entity/Migration.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.infendro.account.model.entity - -import org.jetbrains.exposed.dao.LongEntity -import org.jetbrains.exposed.dao.LongEntityClass -import org.jetbrains.exposed.dao.id.EntityID -import org.jetbrains.exposed.dao.id.LongIdTable - -object MigrationTable : LongIdTable("migration", "id") { - val name = text("name") -} - -class MigrationEntity(id: EntityID) : LongEntity(id) { - companion object : LongEntityClass(MigrationTable) - - var name by MigrationTable.name -} diff --git a/backend/src/main/kotlin/com/infendro/account/model/repository/AccessRepository.kt b/backend/src/main/kotlin/com/infendro/account/model/repository/AccessRepository.kt index 3ce825f..162d568 100644 --- a/backend/src/main/kotlin/com/infendro/account/model/repository/AccessRepository.kt +++ b/backend/src/main/kotlin/com/infendro/account/model/repository/AccessRepository.kt @@ -2,4 +2,4 @@ package com.infendro.account.model.repository import com.infendro.account.model.entity.AccessEntity -class AccessRepository : Repository(AccessEntity) +object AccessRepository : Repository(AccessEntity) diff --git a/backend/src/main/kotlin/com/infendro/account/model/repository/AccountRepository.kt b/backend/src/main/kotlin/com/infendro/account/model/repository/AccountRepository.kt index 9233b73..bc438ec 100644 --- a/backend/src/main/kotlin/com/infendro/account/model/repository/AccountRepository.kt +++ b/backend/src/main/kotlin/com/infendro/account/model/repository/AccountRepository.kt @@ -2,4 +2,4 @@ package com.infendro.account.model.repository import com.infendro.account.model.entity.AccountEntity -class AccountRepository : Repository(AccountEntity) +object AccountRepository : Repository(AccountEntity) diff --git a/backend/src/main/kotlin/com/infendro/account/model/repository/MigrationRepository.kt b/backend/src/main/kotlin/com/infendro/account/model/repository/MigrationRepository.kt deleted file mode 100644 index 07ac6a2..0000000 --- a/backend/src/main/kotlin/com/infendro/account/model/repository/MigrationRepository.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.infendro.account.model.repository - -import com.infendro.account.model.entity.MigrationEntity - -class MigrationRepository : Repository(MigrationEntity) diff --git a/backend/src/main/kotlin/com/infendro/account/model/repository/Repository.kt b/backend/src/main/kotlin/com/infendro/account/model/repository/Repository.kt index 159fb18..ed4d3d5 100644 --- a/backend/src/main/kotlin/com/infendro/account/model/repository/Repository.kt +++ b/backend/src/main/kotlin/com/infendro/account/model/repository/Repository.kt @@ -50,8 +50,8 @@ abstract class Repository( fun exists( where: Op, - ): Boolean { - return all(where).isNotEmpty() + ): Boolean = transaction { + entityClass.find(where).any() } fun exists( diff --git a/backend/src/main/kotlin/com/infendro/account/model/repository/SessionRepository.kt b/backend/src/main/kotlin/com/infendro/account/model/repository/SessionRepository.kt index 7bb2bbc..5ef4668 100644 --- a/backend/src/main/kotlin/com/infendro/account/model/repository/SessionRepository.kt +++ b/backend/src/main/kotlin/com/infendro/account/model/repository/SessionRepository.kt @@ -2,4 +2,4 @@ package com.infendro.account.model.repository import com.infendro.account.model.entity.SessionEntity -class SessionRepository : Repository(SessionEntity) +object SessionRepository : Repository(SessionEntity) diff --git a/backend/src/main/kotlin/com/infendro/account/routing/Access.kt b/backend/src/main/kotlin/com/infendro/account/routing/Access.kt index d7299f7..7b45d9a 100644 --- a/backend/src/main/kotlin/com/infendro/account/routing/Access.kt +++ b/backend/src/main/kotlin/com/infendro/account/routing/Access.kt @@ -3,15 +3,12 @@ package com.infendro.account.routing import com.infendro.account.config.AuthenticationPrincipal import com.infendro.account.service.AccessService import io.ktor.http.HttpStatusCode.Companion.OK -import io.ktor.resources.Resource -import io.ktor.server.auth.authenticate -import io.ktor.server.auth.principal -import io.ktor.server.resources.delete -import io.ktor.server.resources.get +import io.ktor.resources.* +import io.ktor.server.auth.* +import io.ktor.server.resources.* import io.ktor.server.resources.post -import io.ktor.server.response.respond +import io.ktor.server.response.* import io.ktor.server.routing.Routing -import org.koin.ktor.ext.inject @Resource("/access") private class Access { @@ -28,20 +25,18 @@ private class Access { } fun Routing.access() { - val accessService by inject() - authenticate { post { val principal = call.principal()!! - accessService.post(principal) + AccessService.post(principal) .also { call.respond(it) } } get { val principal = call.principal()!! - accessService.getAll(principal) + AccessService.getAll(principal) .also { call.respond(it) } } @@ -49,7 +44,7 @@ fun Routing.access() { val principal = call.principal()!! val id = resource.id - accessService.deleteId(principal, id) + AccessService.deleteId(principal, id) call.respond(OK) } } diff --git a/backend/src/main/kotlin/com/infendro/account/routing/Account.kt b/backend/src/main/kotlin/com/infendro/account/routing/Account.kt index 3603c77..14a7e1a 100644 --- a/backend/src/main/kotlin/com/infendro/account/routing/Account.kt +++ b/backend/src/main/kotlin/com/infendro/account/routing/Account.kt @@ -13,7 +13,6 @@ import io.ktor.server.resources.put import io.ktor.server.response.* import io.ktor.server.routing.Routing import io.ktor.server.sessions.* -import org.koin.ktor.ext.inject @Resource("/account") private class Account { @@ -71,12 +70,10 @@ private class Account { } fun Routing.account() { - val accountService by inject() - post { val request = call.receive() - accountService.post(request) + AccountService.post(request) .also { call.respond(it) } } @@ -84,21 +81,21 @@ fun Routing.account() { get { val principal = call.principal()!! - accountService.getAll(principal) + AccountService.getAll(principal) .also { call.respond(it) } } get { val principal = call.principal()!! - accountService.getCurrent(principal) + AccountService.getCurrent(principal) .also { call.respond(it) } } delete { val principal = call.principal()!! - accountService.deleteCurrent(principal) + AccountService.deleteCurrent(principal) call.respond(OK) } @@ -106,7 +103,7 @@ fun Routing.account() { val principal = call.principal()!! val request = call.receive() - accountService.putCurrentUsername(principal, call.sessions, request) + AccountService.putCurrentUsername(principal, call.sessions, request) call.respond(OK) } @@ -114,7 +111,7 @@ fun Routing.account() { val principal = call.principal()!! val request = call.receive() - accountService.putCurrentPassword(principal, call.sessions, request) + AccountService.putCurrentPassword(principal, call.sessions, request) call.respond(OK) } @@ -122,14 +119,14 @@ fun Routing.account() { val principal = call.principal()!! val request = call.receive() - accountService.postCurrentSecret(principal, call.sessions, request) + AccountService.postCurrentSecret(principal, call.sessions, request) .also { call.respond(it) } } get { val principal = call.principal()!! - accountService.getCurrentSessionAll(principal) + AccountService.getCurrentSessionAll(principal) .also { call.respond(it) } } @@ -137,7 +134,7 @@ fun Routing.account() { val principal = call.principal()!! val id = resource.id - accountService.deleteCurrentSessionId(principal, call.sessions, id) + AccountService.deleteCurrentSessionId(principal, call.sessions, id) call.respond(OK) } @@ -145,7 +142,7 @@ fun Routing.account() { val principal = call.principal()!! val id = resource.id - accountService.deleteId(principal, id) + AccountService.deleteId(principal, id) call.respond(OK) } @@ -154,7 +151,7 @@ fun Routing.account() { val id = resource.parent.id val request = call.receive() - accountService.putIdRole(principal, id, request) + AccountService.putIdRole(principal, id, request) call.respond(OK) } } diff --git a/backend/src/main/kotlin/com/infendro/account/routing/Role.kt b/backend/src/main/kotlin/com/infendro/account/routing/Role.kt index ab24c03..aedc415 100644 --- a/backend/src/main/kotlin/com/infendro/account/routing/Role.kt +++ b/backend/src/main/kotlin/com/infendro/account/routing/Role.kt @@ -1,11 +1,10 @@ package com.infendro.account.routing import com.infendro.account.service.RoleService -import io.ktor.resources.Resource -import io.ktor.server.resources.get -import io.ktor.server.response.respond -import io.ktor.server.routing.Routing -import org.koin.ktor.ext.inject +import io.ktor.resources.* +import io.ktor.server.resources.* +import io.ktor.server.response.* +import io.ktor.server.routing.* @Resource("/role") private class Role { @@ -16,10 +15,8 @@ private class Role { } fun Routing.role() { - val roleService by inject() - get { - roleService.getAll() + RoleService.getAll() .also { call.respond(it) } } } diff --git a/backend/src/main/kotlin/com/infendro/account/routing/Session.kt b/backend/src/main/kotlin/com/infendro/account/routing/Session.kt index 343c935..fbdecaa 100644 --- a/backend/src/main/kotlin/com/infendro/account/routing/Session.kt +++ b/backend/src/main/kotlin/com/infendro/account/routing/Session.kt @@ -4,17 +4,14 @@ import com.infendro.account.config.AuthenticationPrincipal import com.infendro.account.dto.request.PostSessionRequest import com.infendro.account.service.SessionService import io.ktor.http.HttpStatusCode.Companion.OK -import io.ktor.resources.Resource -import io.ktor.server.auth.authenticate -import io.ktor.server.auth.principal -import io.ktor.server.request.receive -import io.ktor.server.resources.delete -import io.ktor.server.resources.get +import io.ktor.resources.* +import io.ktor.server.auth.* +import io.ktor.server.request.* +import io.ktor.server.resources.* import io.ktor.server.resources.post -import io.ktor.server.response.respond +import io.ktor.server.response.* import io.ktor.server.routing.Routing -import io.ktor.server.sessions.sessions -import org.koin.ktor.ext.inject +import io.ktor.server.sessions.* @Resource("/session") private class Session { @@ -36,12 +33,10 @@ private class Session { } fun Routing.session() { - val sessionService by inject() - post { val request = call.receive() - sessionService.post(call.sessions, request) + SessionService.post(call.sessions, request) call.respond(OK) } @@ -49,7 +44,7 @@ fun Routing.session() { get { val principal = call.principal()!! - sessionService.getAll(principal) + SessionService.getAll(principal) .also { call.respond(it) } } @@ -57,21 +52,21 @@ fun Routing.session() { val principal = call.principal()!! val id = resource.id - sessionService.deleteId(principal, id) + SessionService.deleteId(principal, id) call.respond(OK) } get { val principal = call.principal()!! - sessionService.getCurrent(principal) + SessionService.getCurrent(principal) .also { call.respond(it) } } delete { val principal = call.principal()!! - sessionService.deleteCurrent(principal, call.sessions) + SessionService.deleteCurrent(principal, call.sessions) call.respond(OK) } } diff --git a/backend/src/main/kotlin/com/infendro/account/service/AccessService.kt b/backend/src/main/kotlin/com/infendro/account/service/AccessService.kt index d4bd2e2..f6c2e0a 100644 --- a/backend/src/main/kotlin/com/infendro/account/service/AccessService.kt +++ b/backend/src/main/kotlin/com/infendro/account/service/AccessService.kt @@ -13,9 +13,7 @@ import com.infendro.account.util.Hasher import com.infendro.account.util.TokenGenerator import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -class AccessService( - private val accessRepository: AccessRepository, -) { +object AccessService { fun post( principal: AuthenticationPrincipal, ): PostAccessResponse { @@ -23,7 +21,7 @@ class AccessService( throw ForbiddenException() val token = TokenGenerator.generate() - accessRepository.insert { + AccessRepository.insert { this.tokenHash = Hasher.hash(token) } @@ -38,7 +36,7 @@ class AccessService( if (principal.role != OWNER) throw ForbiddenException() - return accessRepository + return AccessRepository .all() .map { it.toResponse() } } @@ -50,10 +48,10 @@ class AccessService( if (principal.role != OWNER) throw ForbiddenException() - val access = accessRepository + val access = AccessRepository .singleOrNull { AccessTable.id eq id } ?: throw NotFoundException() - accessRepository.delete(access) + AccessRepository.delete(access) } } diff --git a/backend/src/main/kotlin/com/infendro/account/service/AccountService.kt b/backend/src/main/kotlin/com/infendro/account/service/AccountService.kt index 36c8d6d..ceabfb5 100644 --- a/backend/src/main/kotlin/com/infendro/account/service/AccountService.kt +++ b/backend/src/main/kotlin/com/infendro/account/service/AccountService.kt @@ -20,26 +20,22 @@ import com.infendro.account.util.SecureHasher import io.ktor.server.sessions.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -class AccountService( - private val accessRepository: AccessRepository, - private val accountRepository: AccountRepository, - private val sessionRepository: SessionRepository, -) { +object AccountService { fun post( request: PostAccountRequest, ): PostAccountResponse { - val access = accessRepository + val access = AccessRepository .singleOrNull { AccessTable.tokenHash eq Hasher.hash(request.access.token) } ?: throw UnauthorizedException() - accountRepository + AccountRepository .singleOrNull { AccountTable.username eq request.username } ?.run { throw ConflictException() } - accessRepository.delete(access) + AccessRepository.delete(access) val secret = OTP.generateSecret() - accountRepository.insert { + AccountRepository.insert { val salt = SecureHasher.generateSalt() this.username = request.username @@ -60,7 +56,7 @@ class AccountService( if (principal.role != OWNER) throw ForbiddenException() - return accountRepository + return AccountRepository .all() .map(AccountEntity::toResponse) } @@ -77,7 +73,7 @@ class AccountService( if (principal.role == OWNER) throw ForbiddenException() - accountRepository.delete(principal.account) + AccountRepository.delete(principal.account) } fun putCurrentUsername( @@ -88,10 +84,10 @@ class AccountService( if (!OTP.verify(principal.account.secret, request.otp)) throw UnauthorizedException() - accountRepository.update(principal.account) { + AccountRepository.update(principal.account) { this.username = request.username } - sessionRepository.delete(principal.account.sessions()) + SessionRepository.delete(principal.account.sessions()) sessions.clear() } @@ -104,13 +100,13 @@ class AccountService( if (!OTP.verify(principal.account.secret, request.otp)) throw UnauthorizedException() - accountRepository.update(principal.account) { + AccountRepository.update(principal.account) { val salt = SecureHasher.generateSalt() this.passwordHash = SecureHasher.hash(request.password, salt) this.passwordSalt = salt } - sessionRepository.delete(principal.account.sessions()) + SessionRepository.delete(principal.account.sessions()) sessions.clear() } @@ -124,10 +120,10 @@ class AccountService( throw UnauthorizedException() val secret = OTP.generateSecret() - accountRepository.update(principal.account) { + AccountRepository.update(principal.account) { this.secret = secret } - sessionRepository.delete(principal.account.sessions()) + SessionRepository.delete(principal.account.sessions()) sessions.clear() @@ -148,14 +144,14 @@ class AccountService( sessions: CurrentSession, id: Long, ) { - val session = sessionRepository + val session = SessionRepository .singleOrNull { SessionTable.id eq id } ?: throw NotFoundException() if (session.account().id != principal.account.id) throw ForbiddenException() - sessionRepository.delete(session) + SessionRepository.delete(session) if (session.id == principal.session.id) sessions.clear() @@ -165,14 +161,14 @@ class AccountService( principal: AuthenticationPrincipal, id: Long, ) { - val account = accountRepository + val account = AccountRepository .singleOrNull { AccountTable.id eq id } ?: throw NotFoundException() if (account.role !in principal.role.children) throw ForbiddenException() - accountRepository.delete(account) + AccountRepository.delete(account) } fun putIdRole( @@ -180,7 +176,7 @@ class AccountService( id: Long, request: PutAccountIdRoleRequest, ) { - val account = accountRepository + val account = AccountRepository .singleOrNull { AccountTable.id eq id } ?: throw NotFoundException() @@ -190,7 +186,7 @@ class AccountService( if (request.role !in principal.role.children) throw ForbiddenException() - accountRepository.update(account) { + AccountRepository.update(account) { role = request.role } } diff --git a/backend/src/main/kotlin/com/infendro/account/service/RoleService.kt b/backend/src/main/kotlin/com/infendro/account/service/RoleService.kt index cda1760..40bf103 100644 --- a/backend/src/main/kotlin/com/infendro/account/service/RoleService.kt +++ b/backend/src/main/kotlin/com/infendro/account/service/RoleService.kt @@ -4,7 +4,7 @@ import com.infendro.account.dto.response.RoleResponse import com.infendro.account.dto.response.toResponse import com.infendro.account.model.Role -class RoleService { +object RoleService { fun getAll(): List { return Role.ALL .map(Role::toResponse) diff --git a/backend/src/main/kotlin/com/infendro/account/service/SessionService.kt b/backend/src/main/kotlin/com/infendro/account/service/SessionService.kt index f612f70..df6538a 100644 --- a/backend/src/main/kotlin/com/infendro/account/service/SessionService.kt +++ b/backend/src/main/kotlin/com/infendro/account/service/SessionService.kt @@ -22,15 +22,12 @@ import io.ktor.server.sessions.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.inList -class SessionService( - private val accountRepository: AccountRepository, - private val sessionRepository: SessionRepository, -) { +object SessionService { fun post( sessions: CurrentSession, request: PostSessionRequest, ) { - val account = accountRepository + val account = AccountRepository .singleOrNull { AccountTable.username eq request.username } ?: throw NotFoundException() @@ -41,7 +38,7 @@ class SessionService( throw UnauthorizedException() val token = TokenGenerator.generate() - sessionRepository.insert { + SessionRepository.insert { this.tokenHash = Hasher.hash(token) this.account = account } @@ -57,7 +54,7 @@ class SessionService( if (principal.role == USER) throw ForbiddenException() - return accountRepository + return AccountRepository .all { AccountTable.role inList principal.role.children } .flatMap { it.sessions() } .map(SessionEntity::toResponse) @@ -70,14 +67,14 @@ class SessionService( if (principal.role == USER) throw ForbiddenException() - val session = sessionRepository + val session = SessionRepository .singleOrNull { SessionTable.id eq id } ?: throw NotFoundException() if (session.account().role !in principal.role.children) throw ForbiddenException() - sessionRepository.delete(session) + SessionRepository.delete(session) } fun getCurrent( @@ -90,7 +87,7 @@ class SessionService( principal: AuthenticationPrincipal, sessions: CurrentSession, ) { - sessionRepository.delete(principal.session) + SessionRepository.delete(principal.session) sessions.clear() } diff --git a/backend/src/main/kotlin/com/infendro/account/util/SecureHasher.kt b/backend/src/main/kotlin/com/infendro/account/util/SecureHasher.kt index 3dc79b5..5086466 100644 --- a/backend/src/main/kotlin/com/infendro/account/util/SecureHasher.kt +++ b/backend/src/main/kotlin/com/infendro/account/util/SecureHasher.kt @@ -6,8 +6,8 @@ import com.infendro.kdf.PBKDF2 import com.infendro.random.PRNG object SecureHasher { - private val kdf = PBKDF2(SHA256) private val random = PRNG.HMAC + private val kdf = PBKDF2(SHA256) fun hash( value: String,