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