diff --git a/api/pom.xml b/api/pom.xml index d8263c8..860ee62 100644 --- a/api/pom.xml +++ b/api/pom.xml @@ -20,7 +20,7 @@ 2023.0.1 - 7.8.2 + 7.8.3 0.2.0 1.6.0.Beta2 diff --git a/api/quiz-api/src/main/java/com/c4soft/quiz/RuntimeHintsConfiguration.java b/api/quiz-api/src/main/java/com/c4soft/quiz/RuntimeHintsConfiguration.java new file mode 100644 index 0000000..65f7646 --- /dev/null +++ b/api/quiz-api/src/main/java/com/c4soft/quiz/RuntimeHintsConfiguration.java @@ -0,0 +1,26 @@ +package com.c4soft.quiz; + +import java.util.List; +import org.springframework.aot.hint.MemberCategory; +import org.springframework.aot.hint.RuntimeHints; +import org.springframework.aot.hint.RuntimeHintsRegistrar; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportRuntimeHints; +import liquibase.database.LiquibaseTableNamesFactory; +import liquibase.report.ShowSummaryGeneratorFactory; +import liquibase.ui.LoggerUIService; + +@Configuration +@ImportRuntimeHints({RuntimeHintsConfiguration.LiquibaseRuntimeHints.class}) +public class RuntimeHintsConfiguration { + + static class LiquibaseRuntimeHints implements RuntimeHintsRegistrar { + @Override + public void registerHints(RuntimeHints hints, ClassLoader classLoader) { + List.of(LoggerUIService.class, LiquibaseTableNamesFactory.class, + ShowSummaryGeneratorFactory.class) + .forEach(clazz -> hints.reflection().registerType(clazz, + MemberCategory.INVOKE_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_METHODS)); + } + } +} diff --git a/api/quiz-api/src/main/java/com/c4soft/quiz/web/SkillTestController.java b/api/quiz-api/src/main/java/com/c4soft/quiz/web/SkillTestController.java index f8fc935..3f7dec3 100644 --- a/api/quiz-api/src/main/java/com/c4soft/quiz/web/SkillTestController.java +++ b/api/quiz-api/src/main/java/com/c4soft/quiz/web/SkillTestController.java @@ -46,14 +46,14 @@ import jakarta.persistence.EntityNotFoundException; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; -import lombok.extern.log4j.Log4j2; +import lombok.extern.slf4j.Slf4j; @RestController @RequestMapping(path = "/skill-tests") @RequiredArgsConstructor @Validated @Tag(name = "SkillTest") -@Log4j2 +@Slf4j public class SkillTestController { private final SkillTestRepository testRepo; private final QuizRepository quizRepo; @@ -82,9 +82,8 @@ public List getSkillTestList( @GetMapping(path = "/{quizId}/{traineeName}", produces = MediaType.APPLICATION_JSON_VALUE) @Transactional(readOnly = true) - @Operation( - description = "Returns a given trainee answers to a quiz, by default over the last 2" - + " weeks") + @Operation(description = "Returns a given trainee answers to a quiz, by default over the last 2" + + " weeks") public SkillTestResultDetailsDto getSkillTest( @PathVariable(value = "quizId", required = true) Long quizId, @PathVariable(value = "traineeName", required = true) String traineeName) { @@ -146,7 +145,7 @@ public ResponseEntity submitSkillTest( } } } catch (Exception e) { - log.error(e); + log.error(e.getMessage()); } return ResponseEntity.accepted().location(URI.create(testUri)).body(toPreviewDto(saved)); diff --git a/keycloak/import/quiz-realm.json b/keycloak/import/quiz-realm.json index caf56f4..c6e5122 100644 --- a/keycloak/import/quiz-realm.json +++ b/keycloak/import/quiz-realm.json @@ -93,6 +93,7 @@ "attributes" : { } } ], "client" : { + "quiz-admin" : [ ], "realm-management" : [ { "id" : "d444308b-e618-4d62-adfe-92db269ba2ff", "name" : "view-realm", @@ -438,6 +439,24 @@ "realmRoles" : [ "default-roles-quiz", "moderator" ], "notBefore" : 0, "groups" : [ ] + }, { + "id" : "d62d7428-704e-4aeb-bfec-fc277ed75cd9", + "username" : "service-account-quiz-admin", + "emailVerified" : false, + "createdTimestamp" : 1718654181092, + "enabled" : true, + "totp" : false, + "serviceAccountClientId" : "quiz-admin", + "credentials" : [ ], + "disableableCredentialTypes" : [ ], + "requiredActions" : [ ], + "realmRoles" : [ "default-roles-quiz" ], + "clientRoles" : { + "realm-management" : [ "view-users" ], + "account" : [ "view-profile" ] + }, + "notBefore" : 0, + "groups" : [ ] }, { "id" : "c0d9b57f-ad81-47e4-b2b8-b47e1de12a0b", "username" : "trainee", @@ -584,7 +603,9 @@ "publicClient" : true, "frontchannelLogout" : false, "protocol" : "openid-connect", - "attributes" : { }, + "attributes" : { + "post.logout.redirect.uris" : "+" + }, "authenticationFlowBindingOverrides" : { }, "fullScopeAllowed" : false, "nodeReRegistrationTimeout" : 0, @@ -610,19 +631,101 @@ "publicClient" : false, "frontchannelLogout" : false, "protocol" : "openid-connect", - "attributes" : { }, + "attributes" : { + "post.logout.redirect.uris" : "+" + }, "authenticationFlowBindingOverrides" : { }, "fullScopeAllowed" : false, "nodeReRegistrationTimeout" : 0, "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] + }, { + "id" : "a8e552e1-0cb9-4688-9619-c2aadeb89d7b", + "clientId" : "quiz-admin", + "name" : "", + "description" : "", + "rootUrl" : "", + "adminUrl" : "", + "baseUrl" : "", + "surrogateAuthRequired" : false, + "enabled" : true, + "alwaysDisplayInConsole" : false, + "clientAuthenticatorType" : "client-secret", + "secret" : "secret", + "redirectUris" : [ "/*" ], + "webOrigins" : [ "/*" ], + "notBefore" : 0, + "bearerOnly" : false, + "consentRequired" : false, + "standardFlowEnabled" : false, + "implicitFlowEnabled" : false, + "directAccessGrantsEnabled" : false, + "serviceAccountsEnabled" : true, + "publicClient" : false, + "frontchannelLogout" : true, + "protocol" : "openid-connect", + "attributes" : { + "oidc.ciba.grant.enabled" : "false", + "oauth2.device.authorization.grant.enabled" : "false", + "client.secret.creation.time" : "1718654181", + "backchannel.logout.session.required" : "true", + "backchannel.logout.revoke.offline.tokens" : "false" + }, + "authenticationFlowBindingOverrides" : { }, + "fullScopeAllowed" : true, + "nodeReRegistrationTimeout" : -1, + "protocolMappers" : [ { + "id" : "abe43a09-3f43-48fd-b1bd-89a3c5efd856", + "name" : "Client IP Address", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientAddress", + "introspection.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientAddress", + "jsonType.label" : "String" + } + }, { + "id" : "a63a64c3-8415-4ed8-8979-d33c79b922c3", + "name" : "Client ID", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "client_id", + "introspection.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "client_id", + "jsonType.label" : "String" + } + }, { + "id" : "1a9f3f9d-332c-460d-8494-4a9f0d259248", + "name" : "Client Host", + "protocol" : "openid-connect", + "protocolMapper" : "oidc-usersessionmodel-note-mapper", + "consentRequired" : false, + "config" : { + "user.session.note" : "clientHost", + "introspection.token.claim" : "true", + "id.token.claim" : "true", + "access.token.claim" : "true", + "claim.name" : "clientHost", + "jsonType.label" : "String" + } + } ], + "defaultClientScopes" : [ "web-origins", "acr", "profile", "roles", "email" ], + "optionalClientScopes" : [ "address", "phone", "offline_access", "microprofile-jwt" ] }, { "id" : "c0511d4c-a116-4030-8957-576a059d049b", "clientId" : "quiz-bff", "name" : "", "description" : "", - "rootUrl" : "http://mc-ch4mp/bff", - "adminUrl" : "http://mc-ch4mp/bff", + "rootUrl" : "http://localhost/bff", + "adminUrl" : "http://localhost/bff", "baseUrl" : "", "surrogateAuthRequired" : false, "enabled" : true, @@ -630,15 +733,14 @@ "clientAuthenticatorType" : "client-secret", "secret" : "secret", "redirectUris" : [ - "http://localhost/bff/login/oauth2/code/quiz-bff", "http://127.0.0.1/bff/login/oauth2/code/quiz-bff", - "http://host.docker.internal/bff/login/oauth2/code/quiz-bff", - "http://mc-ch4mp/bff/login/oauth2/code/quiz-bff", - "https://localhost/bff/login/oauth2/code/quiz-bff", "https://127.0.0.1/bff/login/oauth2/code/quiz-bff", - "https://host.docker.internal/bff/login/oauth2/code/quiz-bff", - "https://mc-ch4mp/bff/login/oauth2/code/quiz-bff" - ], + "http://localhost/bff/login/oauth2/code/quiz-bff", + "https://localhost/bff/login/oauth2/code/quiz-bff", + "http://localhost/bff/login/oauth2/code/quiz-bff", + "https://localhost/bff/login/oauth2/code/quiz-bff", + "http://host.docker.internal/bff/login/oauth2/code/quiz-bff", + "https://host.docker.internal/bff/login/oauth2/code/quiz-bff" ], "webOrigins" : [ "+" ], "notBefore" : 0, "bearerOnly" : false, @@ -654,7 +756,7 @@ "oidc.ciba.grant.enabled" : "false", "client.secret.creation.time" : "1718395789", "backchannel.logout.session.required" : "true", - "backchannel.logout.url" : "http://mc-ch4mp/bff/logout/connect/back-channel/quiz-bff", + "backchannel.logout.url" : "http://localhost/bff/logout/connect/back-channel/quiz-bff", "post.logout.redirect.uris" : "+", "oauth2.device.authorization.grant.enabled" : "false", "display.on.consent.screen" : "false", @@ -685,7 +787,9 @@ "publicClient" : false, "frontchannelLogout" : false, "protocol" : "openid-connect", - "attributes" : { }, + "attributes" : { + "post.logout.redirect.uris" : "+" + }, "authenticationFlowBindingOverrides" : { }, "fullScopeAllowed" : false, "nodeReRegistrationTimeout" : 0, @@ -975,7 +1079,8 @@ "config" : { "id.token.claim" : "true", "introspection.token.claim" : "true", - "access.token.claim" : "true" + "access.token.claim" : "true", + "userinfo.token.claim" : "true" } } ] }, { @@ -1222,6 +1327,7 @@ "config" : { "introspection.token.claim" : "true", "multivalued" : "true", + "userinfo.token.claim" : "true", "user.attribute" : "foo", "id.token.claim" : "true", "access.token.claim" : "true", @@ -1274,7 +1380,7 @@ "subType" : "anonymous", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "saml-user-attribute-mapper", "oidc-usermodel-attribute-mapper", "oidc-address-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-user-property-mapper", "oidc-full-name-mapper", "saml-role-list-mapper" ] + "allowed-protocol-mapper-types" : [ "saml-user-attribute-mapper", "oidc-usermodel-property-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper", "oidc-usermodel-attribute-mapper", "oidc-full-name-mapper", "saml-user-property-mapper", "oidc-address-mapper" ] } }, { "id" : "f6dacc02-7e0f-43ef-b80c-4a342881b6fe", @@ -1290,7 +1396,7 @@ "subType" : "authenticated", "subComponents" : { }, "config" : { - "allowed-protocol-mapper-types" : [ "oidc-usermodel-property-mapper", "oidc-address-mapper", "oidc-usermodel-attribute-mapper", "oidc-sha256-pairwise-sub-mapper", "saml-role-list-mapper", "saml-user-property-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper" ] + "allowed-protocol-mapper-types" : [ "oidc-usermodel-attribute-mapper", "oidc-usermodel-property-mapper", "saml-role-list-mapper", "oidc-address-mapper", "saml-user-property-mapper", "oidc-sha256-pairwise-sub-mapper", "oidc-full-name-mapper", "saml-user-attribute-mapper" ] } }, { "id" : "179b3fbf-e09e-4798-8db8-ee7689838de6", @@ -1925,12 +2031,16 @@ "cibaExpiresIn" : "120", "cibaAuthRequestedUserHint" : "login_hint", "oauth2DeviceCodeLifespan" : "600", + "clientOfflineSessionMaxLifespan" : "0", "oauth2DevicePollingInterval" : "5", + "clientSessionIdleTimeout" : "0", "parRequestUriLifespan" : "60", + "clientSessionMaxLifespan" : "0", + "clientOfflineSessionIdleTimeout" : "0", "cibaInterval" : "5", "realmReusableOtpCode" : "false" }, - "keycloakVersion" : "24.0.5", + "keycloakVersion" : "24.0.0", "userManagedAccessAllowed" : false, "clientProfiles" : { "profiles" : [ ]