add plant integ
This commit is contained in:
parent
fc361e3133
commit
ce1f5f9b04
@ -18,6 +18,8 @@ app:
|
||||
client: rmc
|
||||
scripts:
|
||||
path: /Users/gowthaman.b/IdeaProjects/rmc_modules_api/src/main/resources/scripts
|
||||
integration:
|
||||
rmc: https://www.readymixerp.com
|
||||
security:
|
||||
enforce_role_restriction: 'true'
|
||||
private_key: |-
|
||||
|
||||
@ -9,6 +9,7 @@ import com.restapi.domain.DataNotFoundException
|
||||
import com.restapi.domain.ReminderLog
|
||||
import com.restapi.domain.Session.currentTenant
|
||||
import com.restapi.domain.Session.currentUser
|
||||
import com.restapi.domain.Session.currentUserPlants
|
||||
import com.restapi.domain.Session.objectMapper
|
||||
import com.restapi.domain.Session.setAuthorizedUser
|
||||
import com.restapi.domain.Session.signPayload
|
||||
@ -43,15 +44,13 @@ fun main(args: Array<String>) {
|
||||
|
||||
//ratelimit based on IP Only
|
||||
RateLimitUtil.keyFunction = { ctx -> ctx.header("X-Forwarded-For")?.split(",")?.get(0) ?: ctx.ip() }
|
||||
Javalin
|
||||
.create { cfg ->
|
||||
Javalin.create { cfg ->
|
||||
cfg.http.generateEtags = true
|
||||
if (appConfig.corsEnabled()) {
|
||||
cfg.plugins.enableCors { container ->
|
||||
container.add {
|
||||
it.allowHost(
|
||||
"http://localhost:5173",
|
||||
*appConfig.corsHosts().toTypedArray()
|
||||
"http://localhost:5173", *appConfig.corsHosts().toTypedArray()
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -60,8 +59,7 @@ fun main(args: Array<String>) {
|
||||
cfg.compression.gzipOnly()
|
||||
cfg.jsonMapper(JavalinJackson(objectMapper))
|
||||
cfg.accessManager(AppAccessManager())
|
||||
}
|
||||
.routes {
|
||||
}.routes {
|
||||
path("/auth") {
|
||||
|
||||
get("/endpoint", Auth::endPoint)
|
||||
@ -73,9 +71,7 @@ fun main(args: Array<String>) {
|
||||
before("/api/*") { ctx ->
|
||||
|
||||
NaiveRateLimit.requestPerTimeUnit(
|
||||
ctx,
|
||||
appConfig.rateLimit().getOrDefault(30),
|
||||
TimeUnit.MINUTES
|
||||
ctx, appConfig.rateLimit().getOrDefault(30), TimeUnit.MINUTES
|
||||
)
|
||||
|
||||
val authToken = ctx.getAuthHeader() ?: throw UnauthorizedResponse()
|
||||
@ -106,6 +102,9 @@ fun main(args: Array<String>) {
|
||||
}
|
||||
path("/api") {
|
||||
|
||||
get("/plants") {
|
||||
it.json(currentUserPlants())
|
||||
}
|
||||
post("/audit/{action}") {
|
||||
logger.warn("User ${currentUser()} of tenant ${currentTenant()} has performed ${it.pathParam("action")} @ ${LocalDateTime.now()}")
|
||||
it.json(mapOf("status" to true))
|
||||
@ -117,14 +116,10 @@ fun main(args: Array<String>) {
|
||||
post("/batch", VendorCtrl::createBatch, Roles(Role.Explicit("ROLE_VENDOR_CREATE")))
|
||||
get("/{id}", VendorCtrl::get, Roles(Role.Explicit("ROLE_VENDOR_VIEW", "ROLE_VENDOR_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
VendorCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_VENDOR_VIEW", "ROLE_VENDOR_CREATE"))
|
||||
"/getAll", VendorCtrl::getAll, Roles(Role.Explicit("ROLE_VENDOR_VIEW", "ROLE_VENDOR_CREATE"))
|
||||
)
|
||||
get(
|
||||
"quotes/{id}",
|
||||
VendorCtrl::getQuotes,
|
||||
Roles(Role.Explicit("ROLE_QUOTE_VIEW", "ROLE_QUOTE_CREATE", "ROLE_VENDOR_VIEW"))
|
||||
"quotes/{id}", VendorCtrl::getQuotes, Roles(Role.Explicit("ROLE_QUOTE_VIEW", "ROLE_QUOTE_CREATE", "ROLE_VENDOR_VIEW"))
|
||||
)
|
||||
get("pos/{id}", VendorCtrl::getPos, Roles(Role.Explicit("ROLE_PO_VIEW", "ROLE_PO_CREATE`")))
|
||||
put("/rate/{id}/{rating}", VendorCtrl::rate, Roles(Role.Explicit("ROLE_VENDOR_CREATE")))
|
||||
@ -134,59 +129,43 @@ fun main(args: Array<String>) {
|
||||
post("", IncomingInventoryCtrl::create, Roles(Role.Explicit("ROLE_INVENTORY_CREATE")))
|
||||
get("/next", IncomingInventoryCtrl::getNextNum, Roles(Role.Explicit("ROLE_INVENTORY_CREATE")))
|
||||
get(
|
||||
"/{id}",
|
||||
IncomingInventoryCtrl::get,
|
||||
Roles(Role.Explicit("ROLE_INVENTORY_VIEW", "ROLE_INVENTORY_CREATE"))
|
||||
"/{id}", IncomingInventoryCtrl::get, Roles(Role.Explicit("ROLE_INVENTORY_VIEW", "ROLE_INVENTORY_CREATE"))
|
||||
)
|
||||
put("/{id}", IncomingInventoryCtrl::update, Roles(Role.Explicit("ROLE_INVENTORY_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
IncomingInventoryCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_INVENTORY_CREATE", "ROLE_INVENTORY_VIEW"))
|
||||
"/getAll", IncomingInventoryCtrl::getAll, Roles(Role.Explicit("ROLE_INVENTORY_CREATE", "ROLE_INVENTORY_VIEW"))
|
||||
)
|
||||
}
|
||||
path("/outgoing") {
|
||||
post("", OutgoingInventoryCtrl::create, Roles(Role.Explicit("ROLE_INVENTORY_CREATE")))
|
||||
get("/next", OutgoingInventoryCtrl::getNextNum, Roles(Role.Explicit("ROLE_INVENTORY_CREATE")))
|
||||
get(
|
||||
"/{id}",
|
||||
OutgoingInventoryCtrl::get,
|
||||
Roles(Role.Explicit("ROLE_INVENTORY_VIEW", "ROLE_INVENTORY_CREATE"))
|
||||
"/{id}", OutgoingInventoryCtrl::get, Roles(Role.Explicit("ROLE_INVENTORY_VIEW", "ROLE_INVENTORY_CREATE"))
|
||||
)
|
||||
put("/{id}", OutgoingInventoryCtrl::update, Roles(Role.Explicit("ROLE_INVENTORY_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
OutgoingInventoryCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_INVENTORY_CREATE", "ROLE_INVENTORY_VIEW"))
|
||||
"/getAll", OutgoingInventoryCtrl::getAll, Roles(Role.Explicit("ROLE_INVENTORY_CREATE", "ROLE_INVENTORY_VIEW"))
|
||||
)
|
||||
}
|
||||
path("/invoice") {
|
||||
post("", InvoiceCtrl::create, Roles(Role.Explicit("ROLE_INVOICE_CREATE")))
|
||||
get("/next", InvoiceCtrl::getNextNum, Roles(Role.Explicit("ROLE_INVOICE_CREATE")))
|
||||
get(
|
||||
"/{id}",
|
||||
InvoiceCtrl::get,
|
||||
Roles(Role.Explicit("ROLE_INVOICE_VIEW", "ROLE_INVOICE_CREATE"))
|
||||
"/{id}", InvoiceCtrl::get, Roles(Role.Explicit("ROLE_INVOICE_VIEW", "ROLE_INVOICE_CREATE"))
|
||||
)
|
||||
put("/{id}", InvoiceCtrl::update, Roles(Role.Explicit("ROLE_INVOICE_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
InvoiceCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_INVOICE_CREATE", "ROLE_INVOICE_VIEW"))
|
||||
"/getAll", InvoiceCtrl::getAll, Roles(Role.Explicit("ROLE_INVOICE_CREATE", "ROLE_INVOICE_VIEW"))
|
||||
)
|
||||
}
|
||||
path("/payment") {
|
||||
post("", PaymentCtrl::create, Roles(Role.Explicit("ROLE_PAYMENT_CREATE")))
|
||||
get(
|
||||
"/{id}",
|
||||
PaymentCtrl::get,
|
||||
Roles(Role.Explicit("ROLE_PAYMENT_VIEW", "ROLE_PAYMENT_CREATE"))
|
||||
"/{id}", PaymentCtrl::get, Roles(Role.Explicit("ROLE_PAYMENT_VIEW", "ROLE_PAYMENT_CREATE"))
|
||||
)
|
||||
put("/{id}", PaymentCtrl::update, Roles(Role.Explicit("ROLE_PAYMENT_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
PaymentCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_PAYMENT_CREATE", "ROLE_PAYMENT_VIEW"))
|
||||
"/getAll", PaymentCtrl::getAll, Roles(Role.Explicit("ROLE_PAYMENT_CREATE", "ROLE_PAYMENT_VIEW"))
|
||||
)
|
||||
delete("/{id}", PaymentCtrl::delete, Roles(Role.Explicit("ROLE_PAYMENT_CREATE")))
|
||||
}
|
||||
@ -194,88 +173,62 @@ fun main(args: Array<String>) {
|
||||
|
||||
post("", FleetCtrl::create, Roles(Role.Explicit("ROLE_FLEET_CREATE")))
|
||||
get(
|
||||
"/{id}",
|
||||
FleetCtrl::get,
|
||||
Roles(Role.Explicit("ROLE_FLEET_VIEW", "ROLE_FLEET_CREATE"))
|
||||
"/{id}", FleetCtrl::get, Roles(Role.Explicit("ROLE_FLEET_VIEW", "ROLE_FLEET_CREATE"))
|
||||
)
|
||||
put("/{id}", FleetCtrl::update, Roles(Role.Explicit("ROLE_FLEET_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
FleetCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_FLEET_CREATE", "ROLE_FLEET_VIEW"))
|
||||
"/getAll", FleetCtrl::getAll, Roles(Role.Explicit("ROLE_FLEET_CREATE", "ROLE_FLEET_VIEW"))
|
||||
)
|
||||
delete("/{id}", FleetCtrl::delete, Roles(Role.Explicit("ROLE_FLEET_CREATE")))
|
||||
}
|
||||
path("/renewal") {
|
||||
post("", RenewalCtrl::create, Roles(Role.Explicit("ROLE_FLEET_CREATE")))
|
||||
get(
|
||||
"/{id}",
|
||||
RenewalCtrl::get,
|
||||
Roles(Role.Explicit("ROLE_FLEET_VIEW", "ROLE_FLEET_CREATE"))
|
||||
"/{id}", RenewalCtrl::get, Roles(Role.Explicit("ROLE_FLEET_VIEW", "ROLE_FLEET_CREATE"))
|
||||
)
|
||||
put("/{id}", RenewalCtrl::update, Roles(Role.Explicit("ROLE_FLEET_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
RenewalCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_FLEET_CREATE", "ROLE_FLEET_VIEW"))
|
||||
"/getAll", RenewalCtrl::getAll, Roles(Role.Explicit("ROLE_FLEET_CREATE", "ROLE_FLEET_VIEW"))
|
||||
)
|
||||
delete("/{id}", RenewalCtrl::delete, Roles(Role.Explicit("ROLE_FLEET_CREATE")))
|
||||
}
|
||||
path("/reminder") {
|
||||
post("", ReminderCtrl::create, Roles(Role.Explicit("ROLE_REMINDER_CREATE")))
|
||||
get(
|
||||
"/{id}",
|
||||
ReminderCtrl::get,
|
||||
Roles(Role.Explicit("ROLE_REMINDER_VIEW", "ROLE_REMINDER_CREATE"))
|
||||
"/{id}", ReminderCtrl::get, Roles(Role.Explicit("ROLE_REMINDER_VIEW", "ROLE_REMINDER_CREATE"))
|
||||
)
|
||||
put("/{id}", ReminderCtrl::update, Roles(Role.Explicit("ROLE_REMINDER_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
ReminderLogCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_REMINDER_CREATE", "ROLE_REMINDER_VIEW"))
|
||||
"/getAll", ReminderLogCtrl::getAll, Roles(Role.Explicit("ROLE_REMINDER_CREATE", "ROLE_REMINDER_VIEW"))
|
||||
)
|
||||
post(
|
||||
"/done",
|
||||
ReminderLogCtrl::done,
|
||||
Roles(Role.Explicit("ROLE_REMAINDER_CREATE"))
|
||||
"/done", ReminderLogCtrl::done, Roles(Role.Explicit("ROLE_REMAINDER_CREATE"))
|
||||
)
|
||||
get(
|
||||
"/getAll/{id}",
|
||||
ReminderCtrl::getAllByFleetId,
|
||||
Roles(Role.Explicit("ROLE_REMINDER_CREATE", "ROLE_REMINDER_VIEW"))
|
||||
"/getAll/{id}", ReminderCtrl::getAllByFleetId, Roles(Role.Explicit("ROLE_REMINDER_CREATE", "ROLE_REMINDER_VIEW"))
|
||||
)
|
||||
delete(
|
||||
"/{id}",
|
||||
ReminderCtrl::delete,
|
||||
Roles(Role.Explicit("ROLE_REMINDER_CREATE"))
|
||||
"/{id}", ReminderCtrl::delete, Roles(Role.Explicit("ROLE_REMINDER_CREATE"))
|
||||
)
|
||||
}
|
||||
path("/vehicle") {
|
||||
post("", VehicleCtrl::create, Roles(Role.Explicit("ROLE_FLEET_CREATE")))
|
||||
get(
|
||||
"/{id}",
|
||||
VehicleCtrl::get,
|
||||
Roles(Role.Explicit("ROLE_FLEET_VIEW", "ROLE_FLEET_CREATE"))
|
||||
"/{id}", VehicleCtrl::get, Roles(Role.Explicit("ROLE_FLEET_VIEW", "ROLE_FLEET_CREATE"))
|
||||
)
|
||||
put("/{id}", VehicleCtrl::update, Roles(Role.Explicit("ROLE_FLEET_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
VehicleCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_FLEET_CREATE", "ROLE_FLEET_VIEW"))
|
||||
"/getAll", VehicleCtrl::getAll, Roles(Role.Explicit("ROLE_FLEET_CREATE", "ROLE_FLEET_VIEW"))
|
||||
)
|
||||
}
|
||||
path("/fleetType") {
|
||||
post("", FleetTypeCtrl::create, Roles(Role.Explicit("ROLE_FLEET_CREATE")))
|
||||
get(
|
||||
"/{id}",
|
||||
FleetTypeCtrl::get,
|
||||
Roles(Role.Explicit("ROLE_FLEET_VIEW", "ROLE_FLEET_CREATE"))
|
||||
"/{id}", FleetTypeCtrl::get, Roles(Role.Explicit("ROLE_FLEET_VIEW", "ROLE_FLEET_CREATE"))
|
||||
)
|
||||
put("/{id}", FleetTypeCtrl::update, Roles(Role.Explicit("ROLE_FLEET_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
FleetTypeCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_FLEET_CREATE", "ROLE_FLEET_VIEW"))
|
||||
"/getAll", FleetTypeCtrl::getAll, Roles(Role.Explicit("ROLE_FLEET_CREATE", "ROLE_FLEET_VIEW"))
|
||||
)
|
||||
}
|
||||
path("/po") {
|
||||
@ -283,14 +236,10 @@ fun main(args: Array<String>) {
|
||||
post("", PurchaseOrderCtrl::create, Roles(Role.Explicit("ROLE_PO_CREATE")))
|
||||
post("/batch", PurchaseOrderCtrl::createBatch, Roles(Role.Explicit("ROLE_PO_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
PurchaseOrderCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_VENDOR_CREATE"))
|
||||
"/getAll", PurchaseOrderCtrl::getAll, Roles(Role.Explicit("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_VENDOR_CREATE"))
|
||||
)
|
||||
get(
|
||||
"/{id}",
|
||||
PurchaseOrderCtrl::get,
|
||||
Roles(Role.Explicit("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_QUOTE_CREATE"))
|
||||
"/{id}", PurchaseOrderCtrl::get, Roles(Role.Explicit("ROLE_PO_CREATE", "ROLE_PO_VIEW", "ROLE_QUOTE_CREATE"))
|
||||
)
|
||||
put("/{id}", PurchaseOrderCtrl::update, Roles(Role.Explicit("ROLE_PO_CREATE")))
|
||||
put("/approve/{id}", PurchaseOrderCtrl::approve, Roles(Role.Explicit()))
|
||||
@ -302,9 +251,7 @@ fun main(args: Array<String>) {
|
||||
post("", QuotationCtrl::create, Roles(Role.Explicit("ROLE_QUOTE_CREATE")))
|
||||
post("/batch", QuotationCtrl::createBatch, Roles(Role.Explicit("ROLE_QUOTE_CREATE")))
|
||||
post(
|
||||
"/getAll",
|
||||
QuotationCtrl::getAll,
|
||||
Roles(Role.Explicit("ROLE_QUOTE_CREATE", "ROLE_QUOTE_VIEW"))
|
||||
"/getAll", QuotationCtrl::getAll, Roles(Role.Explicit("ROLE_QUOTE_CREATE", "ROLE_QUOTE_VIEW"))
|
||||
)
|
||||
get("/{id}", QuotationCtrl::get, Roles(Role.Explicit("ROLE_QUOTE_VIEW", "ROLE_QUOTE_CREATE")))
|
||||
put("/{id}", QuotationCtrl::update, Roles(Role.Explicit("ROLE_QUOTE_CREATE")))
|
||||
@ -322,33 +269,23 @@ fun main(args: Array<String>) {
|
||||
post("", DocumentCtrl::create, Roles(Role.Explicit("ROLE_DOC_CREATE")))
|
||||
//why type and refid are clubbed ??
|
||||
get(
|
||||
"/{type}/{refId}",
|
||||
DocumentCtrl::getWithRefId,
|
||||
Roles(Role.Explicit("ROLE_DOC_VIEW", "ROLE_PRODUCT_CREATE"))
|
||||
"/{type}/{refId}", DocumentCtrl::getWithRefId, Roles(Role.Explicit("ROLE_DOC_VIEW", "ROLE_PRODUCT_CREATE"))
|
||||
)
|
||||
get("/{id}", DocumentCtrl::get, Roles(Role.Explicit("ROLE_DOC_VIEW", "ROLE_PRODUCT_CREATE")))
|
||||
get(
|
||||
"/print/{id}",
|
||||
DocumentCtrl::print,
|
||||
Roles(Role.Explicit("ROLE_DOC_CREATE", "ROLE_DOC_VIEW"))
|
||||
"/print/{id}", DocumentCtrl::print, Roles(Role.Explicit("ROLE_DOC_CREATE", "ROLE_DOC_VIEW"))
|
||||
)
|
||||
delete("/{id}", DocumentCtrl::delete, Roles(Role.Explicit("ROLE_DOC_CREATE")))
|
||||
}
|
||||
path("/reqForQuote") {
|
||||
post(
|
||||
"",
|
||||
RequestForQuote::create,
|
||||
Roles(Role.Explicit("ROLE_QUOTE_CREATE", "ROLE_PO_CREATE", "ROLE_RFQ_CREATE"))
|
||||
"", RequestForQuote::create, Roles(Role.Explicit("ROLE_QUOTE_CREATE", "ROLE_PO_CREATE", "ROLE_RFQ_CREATE"))
|
||||
)
|
||||
get(
|
||||
"/{id}",
|
||||
RequestForQuote::get,
|
||||
Roles(Role.Explicit("ROLE_RFQ_CREATE", "ROLE_RFQ_VIEW", "ROLE_QUOTE_VIEW", "ROLE_PO_VIEW"))
|
||||
"/{id}", RequestForQuote::get, Roles(Role.Explicit("ROLE_RFQ_CREATE", "ROLE_RFQ_VIEW", "ROLE_QUOTE_VIEW", "ROLE_PO_VIEW"))
|
||||
)
|
||||
put(
|
||||
"/{id}",
|
||||
RequestForQuote::update,
|
||||
Roles(Role.Explicit("ROLE_QUOTE_CREATE", "ROLE_PO_CREATE", "ROLE_RFQ_CREATE"))
|
||||
"/{id}", RequestForQuote::update, Roles(Role.Explicit("ROLE_QUOTE_CREATE", "ROLE_PO_CREATE", "ROLE_RFQ_CREATE"))
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -368,18 +305,11 @@ fun main(args: Array<String>) {
|
||||
patch("/{entity}/{id}", Entities::patch, Roles(adminRole, updateRole))
|
||||
delete("/{entity}/{id}", Entities::delete, Roles(adminRole, Role.Standard(Action.DELETE)))
|
||||
}
|
||||
}
|
||||
.exception(DuplicateKeyException::class.java, Exceptions.dupKeyExceptionHandler)
|
||||
.exception(DataIntegrityException::class.java, Exceptions.dataIntegrityException)
|
||||
.exception(DataNotFoundException::class.java, Exceptions.dataNotFoundException)
|
||||
.exception(IllegalArgumentException::class.java, Exceptions.illegalArgumentException)
|
||||
.exception(JsonMappingException::class.java, Exceptions.jsonMappingException)
|
||||
.exception(InvalidJwtException::class.java, Exceptions.invalidJwtException)
|
||||
}.exception(DuplicateKeyException::class.java, Exceptions.dupKeyExceptionHandler).exception(DataIntegrityException::class.java, Exceptions.dataIntegrityException)
|
||||
.exception(DataNotFoundException::class.java, Exceptions.dataNotFoundException).exception(IllegalArgumentException::class.java, Exceptions.illegalArgumentException)
|
||||
.exception(JsonMappingException::class.java, Exceptions.jsonMappingException).exception(InvalidJwtException::class.java, Exceptions.invalidJwtException)
|
||||
.start(appConfig.portNumber())
|
||||
}
|
||||
|
||||
private fun Context.getAuthHeader() = header("Authorization")
|
||||
?.replace("Bearer ", "")
|
||||
?.replace("Bearer: ", "")
|
||||
?.trim()
|
||||
private fun Context.getAuthHeader() = header("Authorization")?.replace("Bearer ", "")?.replace("Bearer: ", "")?.trim()
|
||||
|
||||
|
||||
@ -58,6 +58,10 @@ interface AppConfig {
|
||||
@Key("app.iam.client_secret")
|
||||
fun iamClientSecret(): Optional<String>
|
||||
|
||||
@Key("app.integration.rmc")
|
||||
@Default("https://www.readymixerp.com")
|
||||
fun integrationRmc(): String
|
||||
|
||||
@Key("app.cache.redis_uri")
|
||||
fun redisUri(): Optional<String>
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@ package com.restapi.config
|
||||
|
||||
import com.fasterxml.jackson.module.kotlin.readValue
|
||||
import com.restapi.config.AppConfig.Companion.appConfig
|
||||
import com.restapi.domain.Plant
|
||||
import com.restapi.domain.Session
|
||||
import com.restapi.domain.Session.objectMapper
|
||||
import io.javalin.http.BadRequestResponse
|
||||
@ -9,6 +10,9 @@ import io.javalin.http.ContentType
|
||||
import io.javalin.http.Context
|
||||
import io.javalin.http.UnauthorizedResponse
|
||||
import io.javalin.security.RouteRole
|
||||
import org.apache.http.client.methods.HttpGet
|
||||
import org.apache.http.impl.client.HttpClients
|
||||
import org.apache.http.util.EntityUtils
|
||||
import org.jose4j.jwk.HttpsJwks
|
||||
import org.jose4j.jwt.consumer.JwtConsumerBuilder
|
||||
import org.jose4j.keys.resolvers.HttpsJwksVerificationKeyResolver
|
||||
@ -43,13 +47,10 @@ object Auth {
|
||||
|
||||
fun getAuthEndpoint(): AuthEndpoint {
|
||||
return authCache.computeIfAbsent("AUTH") {
|
||||
val wellKnown =
|
||||
"${appConfig.iamUrl()}/realms/${appConfig.iamRealm()}/.well-known/openid-configuration"
|
||||
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()
|
||||
val req = HttpRequest.newBuilder().uri(URI.create(wellKnown)).GET().build()
|
||||
|
||||
objectMapper.readValue<AuthEndpoint>(
|
||||
client.send(req, HttpResponse.BodyHandlers.ofString()).body()
|
||||
@ -58,19 +59,11 @@ object Auth {
|
||||
|
||||
}
|
||||
|
||||
private val jwtConsumer = JwtConsumerBuilder()
|
||||
.setRequireExpirationTime()
|
||||
.setAllowedClockSkewInSeconds(30)
|
||||
.setRequireSubject()
|
||||
.setExpectedAudience("account")
|
||||
.setExpectedIssuer(getAuthEndpoint().issuer)
|
||||
.setVerificationKeyResolver(HttpsJwksVerificationKeyResolver(HttpsJwks(getAuthEndpoint().jwksUri)))
|
||||
.build()
|
||||
private val jwtConsumer = JwtConsumerBuilder().setRequireExpirationTime().setAllowedClockSkewInSeconds(30).setRequireSubject().setExpectedAudience("account")
|
||||
.setExpectedIssuer(getAuthEndpoint().issuer).setVerificationKeyResolver(HttpsJwksVerificationKeyResolver(HttpsJwks(getAuthEndpoint().jwksUri))).build()
|
||||
|
||||
private val jwtConsumerSkipValidate = JwtConsumerBuilder()
|
||||
.setSkipAllValidators()
|
||||
.setVerificationKeyResolver(HttpsJwksVerificationKeyResolver(HttpsJwks(getAuthEndpoint().jwksUri)))
|
||||
.build()
|
||||
private val jwtConsumerSkipValidate =
|
||||
JwtConsumerBuilder().setSkipAllValidators().setVerificationKeyResolver(HttpsJwksVerificationKeyResolver(HttpsJwks(getAuthEndpoint().jwksUri))).build()
|
||||
|
||||
fun validateAuthToken(authToken: String, skipValidate: Boolean = false): AuthUser {
|
||||
|
||||
@ -78,14 +71,29 @@ object Auth {
|
||||
val jwtClaims = if (skipValidate) jwtConsumerSkipValidate.process(authToken) else jwtConsumer.process(authToken)
|
||||
val userId = jwtClaims.jwtClaims.claimsMap["preferred_username"] as String
|
||||
val tenant = jwtClaims.jwtClaims.claimsMap["tenant"] as String
|
||||
val plantIds = jwtClaims.jwtClaims.claimsMap["plantIds"] as List<String>
|
||||
val roles = ((jwtClaims.jwtClaims.claimsMap["realm_access"] as Map<String, Any>)["roles"]) as List<String>
|
||||
val date = Date(jwtClaims.jwtClaims.expirationTime.valueInMillis)
|
||||
|
||||
HttpClients.createDefault().use { h ->
|
||||
//sync plant's from rmc to here, just name and id
|
||||
for (plantId in plantIds) {
|
||||
|
||||
val existing = Session.database.find(Plant::class.java).where().eq("plantId", plantId).findOne()
|
||||
if (existing == null) {
|
||||
h.execute(HttpGet("${appConfig.integrationRmc()}/plant?id=${plantId}")).use { r ->
|
||||
if (r.statusLine.statusCode == 200) {
|
||||
Session.database.save(Plant().apply {
|
||||
this.plantId = plantId
|
||||
this.plantName = EntityUtils.toString(r.entity)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return AuthUser(
|
||||
userName = userId,
|
||||
tenant = tenant,
|
||||
roles = roles,
|
||||
token = authToken,
|
||||
expiry = LocalDateTime.from(date.toInstant().atZone(ZoneId.systemDefault()))
|
||||
userName = userId, tenant = tenant, roles = roles, token = authToken, expiry = LocalDateTime.from(date.toInstant().atZone(ZoneId.systemDefault())), plantIds = plantIds
|
||||
)
|
||||
}
|
||||
|
||||
@ -100,8 +108,7 @@ object Auth {
|
||||
fun init(ctx: Context) {
|
||||
val endpoint = getAuthEndpoint().authorizationEndpoint
|
||||
|
||||
val redirectUrl =
|
||||
"$endpoint?response_type=code&client_id=${appConfig.iamClient()}&redirect_uri=${appConfig.iamClientRedirectUri()}&scope=profile&state=1234zyx"
|
||||
val redirectUrl = "$endpoint?response_type=code&client_id=${appConfig.iamClient()}&redirect_uri=${appConfig.iamClientRedirectUri()}&scope=profile&state=1234zyx"
|
||||
ctx.redirect(redirectUrl)
|
||||
}
|
||||
|
||||
@ -112,9 +119,7 @@ object Auth {
|
||||
|
||||
val ep = getAuthEndpoint().tokenEndpoint
|
||||
val httpClient = HttpClient.newHttpClient()
|
||||
val req = HttpRequest.newBuilder()
|
||||
.uri(URI.create(ep))
|
||||
.POST(
|
||||
val req = HttpRequest.newBuilder().uri(URI.create(ep)).POST(
|
||||
HttpRequest.BodyPublishers.ofString(
|
||||
getFormDataAsString(
|
||||
mapOf(
|
||||
@ -125,9 +130,7 @@ object Auth {
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.build()
|
||||
).header("Content-Type", "application/x-www-form-urlencoded").build()
|
||||
|
||||
val message = httpClient.send(req, HttpResponse.BodyHandlers.ofString()).body()
|
||||
val atResponse = objectMapper.readValue<AuthTokenResponse>(message)
|
||||
@ -135,8 +138,7 @@ object Auth {
|
||||
|
||||
//keep track of this for renewal when asked by client
|
||||
Session.redis.lpush(
|
||||
"$AUTH_TOKEN${parsed.userName}",
|
||||
objectMapper.writeValueAsString(
|
||||
"$AUTH_TOKEN${parsed.userName}", objectMapper.writeValueAsString(
|
||||
atResponse.copy(
|
||||
createdAt = LocalDateTime.now()
|
||||
)
|
||||
@ -147,10 +149,7 @@ object Auth {
|
||||
|
||||
fun refreshToken(ctx: Context) {
|
||||
//refresh authToken
|
||||
val authToken = ctx.header("Authorization")
|
||||
?.replace("Bearer ", "")
|
||||
?.replace("Bearer: ", "")
|
||||
?.trim() ?: throw UnauthorizedResponse()
|
||||
val authToken = ctx.header("Authorization")?.replace("Bearer ", "")?.replace("Bearer: ", "")?.trim() ?: throw UnauthorizedResponse()
|
||||
|
||||
val authUser = validateAuthToken(authToken, skipValidate = true)
|
||||
val client = ctx.queryParam("client") ?: throw BadRequestResponse("client not sent")
|
||||
@ -159,10 +158,7 @@ object Auth {
|
||||
val key = "$AUTH_TOKEN${authUser.userName}"
|
||||
val found = Session.redis.llen(key)
|
||||
logger.warn("for user ${authUser.userName}, found from redis, $key => $found entries")
|
||||
val foundOldAt = (0..found)
|
||||
.mapNotNull { Session.redis.lindex(key, it) }
|
||||
.map { objectMapper.readValue<AuthTokenResponse>(it) }
|
||||
.firstOrNull { it.accessToken == authToken }
|
||||
val foundOldAt = (0..found).mapNotNull { Session.redis.lindex(key, it) }.map { objectMapper.readValue<AuthTokenResponse>(it) }.firstOrNull { it.accessToken == authToken }
|
||||
?: throw BadRequestResponse("authToken not found in cache")
|
||||
|
||||
val createdAt = foundOldAt.createdAt ?: throw BadRequestResponse("created at is missing")
|
||||
@ -177,9 +173,7 @@ object Auth {
|
||||
logger.warn("We can refresh the token for ${authUser.userName}, expires = $expiresAt, refresh Till = $rtExpiresAt")
|
||||
val ep = getAuthEndpoint().tokenEndpoint
|
||||
val httpClient = HttpClient.newHttpClient()
|
||||
val req = HttpRequest.newBuilder()
|
||||
.uri(URI.create(ep))
|
||||
.POST(
|
||||
val req = HttpRequest.newBuilder().uri(URI.create(ep)).POST(
|
||||
HttpRequest.BodyPublishers.ofString(
|
||||
getFormDataAsString(
|
||||
mapOf(
|
||||
@ -190,16 +184,13 @@ object Auth {
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
.header("Content-Type", "application/x-www-form-urlencoded")
|
||||
.build()
|
||||
).header("Content-Type", "application/x-www-form-urlencoded").build()
|
||||
val message = httpClient.send(req, HttpResponse.BodyHandlers.ofString()).body()
|
||||
val atResponse = objectMapper.readValue<AuthTokenResponse>(message)
|
||||
val parsed = validateAuthToken(atResponse.accessToken)
|
||||
|
||||
Session.redis.lpush(
|
||||
"AUTH_TOKEN_${parsed.userName}",
|
||||
objectMapper.writeValueAsString(
|
||||
"AUTH_TOKEN_${parsed.userName}", objectMapper.writeValueAsString(
|
||||
atResponse.copy(createdAt = LocalDateTime.now())
|
||||
)
|
||||
)
|
||||
@ -221,11 +212,7 @@ object Auth {
|
||||
}
|
||||
|
||||
data class AuthUser(
|
||||
val userName: String,
|
||||
val tenant: String,
|
||||
val roles: List<String>,
|
||||
val token: String,
|
||||
val expiry: LocalDateTime
|
||||
val userName: String, val tenant: String, val roles: List<String>, val token: String, val expiry: LocalDateTime, val plantIds: List<String>
|
||||
)
|
||||
|
||||
enum class Action {
|
||||
|
||||
@ -39,7 +39,7 @@ object Session {
|
||||
private val logger = LoggerFactory.getLogger("session")
|
||||
private val currentUser = object : ThreadLocal<AuthUser>() {
|
||||
override fun initialValue(): AuthUser {
|
||||
return AuthUser("", "", emptyList(), "", LocalDateTime.now())
|
||||
return AuthUser("", "", emptyList(), "", LocalDateTime.now(), emptyList())
|
||||
}
|
||||
}
|
||||
|
||||
@ -182,6 +182,13 @@ object Session {
|
||||
fun currentTenant() = currentUser.get().tenant
|
||||
fun currentRoles() = currentUser.get().roles
|
||||
fun currentToken() = currentUser.get().token
|
||||
fun currentUserPlants() = currentUser.get().plantIds.map {
|
||||
Session.database.find(Plant::class.java)
|
||||
.where()
|
||||
.eq("plantId", it)
|
||||
.findOne()
|
||||
}.filterNotNull()
|
||||
|
||||
fun jwk() = keypair.toParams(JsonWebKey.OutputControlLevel.PUBLIC_ONLY)
|
||||
|
||||
fun Database.findDataModelByEntityAndUniqId(entity: String, uniqId: String): DataModel {
|
||||
|
||||
@ -14,11 +14,7 @@ import javax.persistence.*
|
||||
|
||||
data class Comments(val text: String = "", val by: String = "", val at: LocalDateTime = LocalDateTime.now())
|
||||
data class POProducts(
|
||||
val productId: String = "",
|
||||
val productName: String = "",
|
||||
val unitPrice: Double = 0.0,
|
||||
val quantity: Double = 0.0,
|
||||
val description: String = ""
|
||||
val productId: String = "", val productName: String = "", val unitPrice: Double = 0.0, val quantity: Double = 0.0, val description: String = ""
|
||||
)
|
||||
|
||||
|
||||
@ -112,15 +108,13 @@ open class AuditLog : BaseTenantModel() {
|
||||
|
||||
@DbJsonB
|
||||
@Index(
|
||||
definition = "create index audit_log_values_idx on audit_log using GIN (data)",
|
||||
platforms = [Platform.POSTGRES]
|
||||
definition = "create index audit_log_values_idx on audit_log using GIN (data)", platforms = [Platform.POSTGRES]
|
||||
)
|
||||
var data: Map<String, Any> = hashMapOf()
|
||||
|
||||
@DbJsonB
|
||||
@Index(
|
||||
definition = "create index audit_log_changes_idx on audit_log using GIN (changes)",
|
||||
platforms = [Platform.POSTGRES]
|
||||
definition = "create index audit_log_changes_idx on audit_log using GIN (changes)", platforms = [Platform.POSTGRES]
|
||||
)
|
||||
var changes: Map<String, Any> = hashMapOf()
|
||||
}
|
||||
@ -545,7 +539,7 @@ open class Fleet : BaseTenantModel() {
|
||||
var name: String = ""
|
||||
var type: String = ""
|
||||
var regNumber: String = ""
|
||||
var regDate: LocalDate?=null
|
||||
var regDate: LocalDate? = null
|
||||
var model: String = ""
|
||||
var make: String = ""
|
||||
var driver: String = ""
|
||||
@ -636,3 +630,10 @@ open class ReminderLog : BaseTenantModel() {
|
||||
@DbArray
|
||||
var documents: List<String>? = null
|
||||
}
|
||||
|
||||
@Entity
|
||||
@Index(name="plantid_idx", columnNames = ["plant_id"], unique = true)
|
||||
open class Plant : BaseModel() {
|
||||
var plantId: String = ""
|
||||
var plantName: String = ""
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user