From a79984e781c6966f5c01e65edfa508fa1d1b911d Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Fri, 19 Jan 2024 22:25:18 +0100 Subject: [PATCH 1/5] :sparkles: Add Bet and response entity, refactor and modification UserDTO --- Sources/src/main/kotlin/allin/Application.kt | 5 +++ Sources/src/main/kotlin/allin/dto/UserDTO.kt | 2 +- .../kotlin/allin/entities/ResponseEntity.kt | 42 +++++++++++++++++++ .../main/kotlin/allin/entities/UserEntity.kt | 4 +- Sources/src/main/kotlin/allin/model/Bet.kt | 16 ++----- Sources/src/main/kotlin/allin/model/User.kt | 2 +- .../main/kotlin/allin/routing/BetRouter.kt | 21 ++++++++-- .../kotlin/allin/serializer/DateSerializer.kt | 14 ++++++- .../main/kotlin/allin/utils/TokenManager.kt | 6 +-- 9 files changed, 89 insertions(+), 23 deletions(-) create mode 100644 Sources/src/main/kotlin/allin/entities/ResponseEntity.kt diff --git a/Sources/src/main/kotlin/allin/Application.kt b/Sources/src/main/kotlin/allin/Application.kt index e35782f..826268a 100644 --- a/Sources/src/main/kotlin/allin/Application.kt +++ b/Sources/src/main/kotlin/allin/Application.kt @@ -1,5 +1,8 @@ package allin +import allin.entities.BetEntity +import allin.entities.BetsEntity +import allin.entities.ResponsesEntity import allin.entities.UsersEntity import allin.routing.BasicRouting import allin.routing.BetRouter @@ -52,4 +55,6 @@ private fun Application.extracted() { BetRouter() ParticipationRouter() UsersEntity.createUserTable() + BetsEntity.createBetsTable() + ResponsesEntity.createResponseTable() } diff --git a/Sources/src/main/kotlin/allin/dto/UserDTO.kt b/Sources/src/main/kotlin/allin/dto/UserDTO.kt index a440450..c0bec1d 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 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: Double, var token:String?) diff --git a/Sources/src/main/kotlin/allin/entities/ResponseEntity.kt b/Sources/src/main/kotlin/allin/entities/ResponseEntity.kt new file mode 100644 index 0000000..ca61e88 --- /dev/null +++ b/Sources/src/main/kotlin/allin/entities/ResponseEntity.kt @@ -0,0 +1,42 @@ +package allin.entities + +import allin.database +import allin.utils.Execute +import org.ktorm.dsl.* +import org.ktorm.entity.Entity +import org.ktorm.schema.Table +import org.ktorm.schema.uuid +import org.ktorm.schema.varchar +import java.util.* + + +interface ResponseEntity : Entity { + val betId: UUID + val response: String +} + +object ResponsesEntity : Table("response") { + val id = uuid("id").primaryKey() + val response = varchar("response").primaryKey() + fun createResponseTable(){ + val request="CREATE TABLE IF NOT EXISTS response (id UUID,response VARCHAR(250),CONSTRAINT pk_response_id PRIMARY KEY (id,response));" + database.Execute(request) + } + + fun getResponse(idBet: UUID): MutableList { + return database.from(ResponsesEntity) + .select(response) + .where { id eq idBet } + .map { it[response].toString() } + .toMutableList() + } + + fun addResponse(responses : MutableList, idBet : UUID ) { + responses.forEach {selected -> + database.insert(ResponsesEntity) { + set(it.id, idBet) + set(it.response,selected) + } + } + } +} diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt index 21df0cb..6fbf32a 100644 --- a/Sources/src/main/kotlin/allin/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -27,6 +27,7 @@ object UsersEntity : Table("utilisateur") { fun getUserToUserDTO(): MutableList { return database.from(UsersEntity).select().map { row -> UserDTO( + row[id].toString(), row[username].toString(), row[email].toString(), row[nbCoins]?:0.0, @@ -36,7 +37,7 @@ object UsersEntity : Table("utilisateur") { } fun createUserTable(){ - val request="CREATE TABLE IF not exists utilisateur ( id SERIAL 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))" database.Execute(request) } @@ -48,6 +49,7 @@ object UsersEntity : Table("utilisateur") { .map { row -> Pair( UserDTO( + row[id].toString(), row[username].toString(), row[email].toString(), row[nbCoins] ?: 0.0, diff --git a/Sources/src/main/kotlin/allin/model/Bet.kt b/Sources/src/main/kotlin/allin/model/Bet.kt index 16d7bb1..2e8fec0 100644 --- a/Sources/src/main/kotlin/allin/model/Bet.kt +++ b/Sources/src/main/kotlin/allin/model/Bet.kt @@ -3,17 +3,18 @@ package allin.model import allin.serializer.ZonedDateTimeSerializer import kotlinx.serialization.Serializable import java.time.ZonedDateTime +import java.util.* @Serializable data class Bet( - val id: String, + val id: String = "", val theme: String, val sentenceBet: String, @Serializable(ZonedDateTimeSerializer::class) val endRegistration: ZonedDateTime, @Serializable(ZonedDateTimeSerializer::class) var endBet: ZonedDateTime, var isPrivate: Boolean, var response: MutableList, - val createdBy: String + val createdBy: String = "" ) @Serializable @@ -22,15 +23,4 @@ data class UpdatedBetData( @Serializable(ZonedDateTimeSerializer::class) val endBet: ZonedDateTime, val isPrivate: Boolean, val response: MutableList -) - -@Serializable -data class BetWithoutId( - val theme: String, - val sentenceBet: String, - @Serializable(ZonedDateTimeSerializer::class) val endRegistration: ZonedDateTime, - @Serializable(ZonedDateTimeSerializer::class) var endBet: ZonedDateTime, - var isPrivate: Boolean, - var response: MutableList, - val createdBy: String ) \ No newline at end of file diff --git a/Sources/src/main/kotlin/allin/model/User.kt b/Sources/src/main/kotlin/allin/model/User.kt index ac0122e..70a74be 100644 --- a/Sources/src/main/kotlin/allin/model/User.kt +++ b/Sources/src/main/kotlin/allin/model/User.kt @@ -1,4 +1,4 @@ -package allin.model + package allin.model import kotlinx.serialization.Serializable diff --git a/Sources/src/main/kotlin/allin/routing/BetRouter.kt b/Sources/src/main/kotlin/allin/routing/BetRouter.kt index e54e685..619cb55 100644 --- a/Sources/src/main/kotlin/allin/routing/BetRouter.kt +++ b/Sources/src/main/kotlin/allin/routing/BetRouter.kt @@ -1,5 +1,7 @@ package allin.routing +import allin.entities.BetsEntity.addBetEntity +import allin.entities.BetsEntity.getBets import allin.ext.hasToken import allin.ext.verifyUserFromToken import allin.model.ApiMessage @@ -14,16 +16,19 @@ import io.ktor.server.response.* import io.ktor.server.routing.* import java.util.* -val bets = mutableListOf() +//val bets = mutableListOf() val tokenManagerBet = AppConfig.tokenManager fun Application.BetRouter() { routing { route("/bets/add") { + authenticate { post { + hasToken { principal -> val bet = call.receive() val id = UUID.randomUUID().toString() - val username = tokenManagerBet.getUsernameFromToken(bet.createdBy) + val username = tokenManagerBet.getUsernameFromToken(principal) + val bets = getBets() bets.find { it.id == id }?.let { call.respond(HttpStatusCode.Conflict, ApiMessage.BetAlreadyExist) } ?: run { @@ -37,15 +42,21 @@ fun Application.BetRouter() { bet.response, username ) - bets.add(betWithId) + //bets.add(betWithId) + addBetEntity(betWithId) call.respond(HttpStatusCode.Created, betWithId) } + } + + } + } } route("/bets/gets") { get { // if(bets.size>0) + val bets= getBets() call.respond(HttpStatusCode.Accepted, bets.toList()) // else call.respond(HttpStatusCode.NoContent) } @@ -53,6 +64,7 @@ fun Application.BetRouter() { route("/bets/get/{id}") { get { + val bets= getBets() val id = call.parameters["id"] ?: "" bets.find { it.id == id }?.let { bet -> call.respond(HttpStatusCode.Accepted, bet) @@ -63,6 +75,7 @@ fun Application.BetRouter() { route("/bets/delete") { post { val idbet = call.receive>()["id"] + val bets= getBets() bets.find { it.id == idbet }?.let { findbet -> bets.remove(findbet) call.respond(HttpStatusCode.Accepted, findbet) @@ -72,6 +85,7 @@ fun Application.BetRouter() { route("bets/update") { post { val updatedBetData = call.receive() + val bets= getBets() bets.find { it.id == updatedBetData.id }?.let { findbet -> findbet.endBet = updatedBetData.endBet findbet.isPrivate = updatedBetData.isPrivate @@ -83,6 +97,7 @@ fun Application.BetRouter() { authenticate { get("/bets/current") { + val bets= getBets() hasToken { principal -> verifyUserFromToken(principal) { user, _ -> val bets = participations diff --git a/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt b/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt index dc84760..a1262a6 100644 --- a/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt +++ b/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt @@ -1,14 +1,19 @@ package allin.serializer -import kotlinx.serialization.* +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializer import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import java.sql.Timestamp +import java.time.Instant +import java.time.ZoneId import java.time.ZonedDateTime import java.time.format.DateTimeFormatter + @Serializer(ZonedDateTime::class) object ZonedDateTimeSerializer : KSerializer { private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME @@ -24,4 +29,11 @@ object ZonedDateTimeSerializer : KSerializer { val dateString = decoder.decodeString() return ZonedDateTime.parse(dateString, formatter) } + fun convertTimestampToZonedDateTime(ts: Instant?): ZonedDateTime { + + println(ts.toString()) + + val zoneId = ZoneId.of("Asia/Kolkata") + return ZonedDateTime.ofInstant(ts, zoneId) + } } diff --git a/Sources/src/main/kotlin/allin/utils/TokenManager.kt b/Sources/src/main/kotlin/allin/utils/TokenManager.kt index 86f2073..0034ad8 100644 --- a/Sources/src/main/kotlin/allin/utils/TokenManager.kt +++ b/Sources/src/main/kotlin/allin/utils/TokenManager.kt @@ -6,6 +6,7 @@ import com.auth0.jwt.JWT import com.auth0.jwt.JWTVerifier import com.auth0.jwt.algorithms.Algorithm import com.auth0.jwt.interfaces.DecodedJWT +import io.ktor.server.auth.jwt.* import io.ktor.server.config.* import java.util.* @@ -70,9 +71,8 @@ class TokenManager private constructor(val config: HoconApplicationConfig) { fun getUserToken(user: User): String? = user.token fun getUserToken(user: UserDTO): String? = user.token - fun getUsernameFromToken(token: String): String { - val decodedJWT: DecodedJWT = JWT.decode(token) - return decodedJWT.getClaim("username").asString() + fun getUsernameFromToken(principal: JWTPrincipal): String { + return principal.payload.getClaim("username").asString() } companion object { -- 2.36.3 From ed1f78ba87e9e7f92470ea05d40244a86b345b0e Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Fri, 19 Jan 2024 22:27:31 +0100 Subject: [PATCH 2/5] :sparkles: Add BetEntity file --- .../main/kotlin/allin/entities/BetEntity.kt | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 Sources/src/main/kotlin/allin/entities/BetEntity.kt diff --git a/Sources/src/main/kotlin/allin/entities/BetEntity.kt b/Sources/src/main/kotlin/allin/entities/BetEntity.kt new file mode 100644 index 0000000..c4b7cf3 --- /dev/null +++ b/Sources/src/main/kotlin/allin/entities/BetEntity.kt @@ -0,0 +1,65 @@ +package allin.entities + +import allin.database +import allin.entities.ResponsesEntity.getResponse +import allin.model.Bet +import allin.utils.Execute +import org.ktorm.dsl.* +import org.ktorm.entity.Entity +import org.ktorm.schema.* +import java.time.ZoneId +import java.time.ZonedDateTime +import java.util.UUID.fromString + + +interface BetEntity : Entity { + val theme: String + val sentenceBet: String + val endRegistration: ZonedDateTime + val endBet: ZonedDateTime + val isPrivate: Boolean + val createdBy: String +} + +object BetsEntity : Table("bet") { + val id = uuid("id").primaryKey() + val theme = varchar("theme") + val sentenceBet = varchar("sentencebet") + val endRegistration = timestamp("endregistration") + val endBet = timestamp("endbet") + val isPrivate = boolean("isprivate") + val createdBy = varchar("createdby") + + fun getBets(): MutableList { + return database.from(BetsEntity).select().map { + row -> Bet( + row[id].toString(), + row[theme].toString(), + row[sentenceBet].toString(), + row[endRegistration]!!.atZone(ZoneId.of("Europe/Paris")), + row[endBet]!!.atZone(ZoneId.of("Europe/Paris")), + row[isPrivate]?: false, + getResponse(fromString(row[id].toString())), + row[createdBy].toString() + ) + }.toMutableList() + } + + fun createBetsTable(){ + val request="CREATE TABLE IF not exists bet ( id uuid PRIMARY KEY, theme VARCHAR(255), endregistration timestamp,endbet timestamp,sentencebet varchar(500),isprivate boolean, createdby varchar(250))" + database.Execute(request) + } + + fun addBetEntity(bet : Bet) { + database.insert(BetsEntity) { + set(it.id, fromString(bet.id)) + set(it.endBet,bet.endBet.toInstant()) + set(it.endRegistration,bet.endRegistration.toInstant()) + set(it.sentenceBet,bet.sentenceBet) + set(it.theme, bet.theme) + set(it.isPrivate, bet.isPrivate) + set(it.createdBy, bet.createdBy) + } + ResponsesEntity.addResponse(bet.response,fromString(bet.id)) + } +} \ No newline at end of file -- 2.36.3 From b46a97d4ded69c35c0aec26b0e0ac137dfd0322a Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Fri, 19 Jan 2024 22:32:09 +0100 Subject: [PATCH 3/5] :sparkles: Patch null value in User --- Sources/src/main/kotlin/allin/entities/UserEntity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt index 6fbf32a..6574bb4 100644 --- a/Sources/src/main/kotlin/allin/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -63,6 +63,7 @@ object UsersEntity : Table("utilisateur") { fun addUserEntity(user : User){ database.insert(UsersEntity){ + set(it.id,user.id) set(it.nbCoins,user.nbCoins) set(it.username,user.username) set(it.password,user.password) -- 2.36.3 From d89fc026163bbae4449d071c2e5425ecfc9cd2d3 Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Fri, 19 Jan 2024 22:57:46 +0100 Subject: [PATCH 4/5] :sparkles: Patch User UUID --- .../src/main/kotlin/allin/entities/ResponseEntity.kt | 3 +-- Sources/src/main/kotlin/allin/entities/UserEntity.kt | 11 +++++------ Sources/src/main/kotlin/allin/utils/CryptManager.kt | 1 - 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Sources/src/main/kotlin/allin/entities/ResponseEntity.kt b/Sources/src/main/kotlin/allin/entities/ResponseEntity.kt index ca61e88..c029a5e 100644 --- a/Sources/src/main/kotlin/allin/entities/ResponseEntity.kt +++ b/Sources/src/main/kotlin/allin/entities/ResponseEntity.kt @@ -27,8 +27,7 @@ object ResponsesEntity : Table("response") { return database.from(ResponsesEntity) .select(response) .where { id eq idBet } - .map { it[response].toString() } - .toMutableList() + .map { it[response].toString() }.toMutableList() } fun addResponse(responses : MutableList, idBet : UUID ) { diff --git a/Sources/src/main/kotlin/allin/entities/UserEntity.kt b/Sources/src/main/kotlin/allin/entities/UserEntity.kt index 6574bb4..9a1bcfc 100644 --- a/Sources/src/main/kotlin/allin/entities/UserEntity.kt +++ b/Sources/src/main/kotlin/allin/entities/UserEntity.kt @@ -6,10 +6,9 @@ import allin.model.User import allin.utils.Execute import org.ktorm.dsl.* import org.ktorm.entity.* -import org.ktorm.schema.Table -import org.ktorm.schema.double -import org.ktorm.schema.int -import org.ktorm.schema.varchar +import org.ktorm.schema.* +import java.util.* +import java.util.UUID.fromString interface UserEntity : Entity { val username: String @@ -18,7 +17,7 @@ interface UserEntity : Entity { var nbCoins: Double } object UsersEntity : Table("utilisateur") { - val id = int("id").primaryKey() + val id = uuid("id").primaryKey() val username = varchar("username") val password = varchar("password") val nbCoins = double("coins") @@ -63,7 +62,7 @@ object UsersEntity : Table("utilisateur") { fun addUserEntity(user : User){ database.insert(UsersEntity){ - set(it.id,user.id) + set(it.id,fromString(user.id)) set(it.nbCoins,user.nbCoins) set(it.username,user.username) set(it.password,user.password) diff --git a/Sources/src/main/kotlin/allin/utils/CryptManager.kt b/Sources/src/main/kotlin/allin/utils/CryptManager.kt index 9a34cc9..7f8d7fa 100644 --- a/Sources/src/main/kotlin/allin/utils/CryptManager.kt +++ b/Sources/src/main/kotlin/allin/utils/CryptManager.kt @@ -18,7 +18,6 @@ class CryptManager { return BCrypt.hashpw(password,salt) } fun passwordCrypt(user: User){ - println(salt) user.password=BCrypt.hashpw(user.password,salt) } fun passwordDecrypt(password: String, passwordClear: String): Boolean{ -- 2.36.3 From 2897b34e4c832fdcf79ca5cb92f7476dee2aa0e8 Mon Sep 17 00:00:00 2001 From: luevard <99143550+saucepommefrite@users.noreply.github.com> Date: Tue, 23 Jan 2024 15:54:58 +0100 Subject: [PATCH 5/5] :sparkles: Change Pattern of datetime --- Sources/src/main/kotlin/allin/model/Bet.kt | 1 + .../kotlin/allin/serializer/DateSerializer.kt | 9 +-------- .../kotlin/allin/serializer/UUIDSerializer.kt | 20 +++++++++++++++++++ 3 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 Sources/src/main/kotlin/allin/serializer/UUIDSerializer.kt diff --git a/Sources/src/main/kotlin/allin/model/Bet.kt b/Sources/src/main/kotlin/allin/model/Bet.kt index 2e8fec0..e088e2b 100644 --- a/Sources/src/main/kotlin/allin/model/Bet.kt +++ b/Sources/src/main/kotlin/allin/model/Bet.kt @@ -1,5 +1,6 @@ package allin.model +import allin.serializer.UUIDSerializer import allin.serializer.ZonedDateTimeSerializer import kotlinx.serialization.Serializable import java.time.ZonedDateTime diff --git a/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt b/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt index a1262a6..febe993 100644 --- a/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt +++ b/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt @@ -16,7 +16,7 @@ import java.time.format.DateTimeFormatter @Serializer(ZonedDateTime::class) object ZonedDateTimeSerializer : KSerializer { - private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME + private val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z") override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("ZonedDateTime", PrimitiveKind.STRING) @@ -29,11 +29,4 @@ object ZonedDateTimeSerializer : KSerializer { val dateString = decoder.decodeString() return ZonedDateTime.parse(dateString, formatter) } - fun convertTimestampToZonedDateTime(ts: Instant?): ZonedDateTime { - - println(ts.toString()) - - val zoneId = ZoneId.of("Asia/Kolkata") - return ZonedDateTime.ofInstant(ts, zoneId) - } } diff --git a/Sources/src/main/kotlin/allin/serializer/UUIDSerializer.kt b/Sources/src/main/kotlin/allin/serializer/UUIDSerializer.kt new file mode 100644 index 0000000..4bd17fb --- /dev/null +++ b/Sources/src/main/kotlin/allin/serializer/UUIDSerializer.kt @@ -0,0 +1,20 @@ +package allin.serializer + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import java.util.* + +object UUIDSerializer : KSerializer { + override val descriptor = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING) + + override fun deserialize(decoder: Decoder): UUID { + return UUID.fromString(decoder.decodeString()) + } + + override fun serialize(encoder: Encoder, value: UUID) { + encoder.encodeString(value.toString()) + } +} \ No newline at end of file -- 2.36.3