refactor migration
This commit is contained in:
@@ -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"
|
||||||
|
|||||||
@@ -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",
|
|
||||||
"""
|
|
||||||
CREATE TABLE access
|
|
||||||
(
|
|
||||||
id BIGSERIAL
|
|
||||||
PRIMARY KEY,
|
|
||||||
token_hash TEXT
|
|
||||||
NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE account
|
migration("initial") {
|
||||||
(
|
exec(
|
||||||
id BIGSERIAL
|
"""
|
||||||
PRIMARY KEY,
|
CREATE TABLE access
|
||||||
username TEXT
|
(
|
||||||
UNIQUE
|
id BIGSERIAL
|
||||||
NOT NULL,
|
PRIMARY KEY,
|
||||||
password_hash TEXT
|
token_hash TEXT
|
||||||
NOT NULL,
|
NOT NULL
|
||||||
password_salt TEXT
|
);
|
||||||
NOT NULL,
|
|
||||||
secret TEXT
|
|
||||||
NOT NULL,
|
|
||||||
role TEXT
|
|
||||||
NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE session
|
CREATE TABLE account
|
||||||
(
|
(
|
||||||
id BIGSERIAL
|
id BIGSERIAL
|
||||||
PRIMARY KEY,
|
PRIMARY KEY,
|
||||||
token_hash TEXT
|
username TEXT
|
||||||
NOT NULL,
|
UNIQUE
|
||||||
account_id BIGINT
|
NOT NULL,
|
||||||
REFERENCES account (id) ON DELETE CASCADE
|
password_hash TEXT
|
||||||
NOT NULL
|
NOT NULL,
|
||||||
);
|
password_salt TEXT
|
||||||
""".trimIndent()
|
NOT NULL,
|
||||||
)
|
secret TEXT
|
||||||
migration("owner") {
|
NOT NULL,
|
||||||
val accounts by inject<AccountRepository>()
|
role TEXT
|
||||||
|
NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE session
|
||||||
|
(
|
||||||
|
id BIGSERIAL
|
||||||
|
PRIMARY KEY,
|
||||||
|
token_hash TEXT
|
||||||
|
NOT NULL,
|
||||||
|
account_id BIGINT
|
||||||
|
REFERENCES account (id) ON DELETE CASCADE
|
||||||
|
NOT NULL
|
||||||
|
);
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user