From dee7856db23299e8731d825e5ddef08370d343e0 Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Fri, 2 Feb 2024 14:32:21 +0100 Subject: [PATCH 1/9] :sparkles: Add Daily gift route and SQL request --- .../main/kotlin/allin/entities/UserEntity.kt | 19 +++++++++++++++++- Sources/src/main/kotlin/allin/model/User.kt | 12 +++++++---- .../main/kotlin/allin/routing/UserRouter.kt | 15 ++++++++++---- .../main/kotlin/allin/utils/DatabaseUtil.kt | 20 +++++++++++++------ 4 files changed, 51 insertions(+), 15 deletions(-) diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt index 9a1bcfc..72385c4 100644 --- a/Sources/src/main/kotlin/allin/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -4,9 +4,12 @@ import allin.database import allin.dto.UserDTO import allin.model.User import allin.utils.Execute +import io.ktor.util.date.* +import org.h2.util.DateTimeUtils.currentTimestamp import org.ktorm.dsl.* import org.ktorm.entity.* import org.ktorm.schema.* +import java.time.Duration import java.util.* import java.util.UUID.fromString @@ -22,6 +25,8 @@ object UsersEntity : Table("utilisateur") { val password = varchar("password") val nbCoins = double("coins") val email = varchar("email") + val lastGift = varchar("lastgift") + fun getUserToUserDTO(): MutableList { return database.from(UsersEntity).select().map { @@ -36,7 +41,7 @@ object UsersEntity : Table("utilisateur") { } fun createUserTable(){ - val request="CREATE TABLE IF not exists utilisateur ( id uuid PRIMARY KEY, username VARCHAR(255), password VARCHAR(255),coins double precision,email VARCHAR(255))" + val request="CREATE TABLE IF not exists utilisateur ( id uuid PRIMARY KEY, username VARCHAR(255), password VARCHAR(255),coins double precision,email VARCHAR(255), lastgift timestamp)" database.Execute(request) } @@ -75,6 +80,18 @@ object UsersEntity : Table("utilisateur") { } return deletedCount > 0 } + + fun canHaveDailyGift(username: String): Boolean { + val request = "SELECT CASE WHEN lastgift IS NULL THEN TRUE ELSE lastgift < current_timestamp - interval '1 day' END AS can_have_daily_gift, " + + "CASE WHEN lastgift IS NULL THEN null ELSE current_timestamp - lastgift END AS time_remaining " + + "FROM utilisateur WHERE username = '$username';" + val returnCode= database.Execute(request) + + if(returnCode?.next().toString()=="true"){ + return true + } + return false + } } diff --git a/Sources/src/main/kotlin/allin/model/User.kt b/Sources/src/main/kotlin/allin/model/User.kt index 70a74be..9930da7 100644 --- a/Sources/src/main/kotlin/allin/model/User.kt +++ b/Sources/src/main/kotlin/allin/model/User.kt @@ -1,9 +1,9 @@ - package allin.model +package allin.model import kotlinx.serialization.Serializable +import kotlin.random.Random - -@Serializable + @Serializable data class User( val id: String, val username: String, @@ -24,4 +24,8 @@ data class UserRequest( data class CheckUser( val login: String, val password: String -) \ No newline at end of file +) + + fun getDailyGift() : Int{ + return Random.nextInt(10,150) + } diff --git a/Sources/src/main/kotlin/allin/routing/UserRouter.kt b/Sources/src/main/kotlin/allin/routing/UserRouter.kt index ff7f92a..9c64ebf 100644 --- a/Sources/src/main/kotlin/allin/routing/UserRouter.kt +++ b/Sources/src/main/kotlin/allin/routing/UserRouter.kt @@ -1,15 +1,13 @@ package allin.routing import allin.entities.UsersEntity.addUserEntity +import allin.entities.UsersEntity.canHaveDailyGift import allin.entities.UsersEntity.deleteUserByUsername import allin.entities.UsersEntity.getUserByUsernameAndPassword import allin.entities.UsersEntity.getUserToUserDTO import allin.ext.hasToken import allin.ext.verifyUserFromToken -import allin.model.ApiMessage -import allin.model.CheckUser -import allin.model.User -import allin.model.UserRequest +import allin.model.* import allin.utils.AppConfig import io.ktor.http.* import io.ktor.server.application.* @@ -93,6 +91,15 @@ fun Application.UserRouter() { } } } + get("/users/gift") { + hasToken { principal -> + verifyUserFromToken(principal) { userDto, _ -> + if(canHaveDailyGift(userDto.username)) + call.respond(HttpStatusCode.OK, getDailyGift()) + else call.respond(HttpStatusCode.MethodNotAllowed,"Le cadeau ne peut pas être récupéré") + } + } + } } } } diff --git a/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt b/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt index 033afe4..c7697a0 100644 --- a/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt +++ b/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt @@ -2,12 +2,20 @@ package allin.utils import allin.database import org.ktorm.database.Database +import java.sql.ResultSet -fun Database.Execute(request: String){ - if(!request.isNullOrEmpty()) - database.useTransaction { - val connection = it.connection - connection.prepareStatement(request).execute() - connection.commit() +fun Database.Execute(request: String): ResultSet? { + try { + if (!request.isNullOrEmpty()) { + return database.useTransaction { transaction -> + val connection = transaction.connection + val resultSet = connection.prepareStatement(request).executeQuery() + resultSet + } } + } catch (e: Exception){ + println(e.message) + return null + } + return null } \ No newline at end of file From 59f5c73ca1da3151e8de1a4e1d1bfe66b9efa97e Mon Sep 17 00:00:00 2001 From: Lucas EVARD Date: Fri, 2 Feb 2024 14:37:36 +0100 Subject: [PATCH 2/9] =?UTF-8?q?Mise=20=C3=A0=20jour=20de=20'.drone.yml'?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .drone.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.drone.yml b/.drone.yml index 76a7bb8..d86e2e8 100644 --- a/.drone.yml +++ b/.drone.yml @@ -83,6 +83,7 @@ steps: CONTAINERNAME: api COMMAND: create OVERWRITE: true + CODEFIRST_CLIENTDRONE_ENV_DATA_SOURCE: postgres CODEFIRST_CLIENTDRONE_ENV_POSTGRES_DB: from_secret: db_database CODEFIRST_CLIENTDRONE_ENV_POSTGRES_USER: From 33750908159c8856fe542b5c26b715b7c2155ab4 Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:15:14 +0100 Subject: [PATCH 3/9] :sparkles: Add dailygift route --- Sources/src/main/kotlin/allin/entities/UserEntity.kt | 1 + Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt index 72385c4..a620a10 100644 --- a/Sources/src/main/kotlin/allin/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -95,3 +95,4 @@ object UsersEntity : Table("utilisateur") { } + diff --git a/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt b/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt index c7697a0..bd83e54 100644 --- a/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt +++ b/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt @@ -18,4 +18,4 @@ fun Database.Execute(request: String): ResultSet? { return null } return null -} \ No newline at end of file +} From 7dda014bc33c2bdf31a1191dc08b84919af2cd41 Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:21:44 +0100 Subject: [PATCH 4/9] :sparkles: Add modify coins --- Sources/src/main/kotlin/allin/entities/UserEntity.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt index a620a10..8a99436 100644 --- a/Sources/src/main/kotlin/allin/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -45,6 +45,11 @@ object UsersEntity : Table("utilisateur") { database.Execute(request) } + fun modifyCoins(user: String, cost : Int){ + val request = "UPDATE utilisateur SET coins = coins - $cost WHERE username = '$user';" + database.Execute(request) + + } fun getUserByUsernameAndPassword(login: String): Pair { return database.from(UsersEntity) From 1374f48ed2a879130dec1b43ab6ea355e791a180 Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:56:47 +0100 Subject: [PATCH 5/9] :sparkles: Add DailyGift route --- .../main/kotlin/allin/entities/UserEntity.kt | 103 ----------------- .../main/kotlin/allin/routing/UserRouter.kt | 105 ------------------ .../main/kotlin/allin/utils/DatabaseUtil.kt | 21 ---- 3 files changed, 229 deletions(-) delete mode 100644 Sources/src/main/kotlin/allin/entities/UserEntity.kt delete mode 100644 Sources/src/main/kotlin/allin/routing/UserRouter.kt delete mode 100644 Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt deleted file mode 100644 index 8a99436..0000000 --- a/Sources/src/main/kotlin/allin/entities/UserEntity.kt +++ /dev/null @@ -1,103 +0,0 @@ -package allin.entities - -import allin.database -import allin.dto.UserDTO -import allin.model.User -import allin.utils.Execute -import io.ktor.util.date.* -import org.h2.util.DateTimeUtils.currentTimestamp -import org.ktorm.dsl.* -import org.ktorm.entity.* -import org.ktorm.schema.* -import java.time.Duration -import java.util.* -import java.util.UUID.fromString - -interface UserEntity : Entity { - val username: String - var email: String - var password: String - var nbCoins: Double -} -object UsersEntity : Table("utilisateur") { - val id = uuid("id").primaryKey() - val username = varchar("username") - val password = varchar("password") - val nbCoins = double("coins") - val email = varchar("email") - val lastGift = varchar("lastgift") - - - fun getUserToUserDTO(): MutableList { - return database.from(UsersEntity).select().map { - row -> UserDTO( - row[id].toString(), - row[username].toString(), - row[email].toString(), - row[nbCoins]?:0.0, - null - ) - }.toMutableList() - } - - fun createUserTable(){ - val request="CREATE TABLE IF not exists utilisateur ( id uuid PRIMARY KEY, username VARCHAR(255), password VARCHAR(255),coins double precision,email VARCHAR(255), lastgift timestamp)" - database.Execute(request) - } - - fun modifyCoins(user: String, cost : Int){ - val request = "UPDATE utilisateur SET coins = coins - $cost WHERE username = '$user';" - database.Execute(request) - - } - - fun getUserByUsernameAndPassword(login: String): Pair { - return database.from(UsersEntity) - .select() - .where { (username eq login) /*and (password eq passwordParam)*/ } - .map { row -> - Pair( - UserDTO( - row[id].toString(), - row[username].toString(), - row[email].toString(), - row[nbCoins] ?: 0.0, - null - ), - row[password].toString() - ) - } - .firstOrNull() ?: Pair(null, null) - } - - fun addUserEntity(user : User){ - database.insert(UsersEntity){ - set(it.id,fromString(user.id)) - set(it.nbCoins,user.nbCoins) - set(it.username,user.username) - set(it.password,user.password) - set(it.email,user.email) - } - } - fun deleteUserByUsername(username: String): Boolean { - val deletedCount = database.delete(UsersEntity) { - it.username eq username - } - return deletedCount > 0 - } - - fun canHaveDailyGift(username: String): Boolean { - val request = "SELECT CASE WHEN lastgift IS NULL THEN TRUE ELSE lastgift < current_timestamp - interval '1 day' END AS can_have_daily_gift, " + - "CASE WHEN lastgift IS NULL THEN null ELSE current_timestamp - lastgift END AS time_remaining " + - "FROM utilisateur WHERE username = '$username';" - val returnCode= database.Execute(request) - - if(returnCode?.next().toString()=="true"){ - return true - } - return false - } -} - - - diff --git a/Sources/src/main/kotlin/allin/routing/UserRouter.kt b/Sources/src/main/kotlin/allin/routing/UserRouter.kt deleted file mode 100644 index 9c64ebf..0000000 --- a/Sources/src/main/kotlin/allin/routing/UserRouter.kt +++ /dev/null @@ -1,105 +0,0 @@ -package allin.routing - -import allin.entities.UsersEntity.addUserEntity -import allin.entities.UsersEntity.canHaveDailyGift -import allin.entities.UsersEntity.deleteUserByUsername -import allin.entities.UsersEntity.getUserByUsernameAndPassword -import allin.entities.UsersEntity.getUserToUserDTO -import allin.ext.hasToken -import allin.ext.verifyUserFromToken -import allin.model.* -import allin.utils.AppConfig -import io.ktor.http.* -import io.ktor.server.application.* -import io.ktor.server.auth.* -import io.ktor.server.request.* -import io.ktor.server.response.* -import io.ktor.server.routing.* -import java.util.* - -val RegexCheckerUser = AppConfig.regexChecker -val CryptManagerUser = AppConfig.cryptManager -val tokenManagerUser = AppConfig.tokenManager -const val DEFAULT_COINS = 500 -fun Application.UserRouter() { - - routing { - route("/users/register") { - post { - val tempUser = call.receive() - if (RegexCheckerUser.isEmailInvalid(tempUser.email)) { - call.respond(HttpStatusCode.Forbidden, ApiMessage.InvalidMail) - } - val users = getUserToUserDTO() - users.find { it.username == tempUser.username || it.email == tempUser.email }?.let { _ -> - call.respond(HttpStatusCode.Conflict, ApiMessage.UserAlreadyExist) - } ?: run { - val user = User( - id = UUID.randomUUID().toString(), - username = tempUser.username, - email = tempUser.email, - password = tempUser.password, - nbCoins = DEFAULT_COINS, - token = null - ) - CryptManagerUser.passwordCrypt(user) - user.token = tokenManagerUser.generateOrReplaceJWTToken(user) - addUserEntity(user) - call.respond(HttpStatusCode.Created, user) - } - } - } - - route("/users/login") { - post { - val checkUser = call.receive() - val user = getUserByUsernameAndPassword(checkUser.login) - if (CryptManagerUser.passwordDecrypt(user.second ?: "", checkUser.password)) { - user.first?.let { userDtoWithToken -> - userDtoWithToken.token = tokenManagerUser.generateOrReplaceJWTToken(userDtoWithToken) - call.respond(HttpStatusCode.OK, userDtoWithToken) - } ?: call.respond(HttpStatusCode.NotFound, ApiMessage.UserNotFound) - } else { - call.respond(HttpStatusCode.NotFound, ApiMessage.IncorrectLoginPassword) - } - } - } - - authenticate { - post("/users/delete") { - hasToken { principal -> - verifyUserFromToken(principal) { _, password -> - val checkUser = call.receive() - - if (CryptManagerUser.passwordDecrypt(password, checkUser.password)) { - if (!deleteUserByUsername(checkUser.login)) { - call.respond(HttpStatusCode.InternalServerError, "This user can't be delete now !") - } - call.respond(HttpStatusCode.Accepted, password) - } else { - call.respond(HttpStatusCode.NotFound, "Login and/or password incorrect.") - } - - } - } - } - - get("/users/token") { - hasToken { principal -> - verifyUserFromToken(principal) { userDto, _ -> - call.respond(HttpStatusCode.OK, userDto) - } - } - } - get("/users/gift") { - hasToken { principal -> - verifyUserFromToken(principal) { userDto, _ -> - if(canHaveDailyGift(userDto.username)) - call.respond(HttpStatusCode.OK, getDailyGift()) - else call.respond(HttpStatusCode.MethodNotAllowed,"Le cadeau ne peut pas être récupéré") - } - } - } - } - } -} diff --git a/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt b/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt deleted file mode 100644 index bd83e54..0000000 --- a/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt +++ /dev/null @@ -1,21 +0,0 @@ -package allin.utils - -import allin.database -import org.ktorm.database.Database -import java.sql.ResultSet - -fun Database.Execute(request: String): ResultSet? { - try { - if (!request.isNullOrEmpty()) { - return database.useTransaction { transaction -> - val connection = transaction.connection - val resultSet = connection.prepareStatement(request).executeQuery() - resultSet - } - } - } catch (e: Exception){ - println(e.message) - return null - } - return null -} From 7692c6b4635af8858f870996d51aca1defabb139 Mon Sep 17 00:00:00 2001 From: Lucas EVARD Date: Mon, 5 Feb 2024 17:04:34 +0100 Subject: [PATCH 6/9] revert 1374f48ed2a879130dec1b43ab6ea355e791a180 revert :sparkles: Add DailyGift route --- .../main/kotlin/allin/entities/UserEntity.kt | 100 +++++++++++++++++ .../main/kotlin/allin/routing/UserRouter.kt | 105 ++++++++++++++++++ .../main/kotlin/allin/utils/DatabaseUtil.kt | 21 ++++ 3 files changed, 226 insertions(+) create mode 100644 Sources/src/main/kotlin/allin/entities/UserEntity.kt create mode 100644 Sources/src/main/kotlin/allin/routing/UserRouter.kt create mode 100644 Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt new file mode 100644 index 0000000..bbd0321 --- /dev/null +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -0,0 +1,100 @@ +package allin.entities + +import allin.database +import allin.dto.UserDTO +import allin.model.User +import allin.utils.Execute +import io.ktor.util.date.* +import org.h2.util.DateTimeUtils.currentTimestamp +import org.ktorm.dsl.* +import org.ktorm.entity.* +import org.ktorm.schema.* +import java.time.Duration +import java.util.* +import java.util.UUID.fromString + +interface UserEntity : Entity { + val username: String + var email: String + var password: String + var nbCoins: Double +} +object UsersEntity : Table("utilisateur") { + val id = uuid("id").primaryKey() + val username = varchar("username") + val password = varchar("password") + val nbCoins = double("coins") + val email = varchar("email") + val lastGift = varchar("lastgift") + + + fun getUserToUserDTO(): MutableList { + return database.from(UsersEntity).select().map { + row -> UserDTO( + row[id].toString(), + row[username].toString(), + row[email].toString(), + row[nbCoins]?:0.0, + null + ) + }.toMutableList() + } + + fun createUserTable(){ + val request="CREATE TABLE IF not exists utilisateur ( id uuid PRIMARY KEY, username VARCHAR(255), password VARCHAR(255),coins double precision,email VARCHAR(255), lastgift timestamp)" + database.Execute(request) + } + + fun modifyCoins(user: String, cost : Int){ + val request = "UPDATE utilisateur SET coins = coins - $cost WHERE username = '$user';" + database.Execute(request) + + } + + fun getUserByUsernameAndPassword(login: String): Pair { + return database.from(UsersEntity) + .select() + .where { (username eq login) /*and (password eq passwordParam)*/ } + .map { row -> + Pair( + UserDTO( + row[id].toString(), + row[username].toString(), + row[email].toString(), + row[nbCoins] ?: 0.0, + null + ), + row[password].toString() + ) + } + .firstOrNull() ?: Pair(null, null) + } + + fun addUserEntity(user : User){ + database.insert(UsersEntity){ + set(it.id,fromString(user.id)) + set(it.nbCoins,user.nbCoins) + set(it.username,user.username) + set(it.password,user.password) + set(it.email,user.email) + } + } + fun deleteUserByUsername(username: String): Boolean { + val deletedCount = database.delete(UsersEntity) { + it.username eq username + } + return deletedCount > 0 + } + + fun canHaveDailyGift(username: String): Boolean { + val request = "SELECT CASE WHEN lastgift IS NULL THEN TRUE ELSE lastgift < current_timestamp - interval '1 day' END AS can_have_daily_gift, " + + "CASE WHEN lastgift IS NULL THEN null ELSE current_timestamp - lastgift END AS time_remaining " + + "FROM utilisateur WHERE username = '$username';" + val returnCode= database.Execute(request) + + if(returnCode?.next().toString()=="true"){ + return true + } + return false + } +} diff --git a/Sources/src/main/kotlin/allin/routing/UserRouter.kt b/Sources/src/main/kotlin/allin/routing/UserRouter.kt new file mode 100644 index 0000000..9c64ebf --- /dev/null +++ b/Sources/src/main/kotlin/allin/routing/UserRouter.kt @@ -0,0 +1,105 @@ +package allin.routing + +import allin.entities.UsersEntity.addUserEntity +import allin.entities.UsersEntity.canHaveDailyGift +import allin.entities.UsersEntity.deleteUserByUsername +import allin.entities.UsersEntity.getUserByUsernameAndPassword +import allin.entities.UsersEntity.getUserToUserDTO +import allin.ext.hasToken +import allin.ext.verifyUserFromToken +import allin.model.* +import allin.utils.AppConfig +import io.ktor.http.* +import io.ktor.server.application.* +import io.ktor.server.auth.* +import io.ktor.server.request.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import java.util.* + +val RegexCheckerUser = AppConfig.regexChecker +val CryptManagerUser = AppConfig.cryptManager +val tokenManagerUser = AppConfig.tokenManager +const val DEFAULT_COINS = 500 +fun Application.UserRouter() { + + routing { + route("/users/register") { + post { + val tempUser = call.receive() + if (RegexCheckerUser.isEmailInvalid(tempUser.email)) { + call.respond(HttpStatusCode.Forbidden, ApiMessage.InvalidMail) + } + val users = getUserToUserDTO() + users.find { it.username == tempUser.username || it.email == tempUser.email }?.let { _ -> + call.respond(HttpStatusCode.Conflict, ApiMessage.UserAlreadyExist) + } ?: run { + val user = User( + id = UUID.randomUUID().toString(), + username = tempUser.username, + email = tempUser.email, + password = tempUser.password, + nbCoins = DEFAULT_COINS, + token = null + ) + CryptManagerUser.passwordCrypt(user) + user.token = tokenManagerUser.generateOrReplaceJWTToken(user) + addUserEntity(user) + call.respond(HttpStatusCode.Created, user) + } + } + } + + route("/users/login") { + post { + val checkUser = call.receive() + val user = getUserByUsernameAndPassword(checkUser.login) + if (CryptManagerUser.passwordDecrypt(user.second ?: "", checkUser.password)) { + user.first?.let { userDtoWithToken -> + userDtoWithToken.token = tokenManagerUser.generateOrReplaceJWTToken(userDtoWithToken) + call.respond(HttpStatusCode.OK, userDtoWithToken) + } ?: call.respond(HttpStatusCode.NotFound, ApiMessage.UserNotFound) + } else { + call.respond(HttpStatusCode.NotFound, ApiMessage.IncorrectLoginPassword) + } + } + } + + authenticate { + post("/users/delete") { + hasToken { principal -> + verifyUserFromToken(principal) { _, password -> + val checkUser = call.receive() + + if (CryptManagerUser.passwordDecrypt(password, checkUser.password)) { + if (!deleteUserByUsername(checkUser.login)) { + call.respond(HttpStatusCode.InternalServerError, "This user can't be delete now !") + } + call.respond(HttpStatusCode.Accepted, password) + } else { + call.respond(HttpStatusCode.NotFound, "Login and/or password incorrect.") + } + + } + } + } + + get("/users/token") { + hasToken { principal -> + verifyUserFromToken(principal) { userDto, _ -> + call.respond(HttpStatusCode.OK, userDto) + } + } + } + get("/users/gift") { + hasToken { principal -> + verifyUserFromToken(principal) { userDto, _ -> + if(canHaveDailyGift(userDto.username)) + call.respond(HttpStatusCode.OK, getDailyGift()) + else call.respond(HttpStatusCode.MethodNotAllowed,"Le cadeau ne peut pas être récupéré") + } + } + } + } + } +} diff --git a/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt b/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt new file mode 100644 index 0000000..bd83e54 --- /dev/null +++ b/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt @@ -0,0 +1,21 @@ +package allin.utils + +import allin.database +import org.ktorm.database.Database +import java.sql.ResultSet + +fun Database.Execute(request: String): ResultSet? { + try { + if (!request.isNullOrEmpty()) { + return database.useTransaction { transaction -> + val connection = transaction.connection + val resultSet = connection.prepareStatement(request).executeQuery() + resultSet + } + } + } catch (e: Exception){ + println(e.message) + return null + } + return null +} From cbc26a9581ec24e916279caf0e84459172e2143f Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:12:46 +0100 Subject: [PATCH 7/9] :sparkles: Add DailyGift route --- Sources/src/main/kotlin/allin/dto/UserDTO.kt | 2 +- .../main/kotlin/allin/entities/UserEntity.kt | 61 ++++++++++++------- .../main/kotlin/allin/routing/UserRouter.kt | 8 ++- .../main/kotlin/allin/utils/DatabaseUtil.kt | 11 +++- 4 files changed, 56 insertions(+), 26 deletions(-) diff --git a/Sources/src/main/kotlin/allin/dto/UserDTO.kt b/Sources/src/main/kotlin/allin/dto/UserDTO.kt index c0bec1d..2ed2a42 100644 --- a/Sources/src/main/kotlin/allin/dto/UserDTO.kt +++ b/Sources/src/main/kotlin/allin/dto/UserDTO.kt @@ -1,4 +1,4 @@ package allin.dto import kotlinx.serialization.Serializable @Serializable -data class UserDTO(val id: String, val username: String, val email: String, val nbCoins: Double, var token:String?) +data class UserDTO(val id: String, val username: String, val email: String, val nbCoins: Int, var token:String?) diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt index bbd0321..1bb82ea 100644 --- a/Sources/src/main/kotlin/allin/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -4,51 +4,56 @@ import allin.database import allin.dto.UserDTO import allin.model.User import allin.utils.Execute -import io.ktor.util.date.* -import org.h2.util.DateTimeUtils.currentTimestamp +import allin.utils.ExecuteWithResult +import org.ktorm.database.use import org.ktorm.dsl.* import org.ktorm.entity.* import org.ktorm.schema.* -import java.time.Duration -import java.util.* +import java.time.Instant.now import java.util.UUID.fromString interface UserEntity : Entity { val username: String var email: String var password: String - var nbCoins: Double + var nbCoins: Int } object UsersEntity : Table("utilisateur") { val id = uuid("id").primaryKey() val username = varchar("username") val password = varchar("password") - val nbCoins = double("coins") + val nbCoins = int("coins") val email = varchar("email") - val lastGift = varchar("lastgift") + val lastGift = timestamp("lastgift") fun getUserToUserDTO(): MutableList { return database.from(UsersEntity).select().map { - row -> UserDTO( - row[id].toString(), - row[username].toString(), - row[email].toString(), - row[nbCoins]?:0.0, - null - ) + row -> UserDTO( + row[id].toString(), + row[username].toString(), + row[email].toString(), + row[nbCoins]?:0, + null + ) }.toMutableList() } fun createUserTable(){ - val request="CREATE TABLE IF not exists utilisateur ( id uuid PRIMARY KEY, username VARCHAR(255), password VARCHAR(255),coins double precision,email VARCHAR(255), lastgift timestamp)" + val request="CREATE TABLE IF not exists utilisateur ( id uuid PRIMARY KEY, username VARCHAR(255), password VARCHAR(255),coins numeric,email VARCHAR(255), lastgift timestamp)" database.Execute(request) } fun modifyCoins(user: String, cost : Int){ val request = "UPDATE utilisateur SET coins = coins - $cost WHERE username = '$user';" database.Execute(request) + } + fun addCoinByUsername(username: String, coins : Int){ + database.update(UsersEntity){ + set(nbCoins,coins+ nbCoins) + where {it.username eq username} + } } fun getUserByUsernameAndPassword(login: String): Pair { @@ -61,7 +66,7 @@ object UsersEntity : Table("utilisateur") { row[id].toString(), row[username].toString(), row[email].toString(), - row[nbCoins] ?: 0.0, + row[nbCoins] ?: 0, null ), row[password].toString() @@ -77,6 +82,7 @@ object UsersEntity : Table("utilisateur") { set(it.username,user.username) set(it.password,user.password) set(it.email,user.email) + set(it.lastGift,now()) } } fun deleteUserByUsername(username: String): Boolean { @@ -87,14 +93,25 @@ object UsersEntity : Table("utilisateur") { } fun canHaveDailyGift(username: String): Boolean { - val request = "SELECT CASE WHEN lastgift IS NULL THEN TRUE ELSE lastgift < current_timestamp - interval '1 day' END AS can_have_daily_gift, " + - "CASE WHEN lastgift IS NULL THEN null ELSE current_timestamp - lastgift END AS time_remaining " + - "FROM utilisateur WHERE username = '$username';" - val returnCode= database.Execute(request) + val request = "SELECT CASE WHEN NOW() - lastgift > INTERVAL '1 day' THEN true ELSE false END AS is_lastgift_greater_than_1_day FROM utilisateur WHERE username = '$username';" + val resultSet = database.ExecuteWithResult(request) - if(returnCode?.next().toString()=="true"){ - return true + resultSet?.use { + if (resultSet.next()) { + val isDailyGift = resultSet.getBoolean("is_lastgift_greater_than_1_day") + if (isDailyGift) { + database.update(UsersEntity) { + set(lastGift, now()) + where { it.username eq username } + } + } + return isDailyGift + } } return false } + } + + + diff --git a/Sources/src/main/kotlin/allin/routing/UserRouter.kt b/Sources/src/main/kotlin/allin/routing/UserRouter.kt index 9c64ebf..88bd746 100644 --- a/Sources/src/main/kotlin/allin/routing/UserRouter.kt +++ b/Sources/src/main/kotlin/allin/routing/UserRouter.kt @@ -1,5 +1,6 @@ package allin.routing +import allin.entities.UsersEntity.addCoinByUsername import allin.entities.UsersEntity.addUserEntity import allin.entities.UsersEntity.canHaveDailyGift import allin.entities.UsersEntity.deleteUserByUsername @@ -94,8 +95,11 @@ fun Application.UserRouter() { get("/users/gift") { hasToken { principal -> verifyUserFromToken(principal) { userDto, _ -> - if(canHaveDailyGift(userDto.username)) - call.respond(HttpStatusCode.OK, getDailyGift()) + if(canHaveDailyGift(userDto.username)){ + val dailyGift = getDailyGift() + addCoinByUsername(userDto.username,dailyGift) + call.respond(HttpStatusCode.OK,dailyGift) + } else call.respond(HttpStatusCode.MethodNotAllowed,"Le cadeau ne peut pas être récupéré") } } diff --git a/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt b/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt index bd83e54..28fefea 100644 --- a/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt +++ b/Sources/src/main/kotlin/allin/utils/DatabaseUtil.kt @@ -4,7 +4,7 @@ import allin.database import org.ktorm.database.Database import java.sql.ResultSet -fun Database.Execute(request: String): ResultSet? { +fun Database.ExecuteWithResult(request: String): ResultSet? { try { if (!request.isNullOrEmpty()) { return database.useTransaction { transaction -> @@ -19,3 +19,12 @@ fun Database.Execute(request: String): ResultSet? { } return null } + +fun Database.Execute(request: String){ + if(!request.isNullOrEmpty()) + database.useTransaction { + val connection = it.connection + connection.prepareStatement(request).execute() + connection.commit() + } +} \ No newline at end of file From cb7c2ffdbbc53bb2d8d57796231686ed6bb69a71 Mon Sep 17 00:00:00 2001 From: Lucas EVARD Date: Mon, 5 Feb 2024 17:20:35 +0100 Subject: [PATCH 8/9] :sparkles: UsersEntity Merge --- .../main/kotlin/allin/entities/UserEntity.kt | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt index 1bb82ea..b9fd9f2 100644 --- a/Sources/src/main/kotlin/allin/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -10,6 +10,7 @@ import org.ktorm.dsl.* import org.ktorm.entity.* import org.ktorm.schema.* import java.time.Instant.now +import java.util.* import java.util.UUID.fromString interface UserEntity : Entity { @@ -26,16 +27,15 @@ object UsersEntity : Table("utilisateur") { val email = varchar("email") val lastGift = timestamp("lastgift") - fun getUserToUserDTO(): MutableList { return database.from(UsersEntity).select().map { - row -> UserDTO( - row[id].toString(), - row[username].toString(), - row[email].toString(), - row[nbCoins]?:0, - null - ) + row -> UserDTO( + row[id].toString(), + row[username].toString(), + row[email].toString(), + row[nbCoins]?:0, + null + ) }.toMutableList() } @@ -44,17 +44,6 @@ object UsersEntity : Table("utilisateur") { database.Execute(request) } - fun modifyCoins(user: String, cost : Int){ - val request = "UPDATE utilisateur SET coins = coins - $cost WHERE username = '$user';" - database.Execute(request) - } - - fun addCoinByUsername(username: String, coins : Int){ - database.update(UsersEntity){ - set(nbCoins,coins+ nbCoins) - where {it.username eq username} - } - } fun getUserByUsernameAndPassword(login: String): Pair { return database.from(UsersEntity) @@ -114,4 +103,3 @@ object UsersEntity : Table("utilisateur") { } - From 3582fdb0342a145e23ada8877bcf031862e5c2c2 Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Mon, 5 Feb 2024 17:23:01 +0100 Subject: [PATCH 9/9] :sparkles: Add DailyGift route --- Sources/src/main/kotlin/allin/entities/UserEntity.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt index b9fd9f2..632434e 100644 --- a/Sources/src/main/kotlin/allin/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -44,6 +44,11 @@ object UsersEntity : Table("utilisateur") { database.Execute(request) } + fun modifyCoins(user: String, cost : Int){ + val request = "UPDATE utilisateur SET coins = coins - $cost WHERE username = '$user';" + database.Execute(request) + + } fun getUserByUsernameAndPassword(login: String): Pair { return database.from(UsersEntity)