make auth work
This commit is contained in:
parent
b0042d2e6b
commit
1e3d9aa1f1
9
api.http
9
api.http
@ -1,17 +1,19 @@
|
||||
### create row
|
||||
POST http://localhost:9001/api/vehicle
|
||||
Content-Type: application/json
|
||||
Authorization: set-auth-token
|
||||
|
||||
{
|
||||
"data": {
|
||||
"number": "KA03HD6064"
|
||||
"number": "KA01MU0556"
|
||||
},
|
||||
"uniqueIdentifier": "KA03HD6064"
|
||||
"uniqueIdentifier": "KA01MU0556"
|
||||
}
|
||||
|
||||
### create row, with autogenerated identifier
|
||||
POST http://localhost:9001/api/log
|
||||
Content-Type: application/json
|
||||
Authorization: set-auth-token
|
||||
|
||||
{
|
||||
"data": {
|
||||
@ -26,6 +28,7 @@ GET http://localhost:9001/api/vehicle/KA03HD6064
|
||||
### query row
|
||||
POST http://localhost:9001/api/vehicle/query
|
||||
Content-Type: application/json
|
||||
Authorization: set-auth-token
|
||||
|
||||
{
|
||||
"sql": "select sys_pk, tenant_id, deleted_on, deleted_by, deleted, version, created_at, modified_at, created_by, modified_by, data, tags, comments, unique_identifier, entity_name from data_model where data ->> 'number' = :number",
|
||||
@ -37,6 +40,7 @@ Content-Type: application/json
|
||||
### update field
|
||||
PATCH http://localhost:9001/api/vehicle/KA03HD6064
|
||||
Content-Type: application/json
|
||||
Authorization: set-auth-token
|
||||
|
||||
{
|
||||
"key": "ownerName",
|
||||
@ -47,6 +51,7 @@ Content-Type: application/json
|
||||
### upate a row
|
||||
PUT http://localhost:9001/api/vehicle/KA03HD6064
|
||||
Content-Type: application/json
|
||||
Authorization: set-auth-token
|
||||
|
||||
{
|
||||
"number": "KA03HD6064",
|
||||
|
||||
@ -4,4 +4,9 @@ app.cors.hosts=www.readymixerp.com,app.readymixerp.com
|
||||
app.db.user=postgres
|
||||
app.db.pass=postgres
|
||||
app.db.url=jdbc:postgresql://192.168.64.6/modules_app
|
||||
app.db.run_migration=true
|
||||
app.db.run_migration=true
|
||||
app.iam.url=https://auth.compegence.com
|
||||
app.iam.realm=forewarn-dev
|
||||
app.iam.client=forewarn
|
||||
app.iam.client_redirect_uri=http://localhost:9001/auth/code
|
||||
app.cache.redis_uri=redis://127.0.0.1:6379/0
|
||||
@ -26,7 +26,9 @@ dependencies {
|
||||
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.+")
|
||||
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.+")
|
||||
|
||||
implementation("org.bitbucket.b_c:jose4j:0.9.3")
|
||||
implementation("org.slf4j:slf4j-simple:2.0.7")
|
||||
implementation("redis.clients:jedis:5.0.2")
|
||||
api ("net.cactusthorn.config:config-core:0.81")
|
||||
kapt("net.cactusthorn.config:config-compiler:0.81")
|
||||
kapt("io.ebean:kotlin-querybean-generator:13.23.2")
|
||||
|
||||
@ -1,7 +1,12 @@
|
||||
package com.restapi
|
||||
|
||||
import AuthTokenResponse
|
||||
import com.fasterxml.jackson.databind.JsonMappingException
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.restapi.config.AppConfig.Companion.appConfig
|
||||
import com.restapi.config.Auth
|
||||
import com.restapi.config.Auth.getAuthEndpoint
|
||||
import com.restapi.config.AuthEndpoint
|
||||
import com.restapi.domain.DataModel
|
||||
import com.restapi.domain.DataNotFoundException
|
||||
import com.restapi.domain.Session
|
||||
@ -9,6 +14,9 @@ import com.restapi.domain.Session.creatSeq
|
||||
import com.restapi.domain.Session.database
|
||||
import com.restapi.domain.Session.findByEntityAndId
|
||||
import com.restapi.domain.Session.nextUniqId
|
||||
import com.restapi.domain.Session.objectMapper
|
||||
import com.restapi.domain.Session.redis
|
||||
import com.restapi.domain.Session.setAuthorizedUser
|
||||
import io.ebean.CallableSql
|
||||
import io.ebean.DuplicateKeyException
|
||||
import io.ebean.RawSqlBuilder
|
||||
@ -17,10 +25,18 @@ import io.javalin.apibuilder.ApiBuilder.*
|
||||
import io.javalin.http.*
|
||||
import io.javalin.json.JavalinJackson
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.net.URI
|
||||
import java.net.URLEncoder
|
||||
import java.net.http.HttpClient
|
||||
import java.net.http.HttpRequest
|
||||
import java.net.http.HttpRequest.BodyPublishers
|
||||
import java.net.http.HttpResponse.BodyHandlers
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.time.LocalDateTime
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val logger = LoggerFactory.getLogger("api")
|
||||
|
||||
Javalin
|
||||
.create { cfg ->
|
||||
cfg.http.generateEtags = true
|
||||
@ -39,7 +55,47 @@ fun main(args: Array<String>) {
|
||||
cfg.jsonMapper(JavalinJackson(Session.objectMapper))
|
||||
}
|
||||
.routes {
|
||||
before("/*") { ctx ->
|
||||
|
||||
path("/auth") {
|
||||
get("/init") {
|
||||
val endpoint = getAuthEndpoint().authorizationEndpoint
|
||||
|
||||
val redirectUrl =
|
||||
"$endpoint?response_type=code&client_id=${appConfig.iamClient()}&redirect_uri=${appConfig.iamClientRedirectUri()}&scope=profile&state=1234zyx"
|
||||
it.redirect(redirectUrl)
|
||||
}
|
||||
get("/code") {
|
||||
|
||||
val code = it.queryParam("code") ?: throw BadRequestResponse("not proper")
|
||||
|
||||
val ep = getAuthEndpoint().tokenEndpoint
|
||||
val client = HttpClient.newHttpClient()
|
||||
val req = HttpRequest.newBuilder()
|
||||
.uri(URI.create(ep))
|
||||
.POST(
|
||||
BodyPublishers.ofString(
|
||||
getFormDataAsString(
|
||||
mapOf(
|
||||
"code" to code,
|
||||
"redirect_uri" to appConfig.iamClientRedirectUri(),
|
||||
"client_id" to appConfig.iamClient(),
|
||||
"grant_type" to "authorization_code",
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.build()
|
||||
val message = client.send(req, BodyHandlers.ofString()).body()
|
||||
val atResponse = objectMapper.readValue<AuthTokenResponse>(message)
|
||||
|
||||
//lets keep auth token refreshed
|
||||
redis.sadd("AUTH_TOKEN", message)
|
||||
it.result(atResponse.accessToken).contentType(ContentType.TEXT_PLAIN)
|
||||
|
||||
}
|
||||
}
|
||||
before("/api/*") { ctx ->
|
||||
//validate, auth token
|
||||
|
||||
//allow only alpha, numeric, hypen, underscore, dot in paths
|
||||
@ -51,6 +107,12 @@ fun main(args: Array<String>) {
|
||||
throw IllegalArgumentException()
|
||||
}
|
||||
}
|
||||
|
||||
val at = ctx.header("Authorization")?.replace("Bearer ", "")?.replace("Bearer: ", "")?.trim()
|
||||
?: throw UnauthorizedResponse()
|
||||
val pt = Auth.parseAuthToken(authToken = at)
|
||||
|
||||
setAuthorizedUser(pt)
|
||||
}
|
||||
path("/api") {
|
||||
post("/execute/{name}") {
|
||||
@ -174,4 +236,17 @@ data class Query(
|
||||
val params: Map<String, Any>
|
||||
)
|
||||
|
||||
private fun getFormDataAsString(formData: Map<String, String>): String {
|
||||
val formBodyBuilder = StringBuilder()
|
||||
for ((key, value) in formData) {
|
||||
if (formBodyBuilder.length > 0) {
|
||||
formBodyBuilder.append("&")
|
||||
}
|
||||
formBodyBuilder.append(URLEncoder.encode(key, StandardCharsets.UTF_8))
|
||||
formBodyBuilder.append("=")
|
||||
formBodyBuilder.append(URLEncoder.encode(value, StandardCharsets.UTF_8))
|
||||
}
|
||||
return formBodyBuilder.toString()
|
||||
}
|
||||
|
||||
data class PatchValue(val key: String, val value: Any)
|
||||
@ -5,6 +5,7 @@ import net.cactusthorn.config.core.Default
|
||||
import net.cactusthorn.config.core.Key
|
||||
import net.cactusthorn.config.core.factory.ConfigFactory
|
||||
import net.cactusthorn.config.core.loader.LoadStrategy
|
||||
import java.util.Optional
|
||||
|
||||
const val INITIAL_ROLES_JSON = """{
|
||||
"roles": []
|
||||
@ -41,6 +42,26 @@ interface AppConfig {
|
||||
@Key("app.db.run_migration")
|
||||
fun dbRunMigration(): Boolean
|
||||
|
||||
@Key("app.iam.url")
|
||||
fun iamUrl(): String
|
||||
|
||||
@Key("app.iam.realm")
|
||||
fun iamRealm(): String
|
||||
|
||||
@Key("app.iam.client")
|
||||
fun iamClient(): String
|
||||
|
||||
@Key("app.iam.client_redirect_uri")
|
||||
fun iamClientRedirectUri(): String
|
||||
|
||||
@Key("app.iam.client_id")
|
||||
fun iamClientId(): Optional<String>
|
||||
|
||||
@Key("app.iam.client_secret")
|
||||
fun iamClientSecret(): Optional<String>
|
||||
|
||||
@Key("app.cache.redis_uri")
|
||||
fun redisUri(): Optional<String>
|
||||
|
||||
companion object {
|
||||
val appConfig: AppConfig = ConfigFactory.builder().build().create(AppConfig::class.java)
|
||||
|
||||
72
src/main/kotlin/com/restapi/config/Auth.kt
Normal file
72
src/main/kotlin/com/restapi/config/Auth.kt
Normal file
@ -0,0 +1,72 @@
|
||||
package com.restapi.config
|
||||
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.restapi.config.AppConfig.Companion.appConfig
|
||||
import com.restapi.domain.Session
|
||||
import com.restapi.domain.Session.objectMapper
|
||||
import io.javalin.http.Context
|
||||
import io.javalin.http.HandlerType
|
||||
import io.javalin.http.UnauthorizedResponse
|
||||
import org.jose4j.jwk.HttpsJwks
|
||||
import org.jose4j.jwt.consumer.ErrorCodes
|
||||
import org.jose4j.jwt.consumer.InvalidJwtException
|
||||
import org.jose4j.jwt.consumer.JwtConsumerBuilder
|
||||
import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.net.URI
|
||||
import java.net.http.HttpClient
|
||||
import java.net.http.HttpRequest
|
||||
import java.net.http.HttpResponse
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.function.Function
|
||||
|
||||
object Auth {
|
||||
|
||||
|
||||
private val authCache = ConcurrentHashMap<String, AuthEndpoint>()
|
||||
|
||||
fun getAuthEndpoint(): AuthEndpoint {
|
||||
return authCache.computeIfAbsent("AUTH") {
|
||||
val wellKnown =
|
||||
"${appConfig.iamUrl()}/realms/${appConfig.iamRealm()}/.well-known/openid-configuration"
|
||||
val client = HttpClient.newHttpClient()
|
||||
|
||||
val req = HttpRequest.newBuilder()
|
||||
.uri(URI.create(wellKnown))
|
||||
.GET().build()
|
||||
|
||||
objectMapper.readValue<AuthEndpoint>(
|
||||
client.send(req, HttpResponse.BodyHandlers.ofString()).body()
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private val jwtConsumer = JwtConsumerBuilder()
|
||||
.setRequireExpirationTime()
|
||||
.setAllowedClockSkewInSeconds(30)
|
||||
.setRequireSubject()
|
||||
.setExpectedIssuer(getAuthEndpoint().issuer)
|
||||
.setExpectedAudience("account")
|
||||
.setVerificationKeyResolver(HttpsJwksVerificationKeyResolver(HttpsJwks(getAuthEndpoint().jwksUri)))
|
||||
.build()
|
||||
|
||||
|
||||
fun parseAuthToken(authToken: String): AuthUser {
|
||||
|
||||
// Validate the JWT and process it to the Claims
|
||||
val jwtClaims = jwtConsumer.process(authToken)
|
||||
val userId = jwtClaims.jwtClaims.claimsMap["preferred_username"] as String
|
||||
val tenant = jwtClaims.jwtClaims.claimsMap["tenant"] as String
|
||||
val roles = ((jwtClaims.jwtClaims.claimsMap["realm_access"] as Map<String, Any>)["roles"]) as List<String>
|
||||
|
||||
return AuthUser(
|
||||
userName = userId,
|
||||
tenant = tenant,
|
||||
roles = roles
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
data class AuthUser(val userName: String, val tenant: String, val roles: List<String>)
|
||||
132
src/main/kotlin/com/restapi/config/AuthEndpoint.kt
Normal file
132
src/main/kotlin/com/restapi/config/AuthEndpoint.kt
Normal file
@ -0,0 +1,132 @@
|
||||
package com.restapi.config
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
|
||||
data class AuthEndpoint(
|
||||
@JsonProperty("acr_values_supported")
|
||||
val acrValuesSupported: List<String>,
|
||||
@JsonProperty("authorization_encryption_alg_values_supported")
|
||||
val authorizationEncryptionAlgValuesSupported: List<String>,
|
||||
@JsonProperty("authorization_encryption_enc_values_supported")
|
||||
val authorizationEncryptionEncValuesSupported: List<String>,
|
||||
@JsonProperty("authorization_endpoint")
|
||||
val authorizationEndpoint: String,
|
||||
@JsonProperty("authorization_signing_alg_values_supported")
|
||||
val authorizationSigningAlgValuesSupported: List<String>,
|
||||
@JsonProperty("backchannel_authentication_endpoint")
|
||||
val backchannelAuthenticationEndpoint: String,
|
||||
@JsonProperty("backchannel_authentication_request_signing_alg_values_supported")
|
||||
val backchannelAuthenticationRequestSigningAlgValuesSupported: List<String>,
|
||||
@JsonProperty("backchannel_logout_session_supported")
|
||||
val backchannelLogoutSessionSupported: Boolean,
|
||||
@JsonProperty("backchannel_logout_supported")
|
||||
val backchannelLogoutSupported: Boolean,
|
||||
@JsonProperty("backchannel_token_delivery_modes_supported")
|
||||
val backchannelTokenDeliveryModesSupported: List<String>,
|
||||
@JsonProperty("check_session_iframe")
|
||||
val checkSessionIframe: String,
|
||||
@JsonProperty("claim_types_supported")
|
||||
val claimTypesSupported: List<String>,
|
||||
@JsonProperty("claims_parameter_supported")
|
||||
val claimsParameterSupported: Boolean,
|
||||
@JsonProperty("claims_supported")
|
||||
val claimsSupported: List<String>,
|
||||
@JsonProperty("code_challenge_methods_supported")
|
||||
val codeChallengeMethodsSupported: List<String>,
|
||||
@JsonProperty("device_authorization_endpoint")
|
||||
val deviceAuthorizationEndpoint: String,
|
||||
@JsonProperty("end_session_endpoint")
|
||||
val endSessionEndpoint: String,
|
||||
@JsonProperty("frontchannel_logout_session_supported")
|
||||
val frontchannelLogoutSessionSupported: Boolean,
|
||||
@JsonProperty("frontchannel_logout_supported")
|
||||
val frontchannelLogoutSupported: Boolean,
|
||||
@JsonProperty("grant_types_supported")
|
||||
val grantTypesSupported: List<String>,
|
||||
@JsonProperty("id_token_encryption_alg_values_supported")
|
||||
val idTokenEncryptionAlgValuesSupported: List<String>,
|
||||
@JsonProperty("id_token_encryption_enc_values_supported")
|
||||
val idTokenEncryptionEncValuesSupported: List<String>,
|
||||
@JsonProperty("id_token_signing_alg_values_supported")
|
||||
val idTokenSigningAlgValuesSupported: List<String>,
|
||||
@JsonProperty("introspection_endpoint")
|
||||
val introspectionEndpoint: String,
|
||||
@JsonProperty("introspection_endpoint_auth_methods_supported")
|
||||
val introspectionEndpointAuthMethodsSupported: List<String>,
|
||||
@JsonProperty("introspection_endpoint_auth_signing_alg_values_supported")
|
||||
val introspectionEndpointAuthSigningAlgValuesSupported: List<String>,
|
||||
@JsonProperty("issuer")
|
||||
val issuer: String,
|
||||
@JsonProperty("jwks_uri")
|
||||
val jwksUri: String,
|
||||
@JsonProperty("mtls_endpoint_aliases")
|
||||
val mtlsEndpointAliases: MtlsEndpointAliases,
|
||||
@JsonProperty("pushed_authorization_request_endpoint")
|
||||
val pushedAuthorizationRequestEndpoint: String,
|
||||
@JsonProperty("registration_endpoint")
|
||||
val registrationEndpoint: String,
|
||||
@JsonProperty("request_object_encryption_alg_values_supported")
|
||||
val requestObjectEncryptionAlgValuesSupported: List<String>,
|
||||
@JsonProperty("request_object_encryption_enc_values_supported")
|
||||
val requestObjectEncryptionEncValuesSupported: List<String>,
|
||||
@JsonProperty("request_object_signing_alg_values_supported")
|
||||
val requestObjectSigningAlgValuesSupported: List<String>,
|
||||
@JsonProperty("request_parameter_supported")
|
||||
val requestParameterSupported: Boolean,
|
||||
@JsonProperty("request_uri_parameter_supported")
|
||||
val requestUriParameterSupported: Boolean,
|
||||
@JsonProperty("require_pushed_authorization_requests")
|
||||
val requirePushedAuthorizationRequests: Boolean,
|
||||
@JsonProperty("require_request_uri_registration")
|
||||
val requireRequestUriRegistration: Boolean,
|
||||
@JsonProperty("response_modes_supported")
|
||||
val responseModesSupported: List<String>,
|
||||
@JsonProperty("response_types_supported")
|
||||
val responseTypesSupported: List<String>,
|
||||
@JsonProperty("revocation_endpoint")
|
||||
val revocationEndpoint: String,
|
||||
@JsonProperty("revocation_endpoint_auth_methods_supported")
|
||||
val revocationEndpointAuthMethodsSupported: List<String>,
|
||||
@JsonProperty("revocation_endpoint_auth_signing_alg_values_supported")
|
||||
val revocationEndpointAuthSigningAlgValuesSupported: List<String>,
|
||||
@JsonProperty("scopes_supported")
|
||||
val scopesSupported: List<String>,
|
||||
@JsonProperty("subject_types_supported")
|
||||
val subjectTypesSupported: List<String>,
|
||||
@JsonProperty("tls_client_certificate_bound_access_tokens")
|
||||
val tlsClientCertificateBoundAccessTokens: Boolean,
|
||||
@JsonProperty("token_endpoint")
|
||||
val tokenEndpoint: String,
|
||||
@JsonProperty("token_endpoint_auth_methods_supported")
|
||||
val tokenEndpointAuthMethodsSupported: List<String>,
|
||||
@JsonProperty("token_endpoint_auth_signing_alg_values_supported")
|
||||
val tokenEndpointAuthSigningAlgValuesSupported: List<String>,
|
||||
@JsonProperty("userinfo_encryption_alg_values_supported")
|
||||
val userinfoEncryptionAlgValuesSupported: List<String>,
|
||||
@JsonProperty("userinfo_encryption_enc_values_supported")
|
||||
val userinfoEncryptionEncValuesSupported: List<String>,
|
||||
@JsonProperty("userinfo_endpoint")
|
||||
val userinfoEndpoint: String,
|
||||
@JsonProperty("userinfo_signing_alg_values_supported")
|
||||
val userinfoSigningAlgValuesSupported: List<String>
|
||||
) {
|
||||
data class MtlsEndpointAliases(
|
||||
@JsonProperty("backchannel_authentication_endpoint")
|
||||
val backchannelAuthenticationEndpoint: String,
|
||||
@JsonProperty("device_authorization_endpoint")
|
||||
val deviceAuthorizationEndpoint: String,
|
||||
@JsonProperty("introspection_endpoint")
|
||||
val introspectionEndpoint: String,
|
||||
@JsonProperty("pushed_authorization_request_endpoint")
|
||||
val pushedAuthorizationRequestEndpoint: String,
|
||||
@JsonProperty("registration_endpoint")
|
||||
val registrationEndpoint: String,
|
||||
@JsonProperty("revocation_endpoint")
|
||||
val revocationEndpoint: String,
|
||||
@JsonProperty("token_endpoint")
|
||||
val tokenEndpoint: String,
|
||||
@JsonProperty("userinfo_endpoint")
|
||||
val userinfoEndpoint: String
|
||||
)
|
||||
}
|
||||
23
src/main/kotlin/com/restapi/config/AuthTokenResponse.kt
Normal file
23
src/main/kotlin/com/restapi/config/AuthTokenResponse.kt
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty
|
||||
import java.time.LocalDateTime
|
||||
|
||||
data class AuthTokenResponse(
|
||||
@JsonProperty("access_token")
|
||||
val accessToken: String,
|
||||
@JsonProperty("expires_in")
|
||||
val expiresIn: Int,
|
||||
@JsonProperty("not-before-policy")
|
||||
val notBeforePolicy: Int,
|
||||
@JsonProperty("refresh_expires_in")
|
||||
val refreshExpiresIn: Int,
|
||||
@JsonProperty("refresh_token")
|
||||
val refreshToken: String,
|
||||
@JsonProperty("scope")
|
||||
val scope: String,
|
||||
@JsonProperty("session_state")
|
||||
val sessionState: String,
|
||||
@JsonProperty("token_type")
|
||||
val tokenType: String,
|
||||
val createdAt: LocalDateTime = LocalDateTime.now()
|
||||
)
|
||||
@ -6,27 +6,26 @@ import com.fasterxml.jackson.databind.SerializationFeature
|
||||
import com.fasterxml.jackson.databind.module.SimpleModule
|
||||
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
|
||||
import com.restapi.config.AppConfig.Companion.appConfig
|
||||
import com.restapi.config.AuthUser
|
||||
import io.ebean.Database
|
||||
import io.ebean.DatabaseFactory
|
||||
import io.ebean.config.CurrentTenantProvider
|
||||
import io.ebean.config.CurrentUserProvider
|
||||
import io.ebean.config.DatabaseConfig
|
||||
import io.ebean.config.TenantMode
|
||||
import redis.clients.jedis.JedisPooled
|
||||
import java.util.*
|
||||
|
||||
data class CurrentUser(
|
||||
val anon: Boolean = true,
|
||||
val userId: String = "",
|
||||
val tenantId: String = ""
|
||||
)
|
||||
import kotlin.jvm.optionals.getOrDefault
|
||||
|
||||
|
||||
object Session {
|
||||
private val currentUser = object : ThreadLocal<CurrentUser>() {
|
||||
override fun initialValue(): CurrentUser {
|
||||
return CurrentUser()
|
||||
private val currentUser = object : ThreadLocal<AuthUser>() {
|
||||
override fun initialValue(): AuthUser {
|
||||
return AuthUser("", "", emptyList<String>())
|
||||
}
|
||||
}
|
||||
fun setAuthorizedUser(a: AuthUser) = currentUser.set(a)
|
||||
|
||||
private val sc = DatabaseConfig().apply {
|
||||
loadFromProperties(Properties().apply {
|
||||
setProperty("datasource.db.username", appConfig.dbUser())
|
||||
@ -35,8 +34,8 @@ object Session {
|
||||
setProperty("ebean.migration.run", appConfig.dbRunMigration().toString())
|
||||
})
|
||||
tenantMode = TenantMode.PARTITION
|
||||
currentTenantProvider = CurrentTenantProvider { currentUser.get().tenantId }
|
||||
currentUserProvider = CurrentUserProvider { currentUser.get().userId }
|
||||
currentTenantProvider = CurrentTenantProvider { currentUser.get().tenant }
|
||||
currentUserProvider = CurrentUserProvider { currentUser.get().userName }
|
||||
}
|
||||
|
||||
val database: Database = DatabaseFactory.create(sc)
|
||||
@ -46,7 +45,7 @@ object Session {
|
||||
findAndRegisterModules()
|
||||
}
|
||||
|
||||
fun currentUser() = currentUser.get().userId
|
||||
fun currentUser() = currentUser.get().userName
|
||||
|
||||
fun Database.findByEntityAndId(entity: String, id: String): DataModel {
|
||||
return find(DataModel::class.java)
|
||||
@ -68,6 +67,8 @@ object Session {
|
||||
return String.format("%s-%s", entity, "$s".padStart(10, '0'))
|
||||
}
|
||||
|
||||
val redis = JedisPooled(appConfig.redisUri().getOrDefault("redis://localhost:6739/0"))
|
||||
|
||||
}
|
||||
|
||||
object DataNotFoundException : Exception() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user