Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ out/
/.nb-gradle/

### VS Code ###
.vscode/
.vscode/
/config/
8 changes: 8 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ val kotlin_version: String by project
val logback_version: String by project
val kmongo_version: String by project
val koin_version: String by project
val firebase_version: String by project

plugins {
application
Expand All @@ -15,6 +16,7 @@ version = "1.0"

application {
mainClass.set("es.wokis.ApplicationKt")
mainClassName = "es.wokis.ApplicationKt"

val isDevelopment: Boolean = project.ext.has("development")
applicationDefaultJvmArgs = listOf("-Dio.ktor.development=$isDevelopment")
Expand Down Expand Up @@ -47,6 +49,12 @@ dependencies {
// Koin
implementation("io.insert-koin:koin-ktor:$koin_version")
implementation("io.insert-koin:koin-logger-slf4j:$koin_version")

// Firebase
implementation("com.google.firebase:firebase-admin:$firebase_version")

// BCrypt
implementation("org.mindrot:jbcrypt:0.4")
}

ktor {
Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ kotlin_version=1.7.21
logback_version=1.4.4
kmongo_version=4.7.2
koin_version=3.2.2
firebase_version=9.1.1
kotlin.code.style=official
16 changes: 13 additions & 3 deletions src/main/kotlin/es/wokis/Application.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
package es.wokis

import com.typesafe.config.ConfigFactory
import es.wokis.plugins.*
import io.ktor.server.application.*
import io.ktor.server.config.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import es.wokis.plugins.*

fun main() {
embeddedServer(Netty, port = 8080, host = "0.0.0.0", module = Application::module)
.start(wait = true)
embeddedServer(Netty, environment = applicationEngineEnvironment {
config = HoconApplicationConfig(ConfigFactory.load("application.conf"))

connector {
host = config.host
port = config.port
}
}).start(wait = true)
}

fun Application.module() {
initConfig()
configureFirebase()
configureKoin()
configureSerialization()
configureMonitoring()
Expand Down
37 changes: 37 additions & 0 deletions src/main/kotlin/es/wokis/data/bo/invoice/InvoiceBO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package es.wokis.data.bo.invoice

import es.wokis.data.constants.ServerConstants.EMPTY_TEXT
import java.util.*

data class InvoiceBO(
val id: String? = null,
val idApp: Long = 0L,
val title: String = EMPTY_TEXT,
val description: String = EMPTY_TEXT,
val quantity: Int = 0,
val date: Date = Date(),
val type: InvoiceType,
val userId: String,
val category: CategoryBO? = null,
val reactions: List<ReactionBO> = emptyList()
)

data class CategoryBO(
val id: Long,
val title: String,
val color: String,
)

data class ReactionBO(
val id: Long,
val unicode: String
)

enum class InvoiceType(val key: String) {
DEPOSIT("DEPOSIT"),
EXPENSE("EXPENSE");

companion object {
fun getFromKey(key: String) = values().find { it.key == key } ?: DEPOSIT
}
}
13 changes: 13 additions & 0 deletions src/main/kotlin/es/wokis/data/bo/user/UserBO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package es.wokis.data.bo.user

import es.wokis.data.constants.ServerConstants.EMPTY_TEXT
import io.ktor.server.auth.*

data class UserBO(
val id: String? = null,
val username: String,
val email: String,
val password: String,
val image: String = EMPTY_TEXT,
val devices: List<String> = emptyList()
) : Principal
5 changes: 5 additions & 0 deletions src/main/kotlin/es/wokis/data/constants/ServerConstants.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package es.wokis.data.constants

object ServerConstants {
const val EMPTY_TEXT = ""
}
30 changes: 30 additions & 0 deletions src/main/kotlin/es/wokis/data/database/AppDataBase.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package es.wokis.data.database

import com.mongodb.ConnectionString
import com.mongodb.MongoClientSettings
import com.mongodb.MongoCredential
import es.wokis.data.dbo.invoice.InvoiceDBO
import es.wokis.data.dbo.user.UserDBO
import es.wokis.plugins.config
import org.litote.kmongo.KMongo
import org.litote.kmongo.getCollection

class AppDataBase {
private val username = config.getString("db.user")
private val password = config.getString("db.password")
private val dataBaseUrl = "$MONGODB_PREFIX$username:$password@${config.getString("db.ip")}:${config.getString("db.port")}"
private val databaseName = config.getString("db.databaseName")
private val client = KMongo.createClient(
MongoClientSettings.builder()
.credential(MongoCredential.createCredential(username, databaseName, password.toCharArray()))
.applyConnectionString(ConnectionString(dataBaseUrl)).build()
)

val database by lazy { client.getDatabase(databaseName) }
val usersCollection by lazy { database.getCollection<UserDBO>("users") }
val invoicesCollection by lazy { database.getCollection<InvoiceDBO>("invoices") }

companion object {
private const val MONGODB_PREFIX = "mongodb://"
}
}
63 changes: 63 additions & 0 deletions src/main/kotlin/es/wokis/data/datasource/UserLocalDataSource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package es.wokis.data.datasource

import com.mongodb.client.MongoCollection
import es.wokis.data.bo.user.UserBO
import es.wokis.data.constants.ServerConstants.EMPTY_TEXT
import es.wokis.data.dbo.user.UserDBO
import es.wokis.data.mapper.user.toBO
import es.wokis.data.mapper.user.toDBO
import org.bson.types.ObjectId
import org.litote.kmongo.*
import org.litote.kmongo.id.toId
import java.util.regex.Pattern

interface UserLocalDataSource {
suspend fun getAllUsers(): List<UserBO>
suspend fun getUserById(id: String): UserBO?
suspend fun getUserByEmail(email: String): UserBO?
suspend fun getUserByUsername(username: String): UserBO?

suspend fun getUserByUsernameOrEmail(username: String, email: String = EMPTY_TEXT): UserBO?

suspend fun createUser(user: UserBO): Boolean
}

class UserLocalDataSourceImpl(private val userCollection: MongoCollection<UserDBO>) : UserLocalDataSource {

private val getCaseInsensitive: (element: String) -> Pattern = {
Pattern.compile(it, Pattern.CASE_INSENSITIVE)
}

override suspend fun getAllUsers(): List<UserBO> = userCollection.find().map {
it.toBO()
}.toList()

override suspend fun getUserById(id: String): UserBO? {
val bsonId: Id<UserDBO> = ObjectId(id).toId()
return userCollection.findOne(UserDBO::id eq bsonId)?.toBO()
}

override suspend fun getUserByEmail(email: String): UserBO? =
userCollection.findOne(UserDBO::email.regex(getCaseInsensitive(email)))?.toBO()

override suspend fun getUserByUsername(username: String): UserBO? =
userCollection.findOne(UserDBO::username.regex(getCaseInsensitive(username)))?.toBO()

override suspend fun getUserByUsernameOrEmail(username: String, email: String): UserBO? =
userCollection.findOne(
or(
UserDBO::username.regex(getCaseInsensitive(username)),
UserDBO::email.regex(getCaseInsensitive(email.takeIf { it.isNotBlank() } ?: username))
)
)?.toBO()

override suspend fun createUser(user: UserBO): Boolean {
return try {
userCollection.insertOne(user.toDBO()).wasAcknowledged()

} catch (e: Throwable) {
println(e.stackTraceToString())
false
}
}
}
28 changes: 28 additions & 0 deletions src/main/kotlin/es/wokis/data/dbo/invoice/InvoiceDBO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package es.wokis.data.dbo.invoice

import es.wokis.data.constants.ServerConstants
import org.litote.kmongo.Id

data class InvoiceDBO(
val id: Id<InvoiceDBO>? = null,
val idApp: Long = 0L,
val title: String = ServerConstants.EMPTY_TEXT,
val description: String = ServerConstants.EMPTY_TEXT,
val quantity: Int = 0,
val date: Long = 0L,
val type: String? = null,
val userId: String? = null,
val category: CategoryDBO? = null,
val reactions: List<ReactionDBO> = emptyList()
)

data class CategoryDBO(
val id: Long,
val title: String,
val color: String,
)

data class ReactionDBO(
val id: Long,
val unicode: String
)
13 changes: 13 additions & 0 deletions src/main/kotlin/es/wokis/data/dbo/user/UserDBO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package es.wokis.data.dbo.user

import org.bson.codecs.pojo.annotations.BsonId
import org.litote.kmongo.Id

data class UserDBO(
@BsonId
val id: Id<UserDBO>? = null,
val username: String,
val email: String,
val password: String,
val devices: List<String> = emptyList()
)
43 changes: 43 additions & 0 deletions src/main/kotlin/es/wokis/data/dto/invoice/InvoiceDTO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package es.wokis.data.dto.invoice

import com.google.gson.annotations.SerializedName
import es.wokis.data.constants.ServerConstants.EMPTY_TEXT

data class InvoiceDTO(
@SerializedName("server_id")
val id: String? = null,
@SerializedName("id")
val idApp: Long = 0L,
@SerializedName("title")
val title: String = EMPTY_TEXT,
@SerializedName("description")
val description: String = EMPTY_TEXT,
@SerializedName("quantity")
val quantity: Int = 0,
@SerializedName("date")
val date: Long = 0L,
@SerializedName("type")
val type: String? = null,
@SerializedName("userId")
val userId: String? = null,
@SerializedName("category")
val category: CategoryDTO? = null,
@SerializedName("reactions")
val reactions: List<ReactionDTO> = emptyList()
)

data class CategoryDTO(
@SerializedName("id")
val id: Long,
@SerializedName("title")
val title: String,
@SerializedName("color")
val color: String,
)

data class ReactionDTO(
@SerializedName("id")
val id: Long,
@SerializedName("unicode")
val unicode: String
)
11 changes: 11 additions & 0 deletions src/main/kotlin/es/wokis/data/dto/user/UserDTO.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package es.wokis.data.dto.user

import es.wokis.data.constants.ServerConstants

data class UserDTO(
val id: String,
val username: String,
val email: String,
val image: String = ServerConstants.EMPTY_TEXT,
val devices: List<String> = emptyList()
)
12 changes: 12 additions & 0 deletions src/main/kotlin/es/wokis/data/dto/user/auth/Auth.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package es.wokis.data.dto.user.auth

data class LoginDTO(
val username: String,
val password: String
)

data class RegisterDTO(
val username: String,
val email: String,
val password: String
)
36 changes: 36 additions & 0 deletions src/main/kotlin/es/wokis/data/mapper/invoice/InvoiceMapper.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package es.wokis.data.mapper.invoice

import es.wokis.data.bo.invoice.CategoryBO
import es.wokis.data.bo.invoice.InvoiceBO
import es.wokis.data.bo.invoice.InvoiceType
import es.wokis.data.bo.invoice.ReactionBO
import es.wokis.data.dto.invoice.CategoryDTO
import es.wokis.data.dto.invoice.InvoiceDTO
import es.wokis.data.dto.invoice.ReactionDTO
import java.util.*

fun InvoiceDTO.toBO() = InvoiceBO(
id = id,
idApp = idApp,
title = title,
description = description,
quantity = quantity,
date = Date(date),
type = InvoiceType.valueOf(type.orEmpty()),
userId = userId.orEmpty(),
category = category?.toBO(),
reactions = reactions.toBO()
)

fun CategoryDTO.toBO() = CategoryBO(
id = id,
title = title,
color = color
)

fun List<ReactionDTO>?.toBO() = this?.map { it.toBO() }.orEmpty()

fun ReactionDTO.toBO() = ReactionBO(
id = id,
unicode = unicode
)
Loading