diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..0af84ce --- /dev/null +++ b/.editorconfig @@ -0,0 +1,17 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{kt, kts}] +indent_size = 4 +insert_final_newline = true +max_line_length = 120 +disabled_rules = no-wildcard-imports +kotlin_imports_layout = idea diff --git a/pom.xml b/pom.xml index 218e4ae..bef18c8 100644 --- a/pom.xml +++ b/pom.xml @@ -7,6 +7,7 @@ 14 1.4.10 + official ${java.version} ${java.version} UTF-8 diff --git a/src/main/kotlin/Minimalnotes.kt b/src/main/kotlin/Minimalnotes.kt index 99d8b1b..83685a6 100644 --- a/src/main/kotlin/Minimalnotes.kt +++ b/src/main/kotlin/Minimalnotes.kt @@ -25,7 +25,6 @@ import org.jooq.SQLDialect import org.jooq.impl.DSL import org.koin.core.context.startKoin import org.koin.dsl.bind -import org.koin.dsl.koinApplication import org.koin.dsl.module import org.koin.dsl.onClose import java.util.concurrent.TimeUnit @@ -66,8 +65,8 @@ fun main() { single { getAll().toRouter() } single(createdAtStart = true) { ServerFilters.CatchLensFailure() - .then(get()) - .asServer(ApacheServer(7000)).start() + .then(get()) + .asServer(ApacheServer(7000)).start() } onClose { it?.close() } } diff --git a/src/main/kotlin/extensions/HikariExtension.kt b/src/main/kotlin/extensions/HikariExtension.kt index 8be5b70..7770dbf 100644 --- a/src/main/kotlin/extensions/HikariExtension.kt +++ b/src/main/kotlin/extensions/HikariExtension.kt @@ -4,4 +4,4 @@ import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.HikariDataSource fun hikariDataSource(builder: HikariConfig.() -> Unit): HikariDataSource = - HikariDataSource(HikariConfig().apply(builder)) + HikariDataSource(HikariConfig().apply(builder)) diff --git a/src/main/kotlin/extensions/KoinExtensions.kt b/src/main/kotlin/extensions/KoinExtensions.kt index f22234f..deada47 100644 --- a/src/main/kotlin/extensions/KoinExtensions.kt +++ b/src/main/kotlin/extensions/KoinExtensions.kt @@ -4,7 +4,9 @@ import org.koin.core.Koin import kotlin.concurrent.thread fun Koin.addShutdownHook() { - Runtime.getRuntime().addShutdownHook(thread(start = false) { - close() - }) + Runtime.getRuntime().addShutdownHook( + thread(start = false) { + close() + } + ) } diff --git a/src/main/kotlin/repositories/UserRepository.kt b/src/main/kotlin/repositories/UserRepository.kt index 73403dd..44bc067 100644 --- a/src/main/kotlin/repositories/UserRepository.kt +++ b/src/main/kotlin/repositories/UserRepository.kt @@ -11,14 +11,14 @@ import org.jooq.exception.DataAccessException class UserRepository(private val db: DSLContext, private val passwordHash: PasswordHash) { private val cache = Caffeine.newBuilder() - .maximumSize(10) - .build() + .maximumSize(10) + .build() @Throws(DataAccessException::class) fun create(user: User) { db.insertInto(USERS, USERS.USERNAME, USERS.PASSWORD) - .values(user.username, passwordHash.hash(user.password)) - .execute() + .values(user.username, passwordHash.hash(user.password)) + .execute() } fun find(id: UserId): User? = cache.get(id) { @@ -34,7 +34,7 @@ class UserRepository(private val db: DSLContext, private val passwordHash: Passw } private fun userMapper(record: Record): User = - User(UserId(record[USERS.ID]), record[USERS.USERNAME], record[USERS.PASSWORD]) + User(UserId(record[USERS.ID]), record[USERS.USERNAME], record[USERS.PASSWORD]) fun delete(id: UserId): Boolean { val deleted = db.deleteFrom(USERS).where(USERS.ID.eq(id.value)).execute() == 1 diff --git a/src/main/kotlin/routes/UserRoutes.kt b/src/main/kotlin/routes/UserRoutes.kt index f50b207..2c05b62 100644 --- a/src/main/kotlin/routes/UserRoutes.kt +++ b/src/main/kotlin/routes/UserRoutes.kt @@ -1,11 +1,11 @@ package be.simplenotes.routes -import be.simplenotes.security.SimpleJwt import be.simplenotes.User import be.simplenotes.UserId import be.simplenotes.extensions.notFound import be.simplenotes.extensions.ok import be.simplenotes.repositories.UserRepository +import be.simplenotes.security.SimpleJwt import com.auth0.jwt.exceptions.JWTVerificationException import org.http4k.core.Body import org.http4k.core.Method.* @@ -34,41 +34,41 @@ class UserRoutes(private val userRepository: UserRepository, private val simpleJ private fun userNotFound() = Response.notFound().with(msgLens of Message("not found")) override fun get() = routes( - "/user" bind POST to { - userRepository.create(userLens(it)) - Response.ok().with(msgLens of Message("created")) - }, - "/user/{id}" bind GET to { - val user = userRepository.find(idLens(it)) - user?.let { - Response.ok().with(userLens of user) - } ?: userNotFound() - }, - "/user/{id}" bind DELETE to { - if (userRepository.delete(idLens(it))) - Response.ok().with(msgLens of Message("deleted")) - else userNotFound() - }, - "/login" bind POST to { - val (username, password) = loginLens(it) - userRepository.find(username, password)?.let { user -> - val cookie = Cookie( - "Bearer", simpleJwt.sign(user.id!!) - ) - Response.ok().with(userLens of user.copy(id = null)).cookie(cookie) - } ?: Response.notFound() - }, - "/whoami" bind GET to { - jwtLens(it)?.value - ?.let { token -> - try { - simpleJwt.extract(token) - } catch (e: JWTVerificationException) { - null - } - } - ?.let { id -> Response.ok().with(userLens of userRepository.find(id)!!) } - ?: Response.notFound() - } + "/user" bind POST to { + userRepository.create(userLens(it)) + Response.ok().with(msgLens of Message("created")) + }, + "/user/{id}" bind GET to { + val user = userRepository.find(idLens(it)) + user?.let { + Response.ok().with(userLens of user) + } ?: userNotFound() + }, + "/user/{id}" bind DELETE to { + if (userRepository.delete(idLens(it))) + Response.ok().with(msgLens of Message("deleted")) + else userNotFound() + }, + "/login" bind POST to { + val (username, password) = loginLens(it) + userRepository.find(username, password)?.let { user -> + val cookie = Cookie( + "Bearer", simpleJwt.sign(user.id!!) + ) + Response.ok().with(userLens of user.copy(id = null)).cookie(cookie) + } ?: Response.notFound() + }, + "/whoami" bind GET to { + jwtLens(it)?.value + ?.let { token -> + try { + simpleJwt.extract(token) + } catch (e: JWTVerificationException) { + null + } + } + ?.let { id -> Response.ok().with(userLens of userRepository.find(id)!!) } + ?: Response.notFound() + } ) } diff --git a/src/main/kotlin/security/SimpleJwt.kt b/src/main/kotlin/security/SimpleJwt.kt index dcdcdda..9cfd33b 100644 --- a/src/main/kotlin/security/SimpleJwt.kt +++ b/src/main/kotlin/security/SimpleJwt.kt @@ -16,9 +16,9 @@ class SimpleJwt(secret: String, validity: Long, timeUnit: TimeUnit) { private val verifier: JWTVerifier = JWT.require(algorithm).build() fun sign(id: UserId): String = JWT.create() - .withClaim(idClaim, id.value) - .withExpiresAt(getExpiration()) - .sign(algorithm) + .withClaim(idClaim, id.value) + .withExpiresAt(getExpiration()) + .sign(algorithm) fun extract(token: String): UserId? = try { val decodedJWT = verifier.verify(token)