diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..30f3530 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +rest_api \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..fd3f608 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/prettier.xml b/.idea/prettier.xml new file mode 100644 index 0000000..0c83ac4 --- /dev/null +++ b/.idea/prettier.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/src/main/kotlin/com/restapi/AppAccessManager.kt b/src/main/kotlin/com/restapi/AppAccessManager.kt index f26a1b5..e60cc9f 100644 --- a/src/main/kotlin/com/restapi/AppAccessManager.kt +++ b/src/main/kotlin/com/restapi/AppAccessManager.kt @@ -46,12 +46,12 @@ class AppAccessManager : AccessManager { } val isAllowed = currentRoles().count { allowedRoles.contains(it) } > 0 - logger.warn("entity - $entity, action $action, userroles = ${currentRoles()}, allowed = $allowedRoles, isAllowed? $isAllowed, enforce? ${appConfig.enforceRoleRestriction()}") + logger.warn("entity - $entity, action $action, user roles = ${currentRoles()}, allowed = $allowedRoles, isAllowed? $isAllowed, enforce? ${appConfig.enforceRoleRestriction()}") if (isAllowed || !appConfig.enforceRoleRestriction() || allowedRoles.isEmpty()) { //if role is allowed, or enforcement is turned off or no roles are explicitly allowed handler.handle(ctx) } else { - ctx.status(HttpStatus.UNAUTHORIZED).result("unauthorized request") + ctx.status(HttpStatus.FORBIDDEN).result("user not allowed to do this") } } } diff --git a/src/main/kotlin/com/restapi/Main.kt b/src/main/kotlin/com/restapi/Main.kt index 11ddef4..a4d76a9 100644 --- a/src/main/kotlin/com/restapi/Main.kt +++ b/src/main/kotlin/com/restapi/Main.kt @@ -12,6 +12,8 @@ import com.restapi.config.Roles import com.restapi.controllers.Entities import com.restapi.domain.DataNotFoundException import com.restapi.domain.Session +import com.restapi.domain.Session.currentTenant +import com.restapi.domain.Session.currentUser import com.restapi.domain.Session.objectMapper import com.restapi.domain.Session.redis import com.restapi.domain.Session.setAuthorizedUser @@ -34,6 +36,7 @@ import java.net.http.HttpRequest.BodyPublishers import java.net.http.HttpResponse.BodyHandlers import java.nio.charset.StandardCharsets import java.security.MessageDigest +import java.time.LocalDateTime import java.util.* import java.util.concurrent.TimeUnit import kotlin.jvm.optionals.getOrDefault @@ -73,6 +76,9 @@ fun main(args: Array) { path("/auth") { //for testing, development only + get("/endpoint") { + it.json(getAuthEndpoint()) + } get("/init") { val endpoint = getAuthEndpoint().authorizationEndpoint @@ -83,6 +89,8 @@ fun main(args: Array) { get("/code") { val code = it.queryParam("code") ?: throw BadRequestResponse("not proper") + val redirectUri = it.queryParam("redirectUrl") ?: appConfig.iamClientRedirectUri() + val iamClient = it.queryParam("client") ?: appConfig.iamClient() val ep = getAuthEndpoint().tokenEndpoint val client = HttpClient.newHttpClient() @@ -93,8 +101,8 @@ fun main(args: Array) { getFormDataAsString( mapOf( "code" to code, - "redirect_uri" to appConfig.iamClientRedirectUri(), - "client_id" to appConfig.iamClient(), + "redirect_uri" to redirectUri, + "client_id" to iamClient, "grant_type" to "authorization_code", ) ) @@ -104,9 +112,10 @@ fun main(args: Array) { .build() val message = client.send(req, BodyHandlers.ofString()).body() val atResponse = objectMapper.readValue(message) + val parsed = validateAuthToken(atResponse.accessToken) - //lets keep auth token refreshed - redis.sadd("AUTH_TOKEN", message) + //keep track of this + redis.rpush("AUTH_TOKEN_${parsed.userName}", message) it.result(atResponse.accessToken).contentType(ContentType.TEXT_PLAIN) } @@ -155,6 +164,9 @@ fun main(args: Array) { path("/api") { + post("/audit/{action}") { + logger.warn("User ${currentUser()} of tenant ${currentTenant()} has performed ${it.pathParam("action")} @ ${LocalDateTime.now()}") + } post("/script/database/{name}", Entities::executeStoredProcedure, Roles(adminRole, Role.DbOps)) post("/script/{file}/{name}", Entities::executeScript, Roles(adminRole, Role.DbOps))