From 3bce3356e720893eb178e589cca2ada031f31551 Mon Sep 17 00:00:00 2001
From: luevard <99143550+saucepommefrite@users.noreply.github.com>
Date: Mon, 8 Jan 2024 09:34:18 +0100
Subject: [PATCH] :sparkles: Create JWT Usertoken when use register, and
starting bet action
---
Sources/pom.xml | 8 +++++++
Sources/src/main/kotlin/allin/Application.kt | 5 ++--
Sources/src/main/kotlin/allin/model/Bet.kt | 10 +++++++-
.../src/main/kotlin/allin/model/BetAction.kt | 5 ++++
Sources/src/main/kotlin/allin/model/User.kt | 1 +
.../kotlin/allin/routing/BetActionRouter.kt | 13 +++++++++++
.../main/kotlin/allin/routing/BetRouter.kt | 18 +++++++++++----
.../main/kotlin/allin/routing/UserRouter.kt | 23 +++++++++----------
.../kotlin/allin/serializer/DateSerializer.kt | 4 +++-
.../src/main/kotlin/allin/utils/AppConfig.kt | 11 +++++++++
.../main/kotlin/allin/utils/TokenManager.kt | 22 ++++++++++++++----
11 files changed, 96 insertions(+), 24 deletions(-)
create mode 100644 Sources/src/main/kotlin/allin/model/BetAction.kt
create mode 100644 Sources/src/main/kotlin/allin/routing/BetActionRouter.kt
create mode 100644 Sources/src/main/kotlin/allin/utils/AppConfig.kt
diff --git a/Sources/pom.xml b/Sources/pom.xml
index f556046..0d8b30f 100644
--- a/Sources/pom.xml
+++ b/Sources/pom.xml
@@ -220,6 +220,14 @@
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+ 11
+ 11
+
+
\ No newline at end of file
diff --git a/Sources/src/main/kotlin/allin/Application.kt b/Sources/src/main/kotlin/allin/Application.kt
index 70ddcf6..93119eb 100644
--- a/Sources/src/main/kotlin/allin/Application.kt
+++ b/Sources/src/main/kotlin/allin/Application.kt
@@ -1,5 +1,6 @@
package allin
+import allin.model.User
import allin.routing.BasicRouting
import allin.routing.BetRouter
import allin.routing.UserRouter
@@ -21,8 +22,8 @@ fun main() {
}
private fun Application.extracted() {
- val config=HoconApplicationConfig(ConfigFactory.load())
- val tokenManager= TokenManager(config)
+ val config = HoconApplicationConfig(ConfigFactory.load())
+ val tokenManager = TokenManager.getInstance(config)
authentication {
jwt {
verifier(tokenManager.verifyJWTToken())
diff --git a/Sources/src/main/kotlin/allin/model/Bet.kt b/Sources/src/main/kotlin/allin/model/Bet.kt
index e2d6a71..5d4bc13 100644
--- a/Sources/src/main/kotlin/allin/model/Bet.kt
+++ b/Sources/src/main/kotlin/allin/model/Bet.kt
@@ -1,11 +1,19 @@
package allin.model
+import allin.dto.UserDTOWithToken
import allin.serializer.DateSerializer
import kotlinx.serialization.Serializable
import java.util.*
@Serializable
-data class Bet(val id: Int, val theme: String, val sentenceBet: String, @Serializable(DateSerializer::class) val endRegistration: Date, @Serializable(DateSerializer::class) var endBet : Date, var isPrivate : Boolean, var response : MutableList)
+data class Bet(val id: Int, val theme: String, val sentenceBet: String, @Serializable(DateSerializer::class) val endRegistration: Date, @Serializable(DateSerializer::class) var endBet : Date, var isPrivate : Boolean, var response : MutableList, val createdBy : String)
@Serializable
data class UpdatedBetData(val id: Int,@Serializable(DateSerializer::class) val endBet: Date, val isPrivate: Boolean, val response: MutableList)
+
+@Serializable
+data class BetWithoutId(val theme: String, val sentenceBet: String, @Serializable(DateSerializer::class) val endRegistration: Date, @Serializable(DateSerializer::class) var endBet : Date, var isPrivate : Boolean, var response : MutableList, val createdBy : String)
+
+fun convertBetWithoutIdToBet(betWithoutId: BetWithoutId,id : Int, username : String): Bet {
+ return Bet(id,betWithoutId.theme,betWithoutId.sentenceBet,betWithoutId.endRegistration, betWithoutId.endBet, betWithoutId.isPrivate, betWithoutId.response, username)
+}
diff --git a/Sources/src/main/kotlin/allin/model/BetAction.kt b/Sources/src/main/kotlin/allin/model/BetAction.kt
new file mode 100644
index 0000000..f830e2c
--- /dev/null
+++ b/Sources/src/main/kotlin/allin/model/BetAction.kt
@@ -0,0 +1,5 @@
+package allin.model
+
+import allin.dto.UserDTOWithToken
+data class BetAction(val id:Int, val coins: Int, val user: String, val bet: Int)
+data class BetActionCompleted(val id:Int, val coins: Int, val user: UserDTOWithToken, val bet: Bet)
diff --git a/Sources/src/main/kotlin/allin/model/User.kt b/Sources/src/main/kotlin/allin/model/User.kt
index bb99d21..d01dc50 100644
--- a/Sources/src/main/kotlin/allin/model/User.kt
+++ b/Sources/src/main/kotlin/allin/model/User.kt
@@ -1,5 +1,6 @@
package allin.model
+import allin.dto.UserDTO
import kotlinx.serialization.Serializable
@Serializable
diff --git a/Sources/src/main/kotlin/allin/routing/BetActionRouter.kt b/Sources/src/main/kotlin/allin/routing/BetActionRouter.kt
new file mode 100644
index 0000000..aa68a74
--- /dev/null
+++ b/Sources/src/main/kotlin/allin/routing/BetActionRouter.kt
@@ -0,0 +1,13 @@
+package allin.routing
+
+import allin.model.BetAction
+import io.ktor.server.application.*
+import io.ktor.server.request.*
+import io.ktor.server.routing.*
+
+fun Application.BetActionRouter(){
+ routing {
+ route("/BetAction/add"){
+ }
+ }
+}
diff --git a/Sources/src/main/kotlin/allin/routing/BetRouter.kt b/Sources/src/main/kotlin/allin/routing/BetRouter.kt
index f245200..71c3960 100644
--- a/Sources/src/main/kotlin/allin/routing/BetRouter.kt
+++ b/Sources/src/main/kotlin/allin/routing/BetRouter.kt
@@ -3,19 +3,29 @@ import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.routing.*
import allin.model.*
+import allin.utils.AppConfig
import io.ktor.http.*
import io.ktor.server.response.*
val bets = mutableListOf()
+val tokenManagerBet= AppConfig.tokenManager
+
+fun CreateId() : Int{
+ return bets.size
+}
+
fun Application.BetRouter(){
routing{
route("/bets/add"){
post{
- val bet = call.receive()
- val findbet = bets.find { it.id == bet.id }
+ val bet = call.receive()
+ val id = CreateId()
+ val username = tokenManagerBet.getUsernameFromToken(bet.createdBy)
+ val findbet = bets.find { it.id == id }
if(findbet==null){
- bets.add(bet)
- call.respond(HttpStatusCode.Created, bet)
+ val betWithId = convertBetWithoutIdToBet(bet,id,username)
+ bets.add(betWithId)
+ call.respond(HttpStatusCode.Created, betWithId)
}
call.respond(HttpStatusCode.Conflict,"Bet already exist")
}
diff --git a/Sources/src/main/kotlin/allin/routing/UserRouter.kt b/Sources/src/main/kotlin/allin/routing/UserRouter.kt
index 2b6de86..18489be 100644
--- a/Sources/src/main/kotlin/allin/routing/UserRouter.kt
+++ b/Sources/src/main/kotlin/allin/routing/UserRouter.kt
@@ -3,35 +3,34 @@ package allin.routing
import allin.dto.*
import allin.model.CheckUser
import allin.model.User
-import allin.utils.CryptManager
-import com.typesafe.config.ConfigFactory
+import allin.utils.AppConfig
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*
-import io.ktor.server.config.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
-import allin.utils.RegexChecker
-import allin.utils.TokenManager
val users = mutableListOf()
-val tokenManager= TokenManager(HoconApplicationConfig(ConfigFactory.load()))
-val RegexChecker= RegexChecker()
-val CryptManager= CryptManager()
+val RegexCheckerUser= AppConfig.regexChecker
+val CryptManagerUser= AppConfig.cryptManager
+val tokenManagerUser=AppConfig.tokenManager
+
+
fun Application.UserRouter() {
routing {
route("/users/register"){
post {
val TempUser = call.receive()
- if (RegexChecker.isEmailInvalid(TempUser.email)){
+ if (RegexCheckerUser.isEmailInvalid(TempUser.email)){
call.respond(HttpStatusCode.Forbidden,"Input a valid mail !")
}
val user = users.find { it.username == TempUser.username || it.email == TempUser.email }
if(user == null) {
- CryptManager.passwordCrypt(TempUser)
+ CryptManagerUser.passwordCrypt(TempUser)
+ TempUser.token=tokenManagerUser.generateOrReplaceJWTToken(TempUser)
users.add(TempUser)
call.respond(HttpStatusCode.Created, TempUser)
}
@@ -43,8 +42,8 @@ fun Application.UserRouter() {
post {
val checkUser = call.receive()
val user = users.find { it.username == checkUser.login || it.email == checkUser.login }
- if (user != null && CryptManager.passwordDecrypt(user,checkUser.password)) {
- user.token=tokenManager.generateOrReplaceJWTToken(user)
+ if (user != null && CryptManagerUser.passwordDecrypt(user,checkUser.password)) {
+ user.token=tokenManagerUser.generateOrReplaceJWTToken(user)
call.respond(HttpStatusCode.OK, convertUserToUserDTOToken(user))
} else {
call.respond(HttpStatusCode.NotFound,"Login and/or password incorrect.")
diff --git a/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt b/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt
index 6002c28..b5bdc6a 100644
--- a/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt
+++ b/Sources/src/main/kotlin/allin/serializer/DateSerializer.kt
@@ -24,4 +24,6 @@ class DateSerializer : KSerializer {
val dateString = formatter.format(value)
encoder.encodeString(dateString)
}
-}
\ No newline at end of file
+}
+
+//Zoned date time
\ No newline at end of file
diff --git a/Sources/src/main/kotlin/allin/utils/AppConfig.kt b/Sources/src/main/kotlin/allin/utils/AppConfig.kt
new file mode 100644
index 0000000..b0b6b55
--- /dev/null
+++ b/Sources/src/main/kotlin/allin/utils/AppConfig.kt
@@ -0,0 +1,11 @@
+package allin.utils
+
+import com.typesafe.config.ConfigFactory
+import io.ktor.server.config.HoconApplicationConfig
+
+object AppConfig {
+ val config: HoconApplicationConfig = HoconApplicationConfig(ConfigFactory.load())
+ val tokenManager = TokenManager.getInstance(config)
+ val regexChecker= RegexChecker()
+ val cryptManager = CryptManager()
+}
diff --git a/Sources/src/main/kotlin/allin/utils/TokenManager.kt b/Sources/src/main/kotlin/allin/utils/TokenManager.kt
index 5729406..d35ede5 100644
--- a/Sources/src/main/kotlin/allin/utils/TokenManager.kt
+++ b/Sources/src/main/kotlin/allin/utils/TokenManager.kt
@@ -4,15 +4,16 @@ import allin.model.User
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.config.*
import java.util.*
-class TokenManager (val config: HoconApplicationConfig){
+class TokenManager private constructor(val config: HoconApplicationConfig) {
val audience=config.property("audience").getString()
val secret=config.property("secret").getString()
val issuer=config.property("issuer").getString()
- private fun generateJWTToken(user : User): String {
+ fun generateJWTToken(user : User): String {
val expirationDate = System.currentTimeMillis() + 604800000 // une semaine en miliseconde
val token = JWT.create()
@@ -40,12 +41,25 @@ class TokenManager (val config: HoconApplicationConfig){
}
}
- private fun isTokenExpired(token: String): Boolean {
+ fun isTokenExpired(token: String): Boolean {
val expirationTime = JWT.decode(token).expiresAt.time
return System.currentTimeMillis() > expirationTime
}
- private fun getUserToken(user: User): String? {
+ fun getUserToken(user: User): String? {
return user.token
}
+
+ fun getUsernameFromToken(token: String) : String{
+ val decodedJWT: DecodedJWT = JWT.decode(token)
+ return decodedJWT.getClaim("username").asString()
+ }
+ companion object {
+ private var instance: TokenManager? = null
+ fun getInstance(config: HoconApplicationConfig): TokenManager {
+ return instance ?: synchronized(this) {
+ instance ?: TokenManager(config).also { instance = it }
+ }
+ }
+ }
}
\ No newline at end of file