refactor migration

This commit is contained in:
2025-08-17 15:40:26 +02:00
parent dcb490ae31
commit 132a8913aa
3 changed files with 52 additions and 54 deletions

View File

@@ -6,7 +6,7 @@ postgres = "42.7.5"
koin = "4.0.3" koin = "4.0.3"
random = "1.0.0" random = "1.0.0"
otp = "1.1.1" otp = "1.1.1"
kdf = "1.0.1" kdf = "1.0.3"
hash = "1.2.2" hash = "1.2.2"
encoding = "1.1.0" encoding = "1.1.0"
logback = "1.5.18" logback = "1.5.18"

View File

@@ -5,7 +5,6 @@ import com.infendro.account.model.repository.AccountRepository
import com.infendro.account.model.repository.MigrationRepository import com.infendro.account.model.repository.MigrationRepository
import com.infendro.account.util.SecureHasher import com.infendro.account.util.SecureHasher
import io.ktor.server.application.* import io.ktor.server.application.*
import org.intellij.lang.annotations.Language
import org.jetbrains.exposed.sql.SchemaUtils import org.jetbrains.exposed.sql.SchemaUtils
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.Transaction import org.jetbrains.exposed.sql.Transaction
@@ -17,48 +16,48 @@ fun Application.migrate() {
SchemaUtils.create(MigrationTable) SchemaUtils.create(MigrationTable)
} }
migration( val accounts by inject<AccountRepository>()
"initial",
""" migration("initial") {
CREATE TABLE access exec(
( """
id BIGSERIAL CREATE TABLE access
PRIMARY KEY, (
token_hash TEXT id BIGSERIAL
NOT NULL PRIMARY KEY,
); token_hash TEXT
NOT NULL
CREATE TABLE account );
(
id BIGSERIAL CREATE TABLE account
PRIMARY KEY, (
username TEXT id BIGSERIAL
UNIQUE PRIMARY KEY,
NOT NULL, username TEXT
password_hash TEXT UNIQUE
NOT NULL, NOT NULL,
password_salt TEXT password_hash TEXT
NOT NULL, NOT NULL,
secret TEXT password_salt TEXT
NOT NULL, NOT NULL,
role TEXT secret TEXT
NOT NULL NOT NULL,
); role TEXT
NOT NULL
CREATE TABLE session );
(
id BIGSERIAL CREATE TABLE session
PRIMARY KEY, (
token_hash TEXT id BIGSERIAL
NOT NULL, PRIMARY KEY,
account_id BIGINT token_hash TEXT
REFERENCES account (id) ON DELETE CASCADE NOT NULL,
NOT NULL account_id BIGINT
); REFERENCES account (id) ON DELETE CASCADE
""".trimIndent() NOT NULL
) );
migration("owner") { """.trimIndent()
val accounts by inject<AccountRepository>() )
accounts.insert { accounts.insert {
val salt = SecureHasher.generateSalt() val salt = SecureHasher.generateSalt()
@@ -66,7 +65,7 @@ fun Application.migrate() {
this.username = "infendro" this.username = "infendro"
this.passwordHash = SecureHasher.hash("password", salt) this.passwordHash = SecureHasher.hash("password", salt)
this.passwordSalt = salt this.passwordSalt = salt
this.secret = "deadbeef" this.secret = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA===="
this.role = Role.OWNER this.role = Role.OWNER
} }
} }
@@ -83,17 +82,16 @@ private fun Application.migration(
?.run { return } ?.run { return }
transaction { transaction {
block() try {
block()
log.info("""Migration "$name" successful""")
} catch (e: Exception) {
log.error("""Migration "$name" failed""")
throw e
}
} }
migrations.insert { migrations.insert {
this.name = name this.name = name
} }
} }
private fun Application.migration(
name: String,
@Language("sql") sql: String,
) = migration(name) {
exec(sql)
}

View File

@@ -24,6 +24,6 @@ object OTP {
fun generateSecret(): String { fun generateSecret(): String {
val bytes = SecretGenerator.generate(totp.hotp.function) val bytes = SecretGenerator.generate(totp.hotp.function)
return Base32.encode(bytes).toString() return Base32.encode(bytes).decodeToString()
} }
} }