save changed marks
This commit is contained in:
@@ -2,5 +2,5 @@ ktor_version=2.3.3
|
||||
kotlin_version=1.9.0
|
||||
logback_version=1.2.11
|
||||
kotlin.code.style=official
|
||||
exposed_version=0.41.1
|
||||
exposed_version=0.43.0
|
||||
h2_version=2.1.214
|
||||
|
||||
@@ -37,7 +37,7 @@ object MarksDao {
|
||||
}
|
||||
|
||||
suspend fun setMark(ministrantId: Int, gottesdienstId: Int, value: Int): Boolean = dbQuery {
|
||||
Marks.insert {
|
||||
Marks.upsert {
|
||||
it[Marks.mid] = ministrantId
|
||||
it[Marks.gid] = gottesdienstId
|
||||
it[Marks.value] = value
|
||||
|
||||
@@ -27,6 +27,7 @@ data class Ministrant(
|
||||
@Serializable
|
||||
data class SimplifiedMinistrant(
|
||||
val id: Int,
|
||||
val username: String,
|
||||
val firstname: String,
|
||||
val lastname: String
|
||||
)
|
||||
@@ -44,10 +45,10 @@ object Ministranten : Table() {
|
||||
}
|
||||
|
||||
object MinistrantenDao {
|
||||
private fun resultRowToMinistrant(row: ResultRow, showPasswordHash: Boolean = false) = Ministrant (
|
||||
private fun resultRowToMinistrant(row: ResultRow, showPasswordHash: Boolean = false) = Ministrant(
|
||||
row[Ministranten.id],
|
||||
row[Ministranten.username],
|
||||
if(showPasswordHash) row[Ministranten.passwordHash] else "",
|
||||
if (showPasswordHash) row[Ministranten.passwordHash] else "",
|
||||
row[Ministranten.firstname],
|
||||
row[Ministranten.lastname],
|
||||
Date(row[Ministranten.birthday]),
|
||||
@@ -59,8 +60,18 @@ object MinistrantenDao {
|
||||
}
|
||||
|
||||
suspend fun simplifiedMinistranten(): List<SimplifiedMinistrant> = dbQuery {
|
||||
Ministranten.selectAll().map { row ->
|
||||
SimplifiedMinistrant(row[Ministranten.id], row[Ministranten.firstname], row[Ministranten.lastname])
|
||||
Ministranten.slice(
|
||||
Ministranten.id,
|
||||
Ministranten.username,
|
||||
Ministranten.firstname,
|
||||
Ministranten.lastname
|
||||
).selectAll().map { row ->
|
||||
SimplifiedMinistrant(
|
||||
row[Ministranten.id],
|
||||
row[Ministranten.username],
|
||||
row[Ministranten.firstname],
|
||||
row[Ministranten.lastname]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +81,14 @@ object MinistrantenDao {
|
||||
}.firstOrNull()
|
||||
}
|
||||
|
||||
suspend fun createMinistrant(username: String, passwordHash: String, firstname: String, lastname: String, birthday: Date, privileges: List<String>) = dbQuery {
|
||||
suspend fun createMinistrant(
|
||||
username: String,
|
||||
passwordHash: String,
|
||||
firstname: String,
|
||||
lastname: String,
|
||||
birthday: Date,
|
||||
privileges: List<String>
|
||||
) = dbQuery {
|
||||
val statement = Ministranten.insert {
|
||||
it[Ministranten.username] = username
|
||||
it[Ministranten.passwordHash] = ""
|
||||
@@ -95,14 +113,14 @@ object MinistrantenDao {
|
||||
lastname: String? = null,
|
||||
birthday: Date? = null,
|
||||
privileges: List<String>? = null
|
||||
) = dbQuery{
|
||||
Ministranten.update({Ministranten.id eq id}) {
|
||||
if(username != null) it[Ministranten.username] = username
|
||||
if(passwordHash != null) it[Ministranten.passwordHash] = passwordHash
|
||||
if(firstname != null) it[Ministranten.firstname] = firstname
|
||||
if(lastname != null) it[Ministranten.lastname] = lastname
|
||||
if(birthday != null) it[Ministranten.birthday] = birthday.time
|
||||
if(privileges != null) it[Ministranten.privileges] = privileges.joinToString(",")
|
||||
) = dbQuery {
|
||||
Ministranten.update({ Ministranten.id eq id }) {
|
||||
if (username != null) it[Ministranten.username] = username
|
||||
if (passwordHash != null) it[Ministranten.passwordHash] = passwordHash
|
||||
if (firstname != null) it[Ministranten.firstname] = firstname
|
||||
if (lastname != null) it[Ministranten.lastname] = lastname
|
||||
if (birthday != null) it[Ministranten.birthday] = birthday.time
|
||||
if (privileges != null) it[Ministranten.privileges] = privileges.joinToString(",")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import java.util.*
|
||||
|
||||
|
||||
const val SALT_ROUNDS = 10;
|
||||
|
||||
data class JWTEnvironment(
|
||||
val secret: String,
|
||||
val issuer: String,
|
||||
@@ -45,7 +46,7 @@ fun Application.configureSecurity() {
|
||||
|
||||
}
|
||||
|
||||
fun Application.getJWTEnvironment(): JWTEnvironment{
|
||||
fun Application.getJWTEnvironment(): JWTEnvironment {
|
||||
|
||||
val secret = environment.config.property("jwt.secret").getString()
|
||||
val issuer = environment.config.property("jwt.issuer").getString()
|
||||
@@ -58,12 +59,12 @@ fun Payload.mid() = getClaim("id").asInt()
|
||||
|
||||
|
||||
object Security {
|
||||
fun DEFAULT_EXPIRY() = Date(System.currentTimeMillis() + 1000*60*60);
|
||||
fun DEFAULT_EXPIRY() = Date(System.currentTimeMillis() + 1000 * 60 * 60);
|
||||
|
||||
suspend fun authenticateUser(application: Application, username: String, password: String): Ministrant? {
|
||||
if(username == "admin") {
|
||||
if (username == "admin") {
|
||||
val adminPw = application.environment.config.property("admin.password").getString()
|
||||
if(adminPw == password) {
|
||||
if (adminPw == password) {
|
||||
val allMinis = MinistrantenDao.allMinistranten().map { it.username }
|
||||
return Ministrant(
|
||||
0, "admin", "", "admin", "admin", Date(), allMinis
|
||||
@@ -75,7 +76,7 @@ object Security {
|
||||
val ministrant = MinistrantenDao.getMinistrant(username, true)
|
||||
?: return null
|
||||
|
||||
if(!BCrypt.verifyer().verify(password.toCharArray(), ministrant.passwordHash).verified) {
|
||||
if (!BCrypt.verifyer().verify(password.toCharArray(), ministrant.passwordHash).verified) {
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -95,10 +96,11 @@ object Security {
|
||||
}
|
||||
|
||||
fun createToken(jwtEnv: JWTEnvironment, ministrant: Ministrant) = JWT.create()
|
||||
.withAudience(jwtEnv.audience)
|
||||
.withIssuer(jwtEnv.issuer)
|
||||
.withClaim("username", ministrant.username)
|
||||
.withClaim("id", ministrant.id)
|
||||
.withExpiresAt(DEFAULT_EXPIRY())
|
||||
.sign(Algorithm.HMAC256(jwtEnv.secret))
|
||||
.withAudience(jwtEnv.audience)
|
||||
.withIssuer(jwtEnv.issuer)
|
||||
.withClaim("username", ministrant.username)
|
||||
.withClaim("id", ministrant.id)
|
||||
.withClaim("privileges", ministrant.privileges)
|
||||
.withExpiresAt(DEFAULT_EXPIRY())
|
||||
.sign(Algorithm.HMAC256(jwtEnv.secret))
|
||||
}
|
||||
@@ -28,6 +28,7 @@ data class AuthenticationRequest(
|
||||
@Serializable
|
||||
data class AuthenticationResult(
|
||||
val success: Boolean,
|
||||
val token: String? = null,
|
||||
val privileges: List<String>? = null,
|
||||
)
|
||||
|
||||
@@ -61,7 +62,7 @@ fun Route.configureAuthenticationRoutes() {
|
||||
"token=$token; HttpOnly; Expires=$expiry"
|
||||
)
|
||||
|
||||
call.respond(AuthenticationResult(true, ministrant.privileges))
|
||||
call.respond(AuthenticationResult(true, token, ministrant.privileges))
|
||||
}
|
||||
|
||||
authenticate {
|
||||
|
||||
@@ -8,6 +8,7 @@ import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import io.ktor.server.util.*
|
||||
|
||||
|
||||
fun Route.configureMarksView() {
|
||||
route("/marks") {
|
||||
get {
|
||||
@@ -15,22 +16,26 @@ fun Route.configureMarksView() {
|
||||
call.respond(data)
|
||||
}
|
||||
put {
|
||||
val data = call.receive<Mark>()
|
||||
val mark = MarksDao.setMark(
|
||||
data.mid,
|
||||
data.gid,
|
||||
data.value
|
||||
)
|
||||
val changedMarks = call.receive<List<Mark>>()
|
||||
for(changedMark in changedMarks) {
|
||||
val mark = MarksDao.setMark(
|
||||
changedMark.mid,
|
||||
changedMark.gid,
|
||||
changedMark.value
|
||||
)
|
||||
}
|
||||
call.respond(HttpStatusCode.OK)
|
||||
}
|
||||
patch {
|
||||
// TODO: Access only by admin
|
||||
val data = call.receive<Mark>()
|
||||
val changed = MarksDao.setMark(
|
||||
data.mid,
|
||||
data.gid,
|
||||
data.value
|
||||
)
|
||||
val changedMarks = call.receive<List<Mark>>()
|
||||
for(changedMark in changedMarks) {
|
||||
val mark = MarksDao.setMark(
|
||||
changedMark.mid,
|
||||
changedMark.gid,
|
||||
changedMark.value
|
||||
)
|
||||
}
|
||||
call.respond(HttpStatusCode.OK)
|
||||
}
|
||||
delete {
|
||||
|
||||
Reference in New Issue
Block a user