Better seperation

This commit is contained in:
2020-06-25 13:37:49 +02:00
parent 3306b16f91
commit 5b748e1c10
19 changed files with 148 additions and 266 deletions
+75
View File
@@ -0,0 +1,75 @@
package be.vandewalleh.routing
import be.vandewalleh.extensions.authenticatedUserId
import be.vandewalleh.extensions.respondStatus
import be.vandewalleh.features.ValidationException
import be.vandewalleh.services.NoteService
import be.vandewalleh.validation.noteValidator
import be.vandewalleh.validation.receiveValidated
import io.ktor.application.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*
import org.kodein.di.Kodein
import org.kodein.di.generic.instance
import java.util.*
fun Route.noteRoutes(kodein: Kodein) {
val noteService by kodein.instance<NoteService>()
post {
val userId = call.authenticatedUserId()
val note = call.receiveValidated(noteValidator)
val createdNote = noteService.create(userId, note)
call.respond(HttpStatusCode.Created, createdNote)
}
get {
val userId = call.authenticatedUserId()
val notes = noteService.findAll(userId)
call.respond(notes)
}
route("/{uuid}") {
fun ApplicationCall.userIdNoteIdPair(): Pair<Int, UUID> {
val userId = authenticatedUserId()
val uuid = parameters["uuid"]
val noteUuid = try {
UUID.fromString(uuid)
} catch (e: IllegalArgumentException) {
throw ValidationException("`$uuid` is not a valid UUID")
}
return userId to noteUuid
}
get {
val (userId, noteUuid) = call.userIdNoteIdPair()
val response = noteService.find(userId, noteUuid)
?: return@get call.respondStatus(HttpStatusCode.NotFound)
call.respond(response)
}
put {
val (userId, noteUuid) = call.userIdNoteIdPair()
val note = call.receiveValidated(noteValidator)
note.uuid = noteUuid
if (noteService.updateNote(userId, note))
call.respondStatus(HttpStatusCode.OK)
else call.respondStatus(HttpStatusCode.NotFound)
}
delete {
val (userId, noteUuid) = call.userIdNoteIdPair()
if (noteService.delete(userId, noteUuid))
call.respondStatus(HttpStatusCode.OK)
else
call.respondStatus(HttpStatusCode.NotFound)
}
}
}
-17
View File
@@ -1,17 +0,0 @@
package be.vandewalleh.routing
import be.vandewalleh.routing.notes.notes
import be.vandewalleh.routing.notes.tags
import be.vandewalleh.routing.notes.title
import be.vandewalleh.routing.user.auth
import be.vandewalleh.routing.user.user
import io.ktor.routing.*
import org.kodein.di.Kodein
fun Routing.registerRoutes(kodein: Kodein) {
user(kodein)
auth(kodein)
notes(kodein)
title(kodein)
tags(kodein)
}
@@ -1,20 +1,17 @@
package be.vandewalleh.routing.notes
package be.vandewalleh.routing
import be.vandewalleh.extensions.userId
import be.vandewalleh.extensions.authenticatedUserId
import be.vandewalleh.services.NoteService
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.response.*
import io.ktor.routing.*
import org.kodein.di.Kodein
import org.kodein.di.generic.instance
fun Routing.tags(kodein: Kodein) {
fun Route.tagsRoute(kodein: Kodein) {
val noteService by kodein.instance<NoteService>()
authenticate {
get("/tags") {
call.respond(noteService.getTags(call.userId()))
}
get {
call.respond(noteService.getTags(call.authenticatedUserId()))
}
}
@@ -1,11 +1,14 @@
package be.vandewalleh.routing.user
package be.vandewalleh.routing
import be.vandewalleh.auth.SimpleJWT
import be.vandewalleh.auth.UserDbIdPrincipal
import be.vandewalleh.auth.UsernamePasswordCredential
import be.vandewalleh.extensions.respondStatus
import be.vandewalleh.extensions.authenticatedUserId
import be.vandewalleh.features.PasswordHash
import be.vandewalleh.services.UserService
import be.vandewalleh.validation.receiveValidated
import be.vandewalleh.validation.registerValidator
import com.auth0.jwt.exceptions.JWTVerificationException
import io.ktor.application.*
import io.ktor.auth.*
@@ -19,13 +22,25 @@ import org.kodein.di.generic.instance
data class RefreshToken(val refreshToken: String)
data class DualToken(val token: String, val refreshToken: String)
fun Routing.auth(kodein: Kodein) {
fun Route.userRoutes(kodein: Kodein) {
val authSimpleJwt by kodein.instance<SimpleJWT>("auth")
val refreshSimpleJwt by kodein.instance<SimpleJWT>("refresh")
val userService by kodein.instance<UserService>()
val passwordHash by kodein.instance<PasswordHash>()
post("/user/login") {
post {
val user = call.receiveValidated(registerValidator)
if (userService.exists(user.username))
return@post call.respondStatus(HttpStatusCode.Conflict)
val newUser = userService.create(user.username, user.password)
?: return@post call.respondStatus(HttpStatusCode.Conflict)
call.respond(HttpStatusCode.Created, newUser)
}
post("/login") {
val credential = call.receive<UsernamePasswordCredential>()
val user = userService.find(credential.username)
@@ -42,7 +57,7 @@ fun Routing.auth(kodein: Kodein) {
return@post call.respond(response)
}
post("/user/refresh_token") {
post("/refresh_token") {
val token = call.receive<RefreshToken>().refreshToken
val id = try {
@@ -63,12 +78,19 @@ fun Routing.auth(kodein: Kodein) {
}
authenticate {
get("/user/me") {
delete {
val userId = call.authenticatedUserId()
call.respondStatus(
if (userService.delete(userId)) HttpStatusCode.OK
else HttpStatusCode.NotFound
)
}
get("/me") {
val id = call.principal<UserDbIdPrincipal>()!!.id
val info = userService.find(id)
if (info != null) call.respond(mapOf("user" to info))
else call.respondStatus(HttpStatusCode.Unauthorized)
}
}
}
-53
View File
@@ -1,53 +0,0 @@
package be.vandewalleh.routing.notes
import be.vandewalleh.entities.Note
import be.vandewalleh.extensions.noteUuid
import be.vandewalleh.extensions.respondStatus
import be.vandewalleh.extensions.userId
import be.vandewalleh.services.NoteService
import io.ktor.application.call
import io.ktor.auth.authenticate
import io.ktor.http.HttpStatusCode
import io.ktor.request.*
import io.ktor.response.respond
import io.ktor.routing.*
import org.kodein.di.Kodein
import org.kodein.di.generic.instance
fun Routing.title(kodein: Kodein) {
val noteService by kodein.instance<NoteService>()
authenticate {
route("/notes/{noteUuid}") {
get {
val userId = call.userId()
val noteUuid = call.parameters.noteUuid()
val response = noteService.find(userId, noteUuid)
?: return@get call.respondStatus(HttpStatusCode.NotFound)
call.respond(response)
}
put {
val userId = call.userId()
val noteUuid = call.parameters.noteUuid()
val note = call.receive<Note>()
note.uuid = noteUuid
if (noteService.updateNote(userId, note))
call.respondStatus(HttpStatusCode.OK)
else call.respondStatus(HttpStatusCode.NotFound)
}
delete {
val userId = call.userId()
val noteUuid = call.parameters.noteUuid()
if (noteService.delete(userId, noteUuid))
call.respondStatus(HttpStatusCode.OK)
else
call.respondStatus(HttpStatusCode.NotFound)
}
}
}
}
-32
View File
@@ -1,32 +0,0 @@
package be.vandewalleh.routing.notes
import be.vandewalleh.entities.Note
import be.vandewalleh.extensions.userId
import be.vandewalleh.services.NoteService
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.http.*
import io.ktor.request.*
import io.ktor.response.*
import io.ktor.routing.*
import org.kodein.di.Kodein
import org.kodein.di.generic.instance
fun Routing.notes(kodein: Kodein) {
val noteService by kodein.instance<NoteService>()
authenticate {
get("/notes") {
val userId = call.userId()
val notes = noteService.findAll(userId)
call.respond(notes)
}
post("/notes") {
val userId = call.userId()
val note = call.receive<Note>()
val createdNote = noteService.create(userId, note)
call.respond(HttpStatusCode.Created, createdNote)
}
}
}
-43
View File
@@ -1,43 +0,0 @@
package be.vandewalleh.routing.user
import be.vandewalleh.extensions.respondStatus
import be.vandewalleh.extensions.userId
import be.vandewalleh.services.UserService
import be.vandewalleh.validation.receiveValidated
import be.vandewalleh.validation.user.registerValidator
import io.ktor.application.*
import io.ktor.auth.*
import io.ktor.http.*
import io.ktor.response.*
import io.ktor.routing.*
import org.kodein.di.Kodein
import org.kodein.di.generic.instance
fun Routing.user(kodein: Kodein) {
val userService by kodein.instance<UserService>()
route("/user") {
post {
val user = call.receiveValidated(registerValidator)
if (userService.exists(user.username))
return@post call.respondStatus(HttpStatusCode.Conflict)
val newUser = userService.create(user.username, user.password)
?: return@post call.respondStatus(HttpStatusCode.Conflict)
call.respond(HttpStatusCode.Created, newUser)
}
authenticate {
delete {
val status = if (userService.delete(call.userId()))
HttpStatusCode.OK
else
HttpStatusCode.NotFound
call.respondStatus(status)
}
}
}
}