revert cb9edc7492
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
revert Add bet participations and refactoringpull/4/head
parent
cb9edc7492
commit
aecce83607
@ -1,23 +0,0 @@
|
||||
package allin.ext
|
||||
|
||||
import allin.model.ApiMessage
|
||||
import allin.model.User
|
||||
import allin.routing.users
|
||||
import io.ktor.http.*
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.auth.*
|
||||
import io.ktor.server.auth.jwt.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.util.pipeline.*
|
||||
|
||||
suspend fun PipelineContext<*, ApplicationCall>.hasToken(content: suspend (principal: JWTPrincipal) -> Unit) =
|
||||
call.principal<JWTPrincipal>()?.let { content(it) } ?: call.respond(HttpStatusCode.Unauthorized)
|
||||
|
||||
suspend fun PipelineContext<*, ApplicationCall>.verifyUserFromToken(
|
||||
principal: JWTPrincipal,
|
||||
content: suspend (user: User) -> Unit
|
||||
) {
|
||||
val username = principal.payload.getClaim("username").asString()
|
||||
users.find { it.username == username }?.let { content(it) }
|
||||
?: call.respond(HttpStatusCode.NotFound, ApiMessage.TokenUserNotFound)
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package allin.model
|
||||
|
||||
object ApiMessage {
|
||||
const val Welcome = "Welcome on AllIn's API !"
|
||||
const val TokenUserNotFound = "User not found with the valid token !"
|
||||
const val BetNotFound = "Bet not found."
|
||||
const val BetAlreadyExist = "Bet already exists."
|
||||
const val IncorrectLoginPassword = "Login and/or password incorrect."
|
||||
const val UserAlreadyExist = "Mail and/or username already exists."
|
||||
const val InvalidMail = "Invalid mail."
|
||||
const val ParticipationNotFound = "Participation not found."
|
||||
const val NotEnoughCoins = "Not enough coins."
|
||||
}
|
@ -1,37 +1,19 @@
|
||||
package allin.model
|
||||
|
||||
import allin.serializer.ZonedDateTimeSerializer
|
||||
import allin.dto.UserDTOWithToken
|
||||
import allin.serializer.DateSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.time.ZonedDateTime
|
||||
import java.util.*
|
||||
|
||||
@Serializable
|
||||
data class Bet(
|
||||
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<String>,
|
||||
val createdBy: String
|
||||
)
|
||||
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<String>, val createdBy : String)
|
||||
|
||||
@Serializable
|
||||
data class UpdatedBetData(
|
||||
val id: String,
|
||||
@Serializable(ZonedDateTimeSerializer::class) val endBet: ZonedDateTime,
|
||||
val isPrivate: Boolean,
|
||||
val response: MutableList<String>
|
||||
)
|
||||
data class UpdatedBetData(val id: Int,@Serializable(DateSerializer::class) val endBet: Date, val isPrivate: Boolean, val response: MutableList<String>)
|
||||
|
||||
@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<String>,
|
||||
val createdBy: String
|
||||
)
|
||||
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<String>, 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)
|
||||
}
|
||||
|
@ -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)
|
@ -1,19 +0,0 @@
|
||||
package allin.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class Participation(
|
||||
val id: String,
|
||||
val betId: String,
|
||||
val username: String,
|
||||
val answer: String,
|
||||
val stake: Int
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class ParticipationRequest(
|
||||
val betId: String,
|
||||
val answer: String,
|
||||
val stake: Int
|
||||
)
|
@ -1,26 +1,10 @@
|
||||
package allin.model
|
||||
|
||||
import allin.dto.UserDTO
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class User(
|
||||
val id: String,
|
||||
val username: String,
|
||||
val email: String,
|
||||
var password: String,
|
||||
var nbCoins: Int = 1000,
|
||||
var token: String? = null
|
||||
)
|
||||
data class User(val username: String, val email: String, var password: String, var nbCoins: Int = 1000, var token: String? = null)
|
||||
|
||||
@Serializable
|
||||
data class UserRequest(
|
||||
val username: String,
|
||||
val email: String,
|
||||
var password: String
|
||||
)
|
||||
|
||||
@Serializable
|
||||
data class CheckUser(
|
||||
val login: String,
|
||||
val password: String
|
||||
)
|
||||
data class CheckUser(val login: String,val password: String)
|
@ -1,14 +1,13 @@
|
||||
package allin.routing
|
||||
|
||||
import allin.model.ApiMessage
|
||||
import io.ktor.server.application.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
|
||||
fun Application.BasicRouting() {
|
||||
fun Application.BasicRouting(){
|
||||
routing {
|
||||
get("/") {
|
||||
call.respond(ApiMessage.Welcome)
|
||||
call.respond("Bienvenue sur l'API de AlLin!")
|
||||
}
|
||||
}
|
||||
}
|
@ -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"){
|
||||
}
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
package allin.routing
|
||||
|
||||
import allin.ext.hasToken
|
||||
import allin.ext.verifyUserFromToken
|
||||
import allin.model.ApiMessage
|
||||
import allin.model.Participation
|
||||
import allin.model.ParticipationRequest
|
||||
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 participations = mutableListOf<Participation>()
|
||||
|
||||
fun Application.ParticipationRouter() {
|
||||
routing {
|
||||
authenticate {
|
||||
post("/participations/add") {
|
||||
hasToken { principal ->
|
||||
val participation = call.receive<ParticipationRequest>()
|
||||
verifyUserFromToken(principal) { user ->
|
||||
if (user.nbCoins >= participation.stake) {
|
||||
participations.add(
|
||||
Participation(
|
||||
id = UUID.randomUUID().toString(),
|
||||
betId = participation.betId,
|
||||
username = user.username,
|
||||
answer = participation.answer,
|
||||
stake = participation.stake
|
||||
)
|
||||
)
|
||||
call.respond(HttpStatusCode.Created)
|
||||
} else {
|
||||
call.respond(HttpStatusCode.Forbidden, ApiMessage.NotEnoughCoins)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete("/participations/delete") {
|
||||
hasToken { principal ->
|
||||
val participationId = call.receive<String>()
|
||||
participations.find { it.id == participationId }?.let { participation ->
|
||||
verifyUserFromToken(principal) { user ->
|
||||
user.nbCoins += participation.stake
|
||||
participations.remove(participation)
|
||||
call.respond(HttpStatusCode.NoContent)
|
||||
}
|
||||
} ?: call.respond(HttpStatusCode.NotFound, ApiMessage.ParticipationNotFound)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,92 +1,81 @@
|
||||
package allin.routing
|
||||
|
||||
import allin.dto.convertUserToUserDTO
|
||||
import allin.dto.convertUserToUserDTOToken
|
||||
import allin.ext.hasToken
|
||||
import allin.ext.verifyUserFromToken
|
||||
import allin.model.ApiMessage
|
||||
import allin.dto.*
|
||||
import allin.model.CheckUser
|
||||
import allin.model.User
|
||||
import allin.model.UserRequest
|
||||
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.request.*
|
||||
import io.ktor.server.response.*
|
||||
import io.ktor.server.routing.*
|
||||
import java.util.*
|
||||
|
||||
val users = mutableListOf<User>()
|
||||
val RegexCheckerUser = AppConfig.regexChecker
|
||||
val CryptManagerUser = AppConfig.cryptManager
|
||||
val tokenManagerUser = AppConfig.tokenManager
|
||||
const val DEFAULT_COINS = 500
|
||||
val RegexCheckerUser= AppConfig.regexChecker
|
||||
val CryptManagerUser= AppConfig.cryptManager
|
||||
val tokenManagerUser=AppConfig.tokenManager
|
||||
|
||||
|
||||
fun Application.UserRouter() {
|
||||
|
||||
routing {
|
||||
route("/users/register") {
|
||||
route("/users/register"){
|
||||
post {
|
||||
val tempUser = call.receive<UserRequest>()
|
||||
if (RegexCheckerUser.isEmailInvalid(tempUser.email)) {
|
||||
call.respond(HttpStatusCode.Forbidden, ApiMessage.InvalidMail)
|
||||
val TempUser = call.receive<User>()
|
||||
if (RegexCheckerUser.isEmailInvalid(TempUser.email)){
|
||||
call.respond(HttpStatusCode.Forbidden,"Input a valid mail !")
|
||||
}
|
||||
users.find { it.username == tempUser.username || it.email == tempUser.email }?.let { user ->
|
||||
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)
|
||||
users.add(user)
|
||||
call.respond(HttpStatusCode.Created, user)
|
||||
val user = users.find { it.username == TempUser.username || it.email == TempUser.email }
|
||||
if(user == null) {
|
||||
CryptManagerUser.passwordCrypt(TempUser)
|
||||
TempUser.token=tokenManagerUser.generateOrReplaceJWTToken(TempUser)
|
||||
users.add(TempUser)
|
||||
call.respond(HttpStatusCode.Created, TempUser)
|
||||
}
|
||||
call.respond(HttpStatusCode.Conflict,"Mail or/and username already exist")
|
||||
}
|
||||
}
|
||||
|
||||
route("/users/login") {
|
||||
post {
|
||||
val checkUser = call.receive<CheckUser>()
|
||||
users.find { it.username == checkUser.login || it.email == checkUser.login }?.let { user ->
|
||||
if (CryptManagerUser.passwordDecrypt(user, checkUser.password)) {
|
||||
user.token = tokenManagerUser.generateOrReplaceJWTToken(user)
|
||||
call.respond(HttpStatusCode.OK, convertUserToUserDTOToken(user))
|
||||
} else {
|
||||
call.respond(HttpStatusCode.NotFound, ApiMessage.IncorrectLoginPassword)
|
||||
}
|
||||
} ?: call.respond(HttpStatusCode.NotFound, ApiMessage.IncorrectLoginPassword)
|
||||
val user = users.find { it.username == checkUser.login || it.email == checkUser.login }
|
||||
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.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
authenticate {
|
||||
post("/users/delete") {
|
||||
hasToken { principal ->
|
||||
verifyUserFromToken(principal) { user ->
|
||||
val checkUser = call.receive<CheckUser>()
|
||||
if (user.username == checkUser.login && user.password == checkUser.password) {
|
||||
users.remove(user)
|
||||
call.respond(HttpStatusCode.Accepted, convertUserToUserDTO(user))
|
||||
} else {
|
||||
call.respond(HttpStatusCode.NotFound, ApiMessage.IncorrectLoginPassword)
|
||||
}
|
||||
}
|
||||
route("/users/delete") {
|
||||
post {
|
||||
val checkUser = call.receive<CheckUser>()
|
||||
val user = users.find { it.username == checkUser.login || it.email == checkUser.login }
|
||||
if (user != null && user.password == checkUser.password) {
|
||||
users.remove(user)
|
||||
call.respond(HttpStatusCode.Accepted,convertUserToUserDTO(user))
|
||||
} else {
|
||||
call.respond(HttpStatusCode.NotFound,"Login and/or password incorrect.")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
authenticate {
|
||||
get("/users/token") {
|
||||
hasToken { principal ->
|
||||
verifyUserFromToken(principal) { user ->
|
||||
call.respond(HttpStatusCode.OK, convertUserToUserDTO(user))
|
||||
}
|
||||
val principal = call.principal<JWTPrincipal>()
|
||||
val username = principal!!.payload.getClaim("username").asString()
|
||||
val user = users.find { it.username == username }
|
||||
if (user != null) {
|
||||
call.respond(HttpStatusCode.OK,convertUserToUserDTO(user))
|
||||
} else {
|
||||
call.respond(HttpStatusCode.NotFound, "User not found with the valid token !")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,27 @@
|
||||
package allin.serializer
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.*
|
||||
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.time.Instant
|
||||
import java.time.ZoneId
|
||||
import java.time.ZonedDateTime
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
object ZonedDateTimeSerializer : KSerializer<ZonedDateTime> {
|
||||
override val descriptor: SerialDescriptor =
|
||||
PrimitiveSerialDescriptor("ZonedDateTime", PrimitiveKind.LONG)
|
||||
@Serializer(Date::class)
|
||||
class DateSerializer : KSerializer<Date> {
|
||||
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.STRING)
|
||||
|
||||
override fun serialize(encoder: Encoder, value: ZonedDateTime) {
|
||||
encoder.encodeLong(value.toEpochSecond())
|
||||
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.FRANCE)
|
||||
|
||||
override fun deserialize(decoder: Decoder): Date {
|
||||
val dateString = decoder.decodeString()
|
||||
return formatter.parse(dateString)
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): ZonedDateTime {
|
||||
val epoch = decoder.decodeLong()
|
||||
return ZonedDateTime.ofInstant(Instant.ofEpochSecond(epoch), ZoneId.systemDefault())
|
||||
override fun serialize(encoder: Encoder, value: Date) {
|
||||
val dateString = formatter.format(value)
|
||||
encoder.encodeString(dateString)
|
||||
}
|
||||
}
|
Loading…
Reference in new issue