Local Database link
continuous-integration/drone/push Build is passing Details

pull/3/head^2
luevard 1 year ago
parent 73841170cc
commit ff4e36beea

@ -1,15 +1,4 @@
package allin.dto
import allin.model.User
import kotlinx.serialization.Serializable
@Serializable
data class UserDTO(val username: String,val email: String, val nbCoins: Int)
@Serializable
data class UserDTOWithToken(val username: String,val email: String, val nbCoins: Int, val token:String?)
fun convertUserToUserDTO(user: User): UserDTO {
return UserDTO(user.username, user.email, user.nbCoins)
}
fun convertUserToUserDTOToken(user: User): UserDTOWithToken {
return UserDTOWithToken(user.username, user.email, user.nbCoins,user.token)
}
data class UserDTO(val username: String, val email: String, val nbCoins: Double, var token:String?)

@ -1,12 +1,71 @@
package allin.entities
import allin.dto.UserDTO
import allin.model.User
import allin.routing.database
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
object UserEntity : Table<Nothing>("utilisateur") {
interface UserEntity : Entity<UserEntity> {
val username: String
var email: String
var password: String
var nbCoins: Double
}
object UsersEntity : Table<UserEntity>("utilisateur") {
val id = int("id").primaryKey()
val username = varchar("username")
val password = varchar("password")
val nbCoins = double("nbCoins")
}
val email = varchar("email")
fun getUserToUserDTO(): MutableList<UserDTO> {
return database.from(UsersEntity).select().map {
row -> UserDTO(
row[username].toString(),
row[email].toString(),
row[nbCoins]?:0.0,
null
)
}.toMutableList()
}
fun getUserByUsernameAndPassword(login: String): Pair<UserDTO?, String?> {
return database.from(UsersEntity)
.select()
.where { (username eq login) /*and (password eq passwordParam)*/ }
.map { row ->
Pair(
UserDTO(
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.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
}
}

@ -1,19 +1,10 @@
package allin.model
import allin.dto.UserDTOWithToken
import allin.serializer.DateSerializer
import allin.serializer.ZonedDateTimeSerializer
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<String>, val createdBy : String)
@Serializable
data class UpdatedBetData(val id: Int,@Serializable(DateSerializer::class) val endBet: Date, val isPrivate: Boolean, val response: MutableList<String>)
data class Bet(val id: Int, val theme: String, val sentenceBet: String, @Serializable(ZonedDateTimeSerializer::class) val endRegistration: Date, @Serializable(ZonedDateTimeSerializer::class) var endBet : Date, var isPrivate : Boolean, var response : MutableList<String>, var createdBy : String)
@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<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)
}
data class UpdatedBetData(val id: Int,@Serializable(ZonedDateTimeSerializer::class) val endBet: Date, val isPrivate: Boolean, val response: MutableList<String>)

@ -1,5 +1,5 @@
package allin.model
import allin.dto.UserDTOWithToken
import allin.dto.UserDTO
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)
data class BetActionCompleted(val id:Int, val coins: Int, val user: UserDTO, val bet: Bet)

@ -1,10 +1,8 @@
package allin.model
import allin.dto.UserDTO
import allin.routing.users
import kotlinx.serialization.Serializable
@Serializable
data class User(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: Double = 1000.0, var token: String? = null)
@Serializable
data class CheckUser(val login: String,val password: String)

@ -5,7 +5,10 @@ import io.ktor.server.routing.*
import allin.model.*
import allin.utils.AppConfig
import io.ktor.http.*
import io.ktor.server.auth.*
import io.ktor.server.auth.jwt.*
import io.ktor.server.response.*
import java.time.ZonedDateTime
val bets = mutableListOf<Bet>()
val tokenManagerBet= AppConfig.tokenManager
@ -16,20 +19,22 @@ fun CreateId() : Int{
fun Application.BetRouter(){
routing{
authenticate {
route("/bets/add"){
post{
val bet = call.receive<BetWithoutId>()
val bet = call.receive<Bet>()
val token= call.principal<JWTPrincipal>()
val id = CreateId()
val username = tokenManagerBet.getUsernameFromToken(bet.createdBy)
bet.createdBy = tokenManagerBet.getUsernameFromToken(token.toString())
val findbet = bets.find { it.id == id }
if(findbet==null){
val betWithId = convertBetWithoutIdToBet(bet,id,username)
bets.add(betWithId)
call.respond(HttpStatusCode.Created, betWithId)
bets.add(bet)
call.respond(HttpStatusCode.Created, bet)
}
call.respond(HttpStatusCode.Conflict,"Bet already exist")
}
}
}
route("/bets/gets"){
get{
// if(bets.size>0)

@ -1,8 +1,10 @@
package allin.routing
import allin.dto.*
import allin.model.CheckUser
import allin.model.User
import allin.entities.UsersEntity.addUserEntity
import allin.entities.UsersEntity.deleteUserByUsername
import allin.entities.UsersEntity.getUserByUsernameAndPassword
import allin.entities.UsersEntity.getUserToUserDTO
import allin.model.*
import allin.utils.AppConfig
import io.ktor.http.*
import io.ktor.server.application.*
@ -11,15 +13,13 @@ import io.ktor.server.auth.jwt.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import org.ktorm.database.Database
val users = mutableListOf<User>()
val RegexCheckerUser= AppConfig.regexChecker
val CryptManagerUser= AppConfig.cryptManager
val tokenManagerUser=AppConfig.tokenManager
val database = Database.connect("jdbc:postgresql://localhost:5432/Allin", user = "postgres", password = "lulu")
fun Application.UserRouter() {
routing {
route("/users/register"){
post {
@ -27,12 +27,13 @@ fun Application.UserRouter() {
if (RegexCheckerUser.isEmailInvalid(TempUser.email)){
call.respond(HttpStatusCode.Forbidden,"Input a valid mail !")
}
val users=getUserToUserDTO()
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)
addUserEntity(TempUser)
call.respond(HttpStatusCode.Created,TempUser)
}
call.respond(HttpStatusCode.Conflict,"Mail or/and username already exist")
}
@ -41,25 +42,27 @@ fun Application.UserRouter() {
route("/users/login") {
post {
val checkUser = call.receive<CheckUser>()
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))
val user =getUserByUsernameAndPassword(checkUser.login)
if (CryptManagerUser.passwordDecrypt(user.second.toString(),checkUser.password)) {
val userDtoWithToken=user.first
userDtoWithToken?.token=tokenManagerUser.generateOrReplaceJWTToken(userDtoWithToken!!)
call.respond(HttpStatusCode.OK, userDtoWithToken)
} else {
call.respond(HttpStatusCode.NotFound,"Login and/or password incorrect.")
}
}
}
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))
val user =getUserByUsernameAndPassword(checkUser.login)
if (CryptManagerUser.passwordDecrypt(user.second.toString(),checkUser.password)) {
if (!deleteUserByUsername(checkUser.login)) {
call.respond(HttpStatusCode.InternalServerError, "This user can't be delete now !")
}
call.respond(HttpStatusCode.Accepted,user.first!!)
} else {
call.respond(HttpStatusCode.NotFound,"Login and/or password incorrect.")
call.respond(HttpStatusCode.NotFound, "Login and/or password incorrect.")
}
}
}
@ -68,14 +71,13 @@ fun Application.UserRouter() {
get("/users/token") {
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))
val user=getUserByUsernameAndPassword(username)
if (user.first != null) {
call.respond(HttpStatusCode.OK, user.first!!)
} else {
call.respond(HttpStatusCode.NotFound, "User not found with the valid token !")
}
}
}
}
}

@ -6,22 +6,22 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import java.text.SimpleDateFormat
import java.util.*
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter
@Serializer(Date::class)
class DateSerializer : KSerializer<Date> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.STRING)
@Serializer(ZonedDateTime::class)
object ZonedDateTimeSerializer : KSerializer<ZonedDateTime> {
private val formatter: DateTimeFormatter = DateTimeFormatter.ISO_ZONED_DATE_TIME
val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.FRANCE)
override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("ZonedDateTime", PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): Date {
val dateString = decoder.decodeString()
return formatter.parse(dateString)
override fun serialize(encoder: Encoder, value: ZonedDateTime) {
encoder.encodeString(formatter.format(value))
}
override fun serialize(encoder: Encoder, value: Date) {
val dateString = formatter.format(value)
encoder.encodeString(dateString)
override fun deserialize(decoder: Decoder): ZonedDateTime {
val dateString = decoder.decodeString()
return ZonedDateTime.parse(dateString, formatter)
}
}
}

@ -4,12 +4,18 @@ import allin.model.User
import org.mindrot.jbcrypt.BCrypt
class CryptManager {
val salt=BCrypt.gensalt()
//val salt=BCrypt.gensalt()
fun passwordCrypt(password : String): String {
return BCrypt.hashpw(password,"\$2a\$10\$42wsdBeoLKaF6SM9oADONe")
}
fun passwordCrypt(user: User){
user.password=BCrypt.hashpw(user.password,salt)
user.password=BCrypt.hashpw(user.password,"\$2a\$10\$42wsdBeoLKaF6SM9oADONe")
}
fun passwordDecrypt(user: User, password: String): Boolean{
return BCrypt.hashpw(password,salt)==user.password
fun passwordDecrypt(password: String, passwordClear: String): Boolean{
return BCrypt.hashpw(passwordClear,"\$2a\$10\$42wsdBeoLKaF6SM9oADONe")==password
}
fun CheckPassword(hashed: String, clear: String): Boolean{
return BCrypt.checkpw(hashed,clear)
}
}

@ -1,5 +1,6 @@
package allin.utils
import allin.dto.UserDTO
import allin.model.User
import com.auth0.jwt.JWT
import com.auth0.jwt.JWTVerifier
@ -15,7 +16,6 @@ class TokenManager private constructor(val config: HoconApplicationConfig) {
val issuer=config.property("issuer").getString()
fun generateJWTToken(user : User): String {
val expirationDate = System.currentTimeMillis() + 604800000 // une semaine en miliseconde
val token = JWT.create()
.withAudience(audience)
.withIssuer(issuer)
@ -41,6 +41,26 @@ class TokenManager private constructor(val config: HoconApplicationConfig) {
}
}
fun generateOrReplaceJWTToken(user: UserDTO): String {
val userToken = getUserToken(user)
if (userToken != null && !isTokenExpired(userToken)) {
return userToken
} else {
return generateJWTToken(user)
}
}
fun generateJWTToken(user : UserDTO): String {
val expirationDate = System.currentTimeMillis() + 604800000 // une semaine en miliseconde
val token = JWT.create()
.withAudience(audience)
.withIssuer(issuer)
.withClaim("username", user.username)
.withExpiresAt(Date(expirationDate))
.sign(Algorithm.HMAC256(secret))
return token
}
fun isTokenExpired(token: String): Boolean {
val expirationTime = JWT.decode(token).expiresAt.time
return System.currentTimeMillis() > expirationTime
@ -49,7 +69,9 @@ class TokenManager private constructor(val config: HoconApplicationConfig) {
fun getUserToken(user: User): String? {
return user.token
}
fun getUserToken(user: UserDTO): String? {
return user.token
}
fun getUsernameFromToken(token: String) : String{
val decodedJWT: DecodedJWT = JWT.decode(token)
return decodedJWT.getClaim("username").asString()

Loading…
Cancel
Save