From ea2ff1e77b5b93e7d4bee490293b0f64cb3aaf63 Mon Sep 17 00:00:00 2001 From: Hubert Van De Walle Date: Tue, 21 Apr 2020 20:31:17 +0200 Subject: [PATCH 1/3] Add delete/put /user --- api/src/routing/LoginController.kt | 2 +- api/src/routing/RegisterController.kt | 32 -------------- api/src/routing/UserController.kt | 62 +++++++++++++++++++++++++++ api/src/services/UserService.kt | 17 +++++++- 4 files changed, 78 insertions(+), 35 deletions(-) delete mode 100644 api/src/routing/RegisterController.kt create mode 100644 api/src/routing/UserController.kt diff --git a/api/src/routing/LoginController.kt b/api/src/routing/LoginController.kt index b42fc15..cf626b5 100644 --- a/api/src/routing/LoginController.kt +++ b/api/src/routing/LoginController.kt @@ -18,7 +18,7 @@ fun Routing.login(kodein: Kodein) { data class TokenResponse(val token: String) - route("/login"){ + route("/user/login"){ post { val credential = call.receive() diff --git a/api/src/routing/RegisterController.kt b/api/src/routing/RegisterController.kt deleted file mode 100644 index 16275b6..0000000 --- a/api/src/routing/RegisterController.kt +++ /dev/null @@ -1,32 +0,0 @@ -package be.vandewalleh.routing - -import be.vandewalleh.extensions.respondStatus -import be.vandewalleh.services.UserRegistrationDto -import be.vandewalleh.services.UserService -import io.ktor.application.* -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 -import org.mindrot.jbcrypt.BCrypt - -fun Routing.register(kodein: Kodein) { - val userService by kodein.instance() - - post("/register") { - val user = call.receive() - - if (userService.userExists(user.username, user.email)) - return@post call.respond(HttpStatusCode.Conflict) - - val hashedPassword = BCrypt.hashpw(user.password, BCrypt.gensalt()) - - userService.createUser( - UserRegistrationDto(user.username, user.email, hashedPassword) - ) - - return@post call.respondStatus(HttpStatusCode.Created) - } -} \ No newline at end of file diff --git a/api/src/routing/UserController.kt b/api/src/routing/UserController.kt new file mode 100644 index 0000000..aeef679 --- /dev/null +++ b/api/src/routing/UserController.kt @@ -0,0 +1,62 @@ +package be.vandewalleh.routing + +import be.vandewalleh.extensions.respondStatus +import be.vandewalleh.extensions.userId +import be.vandewalleh.services.UserDto +import be.vandewalleh.services.UserService +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 +import org.mindrot.jbcrypt.BCrypt + +fun Routing.user(kodein: Kodein) { + val userService by kodein.instance() + + route("/user") { + post { + val user = call.receive() + + if (userService.userExists(user.username, user.email)) + return@post call.respond(HttpStatusCode.Conflict) + + val hashedPassword = BCrypt.hashpw(user.password, BCrypt.gensalt()) + + userService.createUser( + UserDto(user.username, user.email, hashedPassword) + ) + + call.respondStatus(HttpStatusCode.Created) + } + + authenticate { + + put { + val user = call.receive() + + if (userService.userExists(user.username, user.email)) + return@put call.respond(HttpStatusCode.Conflict) + + val hashedPassword = BCrypt.hashpw(user.password, BCrypt.gensalt()) + + userService.updateUser( + call.userId(), + UserDto(user.username, user.email, hashedPassword) + ) + + call.respondStatus(HttpStatusCode.OK) + } + + delete { + userService.deleteUser(call.userId()) + call.respondStatus(HttpStatusCode.OK) + } + } + + } + +} \ No newline at end of file diff --git a/api/src/services/UserService.kt b/api/src/services/UserService.kt index 5836e3f..f7020ac 100644 --- a/api/src/services/UserService.kt +++ b/api/src/services/UserService.kt @@ -52,7 +52,7 @@ class UserService(override val kodein: Kodein) : KodeinAware { * create a new user * password should already be hashed */ - fun createUser(user: UserRegistrationDto) { + fun createUser(user: UserDto) { db.useTransaction { val newUser = User { this.username = user.username @@ -65,6 +65,19 @@ class UserService(override val kodein: Kodein) : KodeinAware { } } + fun updateUser(userId: Int, user: UserDto) { + db.useTransaction { + db.update(Users) { + it.username to user.username + it.email to user.email + it.password to user.password + where { + it.id eq userId + } + } + } + } + fun deleteUser(userId: Int) { db.useTransaction { db.delete(Users) { it.id eq userId } @@ -72,4 +85,4 @@ class UserService(override val kodein: Kodein) : KodeinAware { } } -data class UserRegistrationDto(val username: String, val email: String, val password: String) \ No newline at end of file +data class UserDto(val username: String, val email: String, val password: String) \ No newline at end of file From acc6435f615a464cfa6fc3f7b94dfcdfeff7d5e6 Mon Sep 17 00:00:00 2001 From: Hubert Van De Walle Date: Tue, 21 Apr 2020 20:33:28 +0200 Subject: [PATCH 2/3] Update docs --- api-doc/users/index.apib | 4 ++-- public/index.html | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/api-doc/users/index.apib b/api-doc/users/index.apib index e4fd27c..ee601f8 100644 --- a/api-doc/users/index.apib +++ b/api-doc/users/index.apib @@ -14,7 +14,7 @@ # Group Accounts -## Create an account [/register] +## Create an account [/user] ### Register a new user [POST] @@ -33,7 +33,7 @@ + message: User already exists (string) -## Authenticate user [/login] +## Authenticate user [/user/login] Authenticate one user to access protected routing. ### Authenticate a user [POST] diff --git a/public/index.html b/public/index.html index 1e970fc..9e1a7f3 100644 --- a/public/index.html +++ b/public/index.html @@ -1,4 +1,4 @@ -Notes API

Notes API

Accounts

Create an account

POST http://localhost:5000/register
Requestsexample 1
Headers
Content-Type: application/json
Body
{
+Notes API

Notes API

Accounts

Create an account

POST http://localhost:5000/user
Requestsexample 1
Headers
Content-Type: application/json
Body
{
   "username": "babar",
   "email": "michel@seed-it.eu",
   "password": "tortue"
@@ -36,9 +36,8 @@
       "type": "string"
     }
   }
-}

Register a new user
POST/register


Authenticate user

Authenticate - one user to access protected routing.

-
POST http://localhost:5000/login
Requestsexample 1
Headers
Content-Type: application/json
Body
{
+}

Register a new user
POST/user


Authenticate user

Authenticate one user to access protected routing.

+
POST http://localhost:5000/user/login
Requestsexample 1
Headers
Content-Type: application/json
Body
{
   "username": "babar",
   "password": "tortue"
 }
Schema
{
@@ -80,7 +79,7 @@
       "type": "number"
     }
   }
-}

Authenticate a user
POST/login


Notes

Notes

GET http://localhost:5000/notes
Requestsexample 1
Headers
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Responses200
Headers
Content-Type: application/json
Body
[
+}

Authenticate a user
POST/user/login


Notes

Notes

GET http://localhost:5000/notes
Requestsexample 1
Headers
Content-Type: application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
Responses200
Headers
Content-Type: application/json
Body
[
   {
     "title": "Kotlin",
     "tags": [
@@ -218,7 +217,7 @@
       "type": "array"
     }
   }
-}

Get all tags
GET/tags


Generated by aglio on 20 Apr 2020