Add KtLint

This commit is contained in:
Hubert Van De Walle 2020-09-29 17:57:20 +02:00
parent c1c05276a2
commit 23eb5ff433
8 changed files with 71 additions and 52 deletions

17
.editorconfig Normal file
View File

@ -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

View File

@ -7,6 +7,7 @@
<properties> <properties>
<java.version>14</java.version> <java.version>14</java.version>
<kotlin.version>1.4.10</kotlin.version> <kotlin.version>1.4.10</kotlin.version>
<kotlin.code.style>official</kotlin.code.style>
<maven.compiler.target>${java.version}</maven.compiler.target> <maven.compiler.target>${java.version}</maven.compiler.target>
<maven.compiler.source>${java.version}</maven.compiler.source> <maven.compiler.source>${java.version}</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@ -25,7 +25,6 @@ import org.jooq.SQLDialect
import org.jooq.impl.DSL import org.jooq.impl.DSL
import org.koin.core.context.startKoin import org.koin.core.context.startKoin
import org.koin.dsl.bind import org.koin.dsl.bind
import org.koin.dsl.koinApplication
import org.koin.dsl.module import org.koin.dsl.module
import org.koin.dsl.onClose import org.koin.dsl.onClose
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
@ -66,8 +65,8 @@ fun main() {
single { getAll<RouteSupplier>().toRouter() } single { getAll<RouteSupplier>().toRouter() }
single(createdAtStart = true) { single(createdAtStart = true) {
ServerFilters.CatchLensFailure() ServerFilters.CatchLensFailure()
.then(get<RoutingHttpHandler>()) .then(get<RoutingHttpHandler>())
.asServer(ApacheServer(7000)).start() .asServer(ApacheServer(7000)).start()
} onClose { it?.close() } } onClose { it?.close() }
} }

View File

@ -4,4 +4,4 @@ import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource import com.zaxxer.hikari.HikariDataSource
fun hikariDataSource(builder: HikariConfig.() -> Unit): HikariDataSource = fun hikariDataSource(builder: HikariConfig.() -> Unit): HikariDataSource =
HikariDataSource(HikariConfig().apply(builder)) HikariDataSource(HikariConfig().apply(builder))

View File

@ -4,7 +4,9 @@ import org.koin.core.Koin
import kotlin.concurrent.thread import kotlin.concurrent.thread
fun Koin.addShutdownHook() { fun Koin.addShutdownHook() {
Runtime.getRuntime().addShutdownHook(thread(start = false) { Runtime.getRuntime().addShutdownHook(
close() thread(start = false) {
}) close()
}
)
} }

View File

@ -11,14 +11,14 @@ import org.jooq.exception.DataAccessException
class UserRepository(private val db: DSLContext, private val passwordHash: PasswordHash) { class UserRepository(private val db: DSLContext, private val passwordHash: PasswordHash) {
private val cache = Caffeine.newBuilder() private val cache = Caffeine.newBuilder()
.maximumSize(10) .maximumSize(10)
.build<UserId, User>() .build<UserId, User>()
@Throws(DataAccessException::class) @Throws(DataAccessException::class)
fun create(user: User) { fun create(user: User) {
db.insertInto(USERS, USERS.USERNAME, USERS.PASSWORD) db.insertInto(USERS, USERS.USERNAME, USERS.PASSWORD)
.values(user.username, passwordHash.hash(user.password)) .values(user.username, passwordHash.hash(user.password))
.execute() .execute()
} }
fun find(id: UserId): User? = cache.get(id) { 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 = 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 { fun delete(id: UserId): Boolean {
val deleted = db.deleteFrom(USERS).where(USERS.ID.eq(id.value)).execute() == 1 val deleted = db.deleteFrom(USERS).where(USERS.ID.eq(id.value)).execute() == 1

View File

@ -1,11 +1,11 @@
package be.simplenotes.routes package be.simplenotes.routes
import be.simplenotes.security.SimpleJwt
import be.simplenotes.User import be.simplenotes.User
import be.simplenotes.UserId import be.simplenotes.UserId
import be.simplenotes.extensions.notFound import be.simplenotes.extensions.notFound
import be.simplenotes.extensions.ok import be.simplenotes.extensions.ok
import be.simplenotes.repositories.UserRepository import be.simplenotes.repositories.UserRepository
import be.simplenotes.security.SimpleJwt
import com.auth0.jwt.exceptions.JWTVerificationException import com.auth0.jwt.exceptions.JWTVerificationException
import org.http4k.core.Body import org.http4k.core.Body
import org.http4k.core.Method.* 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")) private fun userNotFound() = Response.notFound().with(msgLens of Message("not found"))
override fun get() = routes( override fun get() = routes(
"/user" bind POST to { "/user" bind POST to {
userRepository.create(userLens(it)) userRepository.create(userLens(it))
Response.ok().with(msgLens of Message("created")) Response.ok().with(msgLens of Message("created"))
}, },
"/user/{id}" bind GET to { "/user/{id}" bind GET to {
val user = userRepository.find(idLens(it)) val user = userRepository.find(idLens(it))
user?.let { user?.let {
Response.ok().with(userLens of user) Response.ok().with(userLens of user)
} ?: userNotFound() } ?: userNotFound()
}, },
"/user/{id}" bind DELETE to { "/user/{id}" bind DELETE to {
if (userRepository.delete(idLens(it))) if (userRepository.delete(idLens(it)))
Response.ok().with(msgLens of Message("deleted")) Response.ok().with(msgLens of Message("deleted"))
else userNotFound() else userNotFound()
}, },
"/login" bind POST to { "/login" bind POST to {
val (username, password) = loginLens(it) val (username, password) = loginLens(it)
userRepository.find(username, password)?.let { user -> userRepository.find(username, password)?.let { user ->
val cookie = Cookie( val cookie = Cookie(
"Bearer", simpleJwt.sign(user.id!!) "Bearer", simpleJwt.sign(user.id!!)
) )
Response.ok().with(userLens of user.copy(id = null)).cookie(cookie) Response.ok().with(userLens of user.copy(id = null)).cookie(cookie)
} ?: Response.notFound() } ?: Response.notFound()
}, },
"/whoami" bind GET to { "/whoami" bind GET to {
jwtLens(it)?.value jwtLens(it)?.value
?.let { token -> ?.let { token ->
try { try {
simpleJwt.extract(token) simpleJwt.extract(token)
} catch (e: JWTVerificationException) { } catch (e: JWTVerificationException) {
null null
} }
} }
?.let { id -> Response.ok().with(userLens of userRepository.find(id)!!) } ?.let { id -> Response.ok().with(userLens of userRepository.find(id)!!) }
?: Response.notFound() ?: Response.notFound()
} }
) )
} }

View File

@ -16,9 +16,9 @@ class SimpleJwt(secret: String, validity: Long, timeUnit: TimeUnit) {
private val verifier: JWTVerifier = JWT.require(algorithm).build() private val verifier: JWTVerifier = JWT.require(algorithm).build()
fun sign(id: UserId): String = JWT.create() fun sign(id: UserId): String = JWT.create()
.withClaim(idClaim, id.value) .withClaim(idClaim, id.value)
.withExpiresAt(getExpiration()) .withExpiresAt(getExpiration())
.sign(algorithm) .sign(algorithm)
fun extract(token: String): UserId? = try { fun extract(token: String): UserId? = try {
val decodedJWT = verifier.verify(token) val decodedJWT = verifier.verify(token)