init projects
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
package ru.shadowsparky.backend
|
||||
|
||||
import org.koin.core.annotation.ComponentScan
|
||||
import org.koin.core.annotation.Configuration
|
||||
import org.koin.core.annotation.Module
|
||||
|
||||
@Module
|
||||
@ComponentScan
|
||||
@Configuration
|
||||
class BackendCommon
|
||||
@@ -0,0 +1,11 @@
|
||||
package ru.shadowsparky.backend.data
|
||||
|
||||
import org.koin.core.annotation.Single
|
||||
|
||||
@Single
|
||||
class EnvFetcher {
|
||||
fun get(key: String, default: String = ""): String {
|
||||
val value = System.getenv(key)
|
||||
return value?.ifEmpty { default } ?: default
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package ru.shadowsparky.backend.data
|
||||
|
||||
import com.auth0.jwt.JWT
|
||||
import com.auth0.jwt.algorithms.Algorithm
|
||||
import org.koin.core.annotation.Single
|
||||
import ru.shadowsparky.backend.domain.JwtInfo
|
||||
import ru.shadowsparky.backend.domain.LOGIN_NAME
|
||||
import ru.shadowsparky.backend.domain.USER_ID_ARG
|
||||
import java.util.Date
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@Single
|
||||
class JwtPreparer(
|
||||
private val jwtInfo: JwtInfo,
|
||||
private val envFetcher: EnvFetcher
|
||||
) {
|
||||
private val tokenTimeInMinutes = envFetcher.get("JWT_DURATION", "30").toLong()
|
||||
fun prepare(
|
||||
login: String,
|
||||
userId: Long
|
||||
): String {
|
||||
val exp = Date(System.currentTimeMillis() + TimeUnit.MINUTES.toMillis(tokenTimeInMinutes))
|
||||
val token = JWT.create()
|
||||
.withAudience(jwtInfo.audience)
|
||||
.withIssuer(jwtInfo.issuer)
|
||||
.withClaim(LOGIN_NAME, login)
|
||||
.withClaim(USER_ID_ARG, userId)
|
||||
.withSubject(userId.toString())
|
||||
.withExpiresAt(exp)
|
||||
.sign(Algorithm.HMAC512(jwtInfo.secret))
|
||||
return token
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package ru.shadowsparky.backend.data
|
||||
|
||||
import org.koin.core.annotation.Single
|
||||
import org.slf4j.Logger
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
@Single
|
||||
class Logger {
|
||||
private val loggers = hashMapOf<String, Logger>()
|
||||
|
||||
fun info(tag: String, message: String) = obtainLogger(tag).info(message)
|
||||
fun debug(tag: String, message: String) = obtainLogger(tag).debug(message)
|
||||
fun error(tag: String, e: Exception) = obtainLogger(tag).error("error occurred", e)
|
||||
|
||||
private fun obtainLogger(tag: String): Logger {
|
||||
loggers[tag]?.let { return it }
|
||||
loggers[tag] = LoggerFactory.getLogger(tag)
|
||||
return loggers[tag]!!
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package ru.shadowsparky.backend.data
|
||||
|
||||
import org.koin.core.annotation.Single
|
||||
|
||||
@Single
|
||||
class StringFetcher {
|
||||
fun get(resource: StringResource): String {
|
||||
return resource.message
|
||||
}
|
||||
}
|
||||
|
||||
enum class StringResource(val message: String) {
|
||||
UNKNOWN_USER("Пользователь не найден или неверный пароль"),
|
||||
INVALID_PASSWORD("Вы ввели неверный пароль"),
|
||||
NO_CHANGES_PASS("Старый и новый пароль должны отличаться"),
|
||||
USER_BLOCKED("Пользователь заблокирован"),
|
||||
REG_BLOCKED("Регистрация недоступна. Доступ по приглашениям."),
|
||||
ALREADY_REGISTERED("Пользователь уже существует"),
|
||||
VIDEO_NOT_FOUND("Видео не найдено.")
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package ru.shadowsparky.backend.data
|
||||
|
||||
import com.auth0.jwt.JWT
|
||||
import com.auth0.jwt.algorithms.Algorithm
|
||||
import com.auth0.jwt.interfaces.DecodedJWT
|
||||
import org.koin.core.annotation.Factory
|
||||
import ru.shadowsparky.backend.domain.JwtInfo
|
||||
import ru.shadowsparky.backend.domain.LOGIN_NAME
|
||||
import ru.shadowsparky.backend.domain.LoginVerifier
|
||||
|
||||
@Factory
|
||||
class TokenVerifier(
|
||||
private val jwtInfo: JwtInfo,
|
||||
private val loginVerifier: LoginVerifier
|
||||
) {
|
||||
|
||||
val verifier = JWT.require(Algorithm.HMAC512(jwtInfo.secret))
|
||||
.withAudience(jwtInfo.audience)
|
||||
.withIssuer(jwtInfo.issuer)
|
||||
.build()
|
||||
|
||||
suspend fun verify(token: String): DecodedJWT {
|
||||
val jwt = verifier.verify(token)
|
||||
loginVerifier.verify(jwt.getClaim(LOGIN_NAME).asString())
|
||||
return jwt
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package ru.shadowsparky.backend.domain
|
||||
|
||||
data class JwtInfo(
|
||||
val secret: String,
|
||||
val issuer: String,
|
||||
val audience: String,
|
||||
val realm: String
|
||||
)
|
||||
@@ -0,0 +1,10 @@
|
||||
package ru.shadowsparky.backend.domain
|
||||
|
||||
interface LoginVerifier {
|
||||
suspend fun verify(login: String)
|
||||
}
|
||||
|
||||
const val LOGIN_NAME = "login"
|
||||
const val USER_ID_ARG = "user_id"
|
||||
|
||||
const val INVALID_TOKEN_MSG = "Был передан неправильный токен"
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package ru.shadowsparky.backend.domain
|
||||
|
||||
class VerifyTokenException(override val message: String?) : IllegalStateException()
|
||||
Reference in New Issue
Block a user