add generate jwt token
This commit is contained in:
parent
9ca22827d5
commit
b1b1be8a14
@ -24,6 +24,7 @@ dependencies {
|
|||||||
implementation(libs.ktor.serialization.kotlinx.json)
|
implementation(libs.ktor.serialization.kotlinx.json)
|
||||||
implementation(libs.ktor.server.content.negotiation)
|
implementation(libs.ktor.server.content.negotiation)
|
||||||
implementation(libs.postgresql)
|
implementation(libs.postgresql)
|
||||||
|
implementation("org.springframework.security:spring-security-crypto:6.4.1")
|
||||||
implementation("io.insert-koin:koin-ktor:4.0.0")
|
implementation("io.insert-koin:koin-ktor:4.0.0")
|
||||||
implementation("org.jetbrains.exposed:exposed-java-time:0.57.0")
|
implementation("org.jetbrains.exposed:exposed-java-time:0.57.0")
|
||||||
implementation(libs.exposed.core)
|
implementation(libs.exposed.core)
|
||||||
|
@ -1,6 +1,14 @@
|
|||||||
package com.college
|
package com.college
|
||||||
|
|
||||||
|
import com.college.controller.auth.AuthRouter
|
||||||
|
import com.college.data.DbSettings
|
||||||
|
import com.college.di.myModule
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.serialization.kotlinx.json.*
|
||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
|
import io.ktor.server.plugins.contentnegotiation.*
|
||||||
|
import io.ktor.server.plugins.cors.routing.*
|
||||||
|
import io.ktor.server.routing.*
|
||||||
import org.koin.ktor.plugin.Koin
|
import org.koin.ktor.plugin.Koin
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
@ -8,6 +16,15 @@ fun main(args: Array<String>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Application.module() {
|
fun Application.module() {
|
||||||
install(Koin)
|
val db = DbSettings.db
|
||||||
|
install(Koin){
|
||||||
|
modules(myModule)
|
||||||
|
}
|
||||||
|
install(CORS){
|
||||||
|
allowHeader(HttpHeaders.ContentType)
|
||||||
|
}
|
||||||
|
install(ContentNegotiation){
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
AuthRouter()
|
||||||
}
|
}
|
||||||
|
44
src/main/kotlin/com/college/controller/auth/AuthRouter.kt
Normal file
44
src/main/kotlin/com/college/controller/auth/AuthRouter.kt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package com.college.controller.auth
|
||||||
|
|
||||||
|
import com.auth0.jwt.JWT
|
||||||
|
import com.auth0.jwt.algorithms.Algorithm
|
||||||
|
import com.college.controller.request.UserRegistrationRequest
|
||||||
|
import com.college.controller.request.UserLoginRequest
|
||||||
|
import com.college.controller.response.AuthResponse
|
||||||
|
import com.college.domain.request.user.UserCreateRequest
|
||||||
|
import com.college.domain.request.user.UserFindRequest
|
||||||
|
import com.college.domain.usecase.UserUseCase
|
||||||
|
import io.ktor.http.*
|
||||||
|
import io.ktor.server.application.*
|
||||||
|
import io.ktor.server.request.*
|
||||||
|
import io.ktor.server.response.*
|
||||||
|
import io.ktor.server.routing.*
|
||||||
|
import org.koin.ktor.ext.inject
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun Application.AuthRouter(){
|
||||||
|
val userUseCase by inject<UserUseCase>()
|
||||||
|
routing {
|
||||||
|
route("auth"){
|
||||||
|
val secret = environment.config.property("jwt.secret").getString()
|
||||||
|
val issuer = environment.config.property("jwt.issuer").getString()
|
||||||
|
post("login") {
|
||||||
|
val user = call.receive<UserLoginRequest>()
|
||||||
|
val findUser = userUseCase.getUserByLogin(userFindRequest = UserFindRequest(
|
||||||
|
login = user.login
|
||||||
|
))
|
||||||
|
val token = JWT.create()
|
||||||
|
.withIssuer(issuer)
|
||||||
|
.withClaim("username", findUser.login)
|
||||||
|
.withExpiresAt(Date(System.currentTimeMillis() + 60000))
|
||||||
|
.sign(Algorithm.HMAC256(secret))
|
||||||
|
call.respond(HttpStatusCode.OK, AuthResponse(jwtToken = token))
|
||||||
|
}
|
||||||
|
post("registration") {
|
||||||
|
val newUser = call.receive<UserRegistrationRequest>()
|
||||||
|
val userCreateRequest = UserCreateRequest(password = newUser.password, login = newUser.login, roleId = newUser.roleId)
|
||||||
|
userUseCase.register(userCreateRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.college.controller.common
|
||||||
|
|
||||||
|
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder
|
||||||
|
|
||||||
|
fun encodePassword(password: String):String{
|
||||||
|
val argon2PasswordEncoder = Argon2PasswordEncoder(16, 32, 1, 60000, 16)
|
||||||
|
return argon2PasswordEncoder.encode(password)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun matchPassword(password: String, hashedPassword: String): Boolean {
|
||||||
|
val argon2PasswordEncoder = Argon2PasswordEncoder(16, 32, 1, 60000, 16)
|
||||||
|
return argon2PasswordEncoder.matches(password, hashedPassword)
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.college.controller.request
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class UserLoginRequest(val login: String, val password: String)
|
@ -0,0 +1,6 @@
|
|||||||
|
package com.college.controller.request
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class UserRegistrationRequest(val login: String, val password: String, val roleId: Int)
|
@ -0,0 +1,7 @@
|
|||||||
|
package com.college.controller.response
|
||||||
|
|
||||||
|
import com.auth0.jwt.JWT
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class AuthResponse (val jwtToken: String)
|
@ -1,18 +1,28 @@
|
|||||||
package com.college.data
|
package com.college.data
|
||||||
|
|
||||||
|
import com.college.data.table.RoleIdTable
|
||||||
|
import com.college.data.table.UserUuidTable
|
||||||
import org.jetbrains.exposed.sql.Database
|
import org.jetbrains.exposed.sql.Database
|
||||||
|
import org.jetbrains.exposed.sql.SchemaUtils
|
||||||
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
|
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transaction
|
||||||
|
import org.jetbrains.exposed.sql.transactions.transactionManager
|
||||||
|
|
||||||
object DbSettings {
|
object DbSettings {
|
||||||
|
|
||||||
val db by lazy {
|
val db by lazy {
|
||||||
Database.connect(
|
Database.connect(
|
||||||
url = "jdbc:postgresql://localhost:5432/presence",
|
url = "jdbc:postgresql://localhost:5432/presence",
|
||||||
user = "postgres",
|
user = "postgres",
|
||||||
password = "123"
|
password = "123"
|
||||||
)
|
)
|
||||||
|
transaction {
|
||||||
|
SchemaUtils.create(RoleIdTable)
|
||||||
|
SchemaUtils.create(UserUuidTable)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun <T> query(block: () -> Unit): T =
|
suspend fun <T> query(block: () -> T): T =
|
||||||
newSuspendedTransaction { block() }
|
newSuspendedTransaction { block() }
|
||||||
|
|
||||||
}
|
}
|
@ -7,6 +7,7 @@ import java.util.UUID
|
|||||||
|
|
||||||
interface UserRepository {
|
interface UserRepository {
|
||||||
suspend fun getUserByUuid(userUuid: UUID): User?
|
suspend fun getUserByUuid(userUuid: UUID): User?
|
||||||
|
suspend fun getUserByLogin(userLogin: String): User?
|
||||||
suspend fun removeUserByUuid(userUuid: UUID): Boolean
|
suspend fun removeUserByUuid(userUuid: UUID): Boolean
|
||||||
suspend fun addUser(userCreateRequest: UserCreateRequest): User
|
suspend fun addUser(userCreateRequest: UserCreateRequest): User
|
||||||
suspend fun getAllUsers(): List<User>
|
suspend fun getAllUsers(): List<User>
|
||||||
|
@ -24,6 +24,14 @@ class UserRepositoryImpl(private val database: DbSettings): UserRepository {
|
|||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getUserByLogin(userLogin: String): User? = database.query {
|
||||||
|
(UserUuidTable innerJoin RoleIdTable).selectAll().where {
|
||||||
|
UserUuidTable.login eq userLogin
|
||||||
|
}
|
||||||
|
.map(::resultRowToUserWithJoinRole)
|
||||||
|
.firstOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun removeUserByUuid(userUuid: UUID): Boolean = database.query{
|
override suspend fun removeUserByUuid(userUuid: UUID): Boolean = database.query{
|
||||||
val result = UserUuidTable.deleteWhere {
|
val result = UserUuidTable.deleteWhere {
|
||||||
UserUuidTable.id eq userUuid
|
UserUuidTable.id eq userUuid
|
||||||
@ -35,7 +43,7 @@ class UserRepositoryImpl(private val database: DbSettings): UserRepository {
|
|||||||
val result = UserUuidTable.insertReturning {
|
val result = UserUuidTable.insertReturning {
|
||||||
it[password] = userCreateRequest.password
|
it[password] = userCreateRequest.password
|
||||||
it[login] = userCreateRequest.login
|
it[login] = userCreateRequest.login
|
||||||
it[role] = userCreateRequest.role.id
|
it[role] = userCreateRequest.roleId
|
||||||
}
|
}
|
||||||
resultRowToUser(result.first())
|
resultRowToUser(result.first())
|
||||||
}
|
}
|
||||||
|
13
src/main/kotlin/com/college/di/DI.kt
Normal file
13
src/main/kotlin/com/college/di/DI.kt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package com.college.di
|
||||||
|
|
||||||
|
import com.college.data.DbSettings
|
||||||
|
import com.college.data.repositorty.user.UserRepository
|
||||||
|
import com.college.data.repositorty.user.UserRepositoryImpl
|
||||||
|
import com.college.domain.usecase.UserUseCase
|
||||||
|
import org.koin.dsl.module
|
||||||
|
|
||||||
|
val myModule = module {
|
||||||
|
single { DbSettings }
|
||||||
|
single<UserRepository> { UserRepositoryImpl(get()) }
|
||||||
|
single { UserUseCase(get()) }
|
||||||
|
}
|
@ -5,5 +5,5 @@ import com.college.domain.model.Role
|
|||||||
data class UserCreateRequest(
|
data class UserCreateRequest(
|
||||||
val login:String,
|
val login:String,
|
||||||
val password:String,
|
val password:String,
|
||||||
val role: Role
|
val roleId: Int
|
||||||
)
|
)
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
package com.college.domain.request.user
|
||||||
|
|
||||||
|
data class UserFindRequest(val login:String)
|
@ -1,7 +1,16 @@
|
|||||||
package com.college.domain.usecase
|
package com.college.domain.usecase
|
||||||
|
|
||||||
import com.college.data.repositorty.user.UserRepository
|
import com.college.data.repositorty.user.UserRepository
|
||||||
|
import com.college.domain.model.User
|
||||||
|
import com.college.domain.request.user.UserCreateRequest
|
||||||
|
import com.college.domain.request.user.UserFindRequest
|
||||||
|
import io.ktor.server.plugins.*
|
||||||
|
|
||||||
class UserUseCase(private val userRepository: UserRepository) {
|
class UserUseCase(private val userRepository: UserRepository) {
|
||||||
fun re
|
suspend fun register(userCreateRequest: UserCreateRequest){
|
||||||
|
userRepository.addUser(userCreateRequest)
|
||||||
|
}
|
||||||
|
suspend fun getUserByLogin(userFindRequest: UserFindRequest):User{
|
||||||
|
return userRepository.getUserByLogin(userFindRequest.login) ?: throw NotFoundException()
|
||||||
|
}
|
||||||
}
|
}
|
@ -8,3 +8,6 @@ postgres:
|
|||||||
url: "jdbc:postgresql://localhost:5432/presence"
|
url: "jdbc:postgresql://localhost:5432/presence"
|
||||||
user: "postgres"
|
user: "postgres"
|
||||||
password: "123"
|
password: "123"
|
||||||
|
jwt:
|
||||||
|
secret: "test"
|
||||||
|
issuer: "http://0.0.0.0:8080/"
|
Loading…
Reference in New Issue
Block a user