Refactor and fixes
continuous-integration/drone/push Build is passing Details

pull/12/head
avalin 11 months ago
parent 0621d8c406
commit cae02af684

@ -33,6 +33,7 @@ private val allInDataSource: AllInDataSource = when (data_source) {
"postgres" -> PostgresDataSource()
else -> MockDataSource()
}
val Application.dataSource: AllInDataSource
get() = allInDataSource
@ -79,11 +80,11 @@ private fun Application.extracted() {
}
}
BasicRouting()
UserRouter()
BetRouter()
ParticipationRouter()
BetDetailRouter()
basicRouter()
userRouter()
betRouter()
participationRouter()
betDetailRouter()
kronJob(BET_VERIFY_DELAY) {
dataSource.betDataSource.updateBetStatuses(ZonedDateTime.now())

@ -4,7 +4,6 @@ import allin.dto.UserDTO
import allin.model.User
interface UserDataSource {
fun getUserByUsername(username: String): Pair<UserDTO?, String?>
fun addUser(user: User)
fun deleteUser(username: String): Boolean

@ -6,11 +6,11 @@ import allin.model.BetStatus.*
import java.time.ZonedDateTime
class MockBetDataSource(mockData: MockDataSource.MockData) : BetDataSource {
private val bets = mockData.bets
private val results = mockData.results
private val users = mockData.users
private val participations = mockData.participations
private val resultNotifications = mockData.resultNotifications
private val bets by lazy { mockData.bets }
private val results by lazy { mockData.results }
private val users by lazy { mockData.users }
private val participations by lazy { mockData.participations }
private val resultNotifications by lazy { mockData.resultNotifications }
override fun getAllBets(): List<Bet> = bets
override fun getBetById(id: String): Bet? =
@ -39,7 +39,7 @@ class MockBetDataSource(mockData: MockDataSource.MockData) : BetDataSource {
if (date >= bet.endBet) {
bets[idx] = bet.copy(status = CLOSING)
} else {
bets[idx] = bet.copy(status = WAITING)
bets[idx] = bet.copy(status = IN_PROGRESS)
}
}
}

@ -12,6 +12,10 @@ import java.time.ZonedDateTime
class MockDataSource : AllInDataSource() {
init {
println("APP STARTING ON MOCK DATA SOURCE")
}
class MockData {
val bets by lazy { mutableListOf<Bet>() }
val results by lazy { mutableListOf<BetResult>() }
@ -23,7 +27,7 @@ class MockDataSource : AllInDataSource() {
private val mockData by lazy { MockData() }
override val userDataSource: UserDataSource = MockUserDataSource(mockData)
override val betDataSource: BetDataSource = MockBetDataSource(mockData)
override val participationDataSource: ParticipationDataSource = MockParticipationDataSource(mockData)
override val userDataSource: UserDataSource by lazy { MockUserDataSource(mockData) }
override val betDataSource: BetDataSource by lazy { MockBetDataSource(mockData) }
override val participationDataSource: ParticipationDataSource by lazy { MockParticipationDataSource(mockData) }
}

@ -4,7 +4,7 @@ import allin.data.ParticipationDataSource
import allin.model.Participation
class MockParticipationDataSource(mockData: MockDataSource.MockData) : ParticipationDataSource {
private val participations = mockData.participations
private val participations by lazy { mockData.participations }
override fun addParticipation(participation: Participation) {
participations += participation

@ -6,9 +6,8 @@ import allin.model.User
import java.time.ZonedDateTime
class MockUserDataSource(mockData: MockDataSource.MockData) : UserDataSource {
private val users = mockData.users
private val lastGifts = mockData.lastGifts
private val users by lazy { mockData.users }
private val lastGifts by lazy { mockData.lastGifts }
override fun getUserByUsername(username: String): Pair<UserDTO?, String?> =
users.find { it.username == username }?.let {

@ -200,7 +200,7 @@ class PostgresBetDataSource(private val database: Database) : BetDataSource {
override fun updateBetStatuses(date: ZonedDateTime) {
database.update(BetsEntity) {
set(BetsEntity.status, BetStatus.WAITING)
set(BetsEntity.status, BetStatus.IN_PROGRESS)
where {
(date.toInstant() greaterEq BetsEntity.endRegistration) and
(date.toInstant() less BetsEntity.endBet) and

@ -4,7 +4,7 @@ import allin.data.AllInDataSource
import allin.data.BetDataSource
import allin.data.ParticipationDataSource
import allin.data.UserDataSource
import allin.utils.Execute
import allin.ext.execute
import org.ktorm.database.Database
class PostgresDataSource : AllInDataSource() {
@ -16,14 +16,17 @@ class PostgresDataSource : AllInDataSource() {
val dbUser = System.getenv()["POSTGRES_USER"]
val dbPassword = System.getenv()["POSTGRES_PASSWORD"]
val dbHost = System.getenv()["POSTGRES_HOST"]
val url = "jdbc:postgresql://$dbHost/$dbDatabase"
println("APP STARTING ON POSTGRESQL DATA SOURCE $url")
database = Database.connect(
url = "jdbc:postgresql://$dbHost/$dbDatabase",
url = url,
user = dbUser,
password = dbPassword
)
database.Execute(
database.execute(
"""
CREATE TABLE IF not exists utilisateur (
id VARCHAR(255) PRIMARY KEY,
@ -36,7 +39,7 @@ class PostgresDataSource : AllInDataSource() {
""".trimIndent()
)
database.Execute(
database.execute(
"""
CREATE TABLE IF not exists bet (
id VARCHAR(255) PRIMARY KEY,
@ -52,7 +55,7 @@ class PostgresDataSource : AllInDataSource() {
""".trimIndent()
)
database.Execute(
database.execute(
"""
CREATE TABLE IF NOT EXISTS betresult (
betid VARCHAR(255) PRIMARY KEY REFERENCES bet,
@ -61,7 +64,7 @@ class PostgresDataSource : AllInDataSource() {
""".trimIndent()
)
database.Execute(
database.execute(
"""
CREATE TABLE IF NOT EXISTS betresultnotification (
betid VARCHAR(255),
@ -71,7 +74,7 @@ class PostgresDataSource : AllInDataSource() {
""".trimIndent()
)
database.Execute(
database.execute(
"""
CREATE TABLE IF NOT EXISTS participation (
id VARCHAR(255) PRIMARY KEY,
@ -83,7 +86,7 @@ class PostgresDataSource : AllInDataSource() {
""".trimIndent()
)
database.Execute(
database.execute(
"""
CREATE TABLE IF NOT EXISTS response (
id VARCHAR(255),
@ -94,7 +97,7 @@ class PostgresDataSource : AllInDataSource() {
)
}
override val userDataSource: UserDataSource = PostgresUserDataSource(database)
override val betDataSource: BetDataSource = PostgresBetDataSource(database)
override val participationDataSource: ParticipationDataSource = PostgresParticipationDataSource(database)
override val userDataSource: UserDataSource by lazy { PostgresUserDataSource(database) }
override val betDataSource: BetDataSource by lazy { PostgresBetDataSource(database) }
override val participationDataSource: ParticipationDataSource by lazy { PostgresParticipationDataSource(database) }
}

@ -3,8 +3,8 @@ package allin.data.postgres
import allin.data.UserDataSource
import allin.data.postgres.entities.UsersEntity
import allin.dto.UserDTO
import allin.ext.executeWithResult
import allin.model.User
import allin.utils.ExecuteWithResult
import org.ktorm.database.Database
import org.ktorm.database.use
import org.ktorm.dsl.*
@ -70,7 +70,7 @@ class PostgresUserDataSource(private val database: Database) : UserDataSource {
override fun canHaveDailyGift(username: String): Boolean {
val request =
"SELECT CASE WHEN DATE(NOW()) > DATE(lastgift) THEN true ELSE false END AS is_lastgift_greater_than_1_day FROM utilisateur WHERE username = '$username';"
val resultSet = database.ExecuteWithResult(request)
val resultSet = database.executeWithResult(request)
resultSet?.use {
if (resultSet.next()) {

@ -20,4 +20,4 @@ object ParticipationsEntity : Table<ParticipationEntity>("participation") {
val username = varchar("username")
val answer = varchar("answer")
val stake = int("stake")
}
}

@ -1,18 +1,12 @@
package allin.dto
import io.github.smiley4.ktorswaggerui.dsl.Example
import kotlinx.serialization.Serializable
@Serializable
data class UserDTO(
@Example("cabb366c-5a47-4b0f-81e1-25a08fe2c2fe")
val id: String,
@Example("Steve")
val username: String,
@Example("stevemaroco@gmail.com")
val email: String,
@Example("16027")
val nbCoins: Int,
@Example("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwOi8vMC4wLjAuMDo4MDgwLyIsImlzcyI6Imh0dHA6Ly8wLjAuMC4wOjgwODAvIiwidXNlcm5hbWUiOiJ0ZXN0IiwiZXhwIjoxNzA3OTIyNjY1fQ.TwaT9Rd4Xkhg3l4fHiba0IEqnM7xUGJVFRrr5oaWOwQ")
var token: String?
)

@ -1,9 +1,9 @@
package allin.utils
package allin.ext
import org.ktorm.database.Database
import java.sql.ResultSet
fun Database.ExecuteWithResult(request: String): ResultSet? {
fun Database.executeWithResult(request: String): ResultSet? {
try {
if (request.isNotEmpty()) {
return this.useTransaction { transaction ->
@ -19,7 +19,7 @@ fun Database.ExecuteWithResult(request: String): ResultSet? {
return null
}
fun Database.Execute(request: String) {
fun Database.execute(request: String) {
if (request.isNotEmpty())
this.useTransaction {
val connection = it.connection

@ -1,6 +1,6 @@
package allin.model
import allin.model.BetStatus.IN_PROGRESS
import allin.model.BetStatus.WAITING
import allin.serializer.ZonedDateTimeSerializer
import kotlinx.serialization.Serializable
import java.time.ZonedDateTime
@ -10,7 +10,7 @@ data class Bet(
val id: String = "",
val theme: String,
val sentenceBet: String,
val status: BetStatus = IN_PROGRESS,
val status: BetStatus = WAITING,
val type: BetType,
@Serializable(ZonedDateTimeSerializer::class) val endRegistration: ZonedDateTime,
@Serializable(ZonedDateTimeSerializer::class) var endBet: ZonedDateTime,

@ -1,43 +1,30 @@
package allin.model
import io.github.smiley4.ktorswaggerui.dsl.Example
import kotlinx.serialization.Serializable
import kotlin.random.Random
const val DEFAULT_COIN_AMOUNT = 500
const val DAILY_GIFT_MIN = 10
const val DAILY_GIFT_MAX = 150
@Serializable
data class User(
@Example("cabb366c-5a47-4b0f-81e1-25a08fe2c2fe")
val id: String,
@Example("Steve")
val username: String,
@Example("stevemaroco@gmail.com")
val email: String,
@Example("MarocoSteveHDOIU978*")
var password: String,
@Example("16027")
var nbCoins: Int = 500,
@Example("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJodHRwOi8vMC4wLjAuMDo4MDgwLyIsImlzcyI6Imh0dHA6Ly8wLjAuMC4wOjgwODAvIiwidXNlcm5hbWUiOiJ0ZXN0IiwiZXhwIjoxNzA3OTIyNjY1fQ.TwaT9Rd4Xkhg3l4fHiba0IEqnM7xUGJVFRrr5oaWOwQ")
var nbCoins: Int = DEFAULT_COIN_AMOUNT,
var token: String? = null
)
@Serializable
data class UserRequest(
@Example("Steve")
val username: String,
@Example("stevemaroco@gmail.com")
val email: String,
@Example("MarocoSteveHDOIU978*")
var password: String
)
@Serializable
data class CheckUser(
@Example("stevemaroco@gmail.com")
val login: String,
@Example("MarocoSteveHDOIU978*")
val password: String
)
fun getDailyGift() : Int{
return Random.nextInt(10,150)
}
)

@ -8,7 +8,7 @@ import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Application.BasicRouting() {
fun Application.basicRouter() {
routing {
get("/", {
description = "Hello World of Allin API"

@ -16,7 +16,7 @@ import io.ktor.server.routing.*
import java.util.*
fun Application.BetDetailRouter() {
fun Application.betDetailRouter() {
val userDataSource = this.dataSource.userDataSource
val betDataSource = this.dataSource.betDataSource
val participationDataSource = this.dataSource.participationDataSource

@ -7,7 +7,6 @@ import allin.model.*
import allin.utils.AppConfig
import io.github.smiley4.ktorswaggerui.dsl.get
import io.github.smiley4.ktorswaggerui.dsl.post
import io.github.smiley4.ktorswaggerui.dsl.route
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.auth.*
@ -15,13 +14,11 @@ import io.ktor.server.auth.jwt.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.swagger.annotations.Api
import java.util.*
val tokenManagerBet = AppConfig.tokenManager
fun Application.BetRouter() {
fun Application.betRouter() {
val userDataSource = this.dataSource.userDataSource
val betDataSource = this.dataSource.betDataSource
val participationDataSource = this.dataSource.participationDataSource

@ -18,7 +18,7 @@ import io.ktor.server.routing.*
import java.util.*
fun Application.ParticipationRouter() {
fun Application.participationRouter() {
val userDataSource = this.dataSource.userDataSource
val participationDataSource = this.dataSource.participationDataSource

@ -15,7 +15,6 @@ import io.ktor.server.auth.jwt.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.swagger.annotations.Api
import java.util.*
val RegexCheckerUser = AppConfig.regexChecker
@ -24,7 +23,7 @@ val tokenManagerUser = AppConfig.tokenManager
const val DEFAULT_COINS = 500
fun Application.UserRouter() {
fun Application.userRouter() {
val userDataSource = this.dataSource.userDataSource
@ -39,8 +38,8 @@ fun Application.UserRouter() {
response {
HttpStatusCode.Created to {
description = "User created"
body<User>{
description="The new user"
body<User> {
description = "The new user"
}
}
HttpStatusCode.Conflict to {
@ -189,7 +188,7 @@ fun Application.UserRouter() {
hasToken { principal ->
verifyUserFromToken(userDataSource, principal) { userDto, _ ->
if (userDataSource.canHaveDailyGift(userDto.username)) {
val dailyGift = getDailyGift()
val dailyGift = (DAILY_GIFT_MIN..DAILY_GIFT_MAX).random()
userDataSource.addCoins(userDto.username, dailyGift)
call.respond(HttpStatusCode.OK, dailyGift)
} else call.respond(HttpStatusCode.MethodNotAllowed, ApiMessage.NO_GIFT)

@ -1,5 +1,6 @@
package allin.serializer
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializer
import kotlinx.serialization.descriptors.PrimitiveKind
@ -7,13 +8,11 @@ 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
@OptIn(ExperimentalSerializationApi::class)
@Serializer(ZonedDateTime::class)
object ZonedDateTimeSerializer : KSerializer<ZonedDateTime> {
private val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss Z")

@ -1,11 +1,11 @@
package allin.utils
import com.typesafe.config.ConfigFactory
import io.ktor.server.config.HoconApplicationConfig
import io.ktor.server.config.*
object AppConfig {
val config: HoconApplicationConfig = HoconApplicationConfig(ConfigFactory.load())
private val config: HoconApplicationConfig = HoconApplicationConfig(ConfigFactory.load())
val tokenManager = TokenManager.getInstance(config)
val regexChecker= RegexChecker()
val regexChecker = RegexChecker()
val cryptManager = CryptManager()
}

@ -4,9 +4,12 @@ import allin.model.User
import org.mindrot.jbcrypt.BCrypt
class CryptManager {
val salt=addDollarsSecrets(System.getenv().get("SALT").toString())
private val salt = addDollarsSecrets(
System.getenv()["SALT"] ?: throw RuntimeException("Salt is null")
)
// Cette fonction permet de remettre les $ que drone supprime dans les secrets drone
fun addDollarsSecrets(chaine: String): String {
private fun addDollarsSecrets(chaine: String): String {
val stringBuilder = StringBuilder(chaine)
stringBuilder.insert(0, '$')
stringBuilder.insert(3, '$')
@ -14,17 +17,20 @@ class CryptManager {
return stringBuilder.toString()
}
fun passwordCrypt(password : String): String {
return BCrypt.hashpw(password,salt)
fun passwordCrypt(password: String): String {
return BCrypt.hashpw(password, salt)
}
fun passwordCrypt(user: User){
user.password=BCrypt.hashpw(user.password,salt)
fun passwordCrypt(user: User) {
user.password = BCrypt.hashpw(user.password, salt)
}
fun passwordDecrypt(password: String, passwordClear: String): Boolean{
return BCrypt.hashpw(passwordClear,salt)==password
fun passwordDecrypt(password: String, passwordClear: String): Boolean {
return BCrypt.hashpw(passwordClear, salt) == password
}
fun CheckPassword(hashed: String, clear: String): Boolean{
return BCrypt.checkpw(hashed,clear)
fun checkPassword(hashed: String, clear: String): Boolean {
return BCrypt.checkpw(hashed, clear)
}
}
}

@ -2,9 +2,8 @@ package allin.utils
import kotlinx.coroutines.*
import kotlin.time.Duration
import kotlin.time.ExperimentalTime
@OptIn(DelicateCoroutinesApi::class, ExperimentalTime::class)
@OptIn(DelicateCoroutinesApi::class)
fun kronJob(duration: Duration, action: () -> Unit) =
GlobalScope.launch {
withContext(Dispatchers.IO) {

Loading…
Cancel
Save