diff --git a/infrastructure/keycloak/realm-export-acceptance.json b/infrastructure/keycloak/realm-export-acceptance.json index 81bf5e02b..e1c1b6d9a 100644 --- a/infrastructure/keycloak/realm-export-acceptance.json +++ b/infrastructure/keycloak/realm-export-acceptance.json @@ -313,6 +313,7 @@ "attributes": {} } ], + "timekeeper-swagger": [], "react-timekeeper-client": [], "security-admin-console": [], "admin-cli": [], @@ -963,6 +964,63 @@ "offline_access", "microprofile-jwt" ] + }, + { + "id": "9eb912f2-7853-44f7-92bc-4a9972a52ae2", + "clientId": "timekeeper-swagger", + "description": "The client required by swagger, used to get read and write access on the API", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "xbz32-any-secret-we-do-not-use-it", + "redirectUris": [ + "https://acceptance.timekeeper.lunatech.fr/swagger-ui/oauth2-redirect.html", + "https://acceptance.timekeeper.lunatech.fr/oauth2-redirect.html" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": true, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "saml.encrypt": "false", + "login_theme": "timekeeper", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "exclude.session.state.from.auth.response": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "saml.onetimeuse.condition": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "defaultClientScopes": [ + "web-origins", + "role_list", + "profile", + "roles", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] } ], "clientScopes": [ @@ -1501,76 +1559,8 @@ "eventsListeners": [ "jboss-logging" ], - "enabledEventTypes": [ - "SEND_RESET_PASSWORD", - "UPDATE_CONSENT_ERROR", - "GRANT_CONSENT", - "REMOVE_TOTP", - "REVOKE_GRANT", - "UPDATE_TOTP", - "LOGIN_ERROR", - "CLIENT_LOGIN", - "RESET_PASSWORD_ERROR", - "IMPERSONATE_ERROR", - "CODE_TO_TOKEN_ERROR", - "CUSTOM_REQUIRED_ACTION", - "RESTART_AUTHENTICATION", - "IMPERSONATE", - "UPDATE_PROFILE_ERROR", - "LOGIN", - "UPDATE_PASSWORD_ERROR", - "CLIENT_INITIATED_ACCOUNT_LINKING", - "TOKEN_EXCHANGE", - "LOGOUT", - "REGISTER", - "CLIENT_REGISTER", - "IDENTITY_PROVIDER_LINK_ACCOUNT", - "UPDATE_PASSWORD", - "CLIENT_DELETE", - "FEDERATED_IDENTITY_LINK_ERROR", - "IDENTITY_PROVIDER_FIRST_LOGIN", - "CLIENT_DELETE_ERROR", - "VERIFY_EMAIL", - "CLIENT_LOGIN_ERROR", - "RESTART_AUTHENTICATION_ERROR", - "EXECUTE_ACTIONS", - "REMOVE_FEDERATED_IDENTITY_ERROR", - "TOKEN_EXCHANGE_ERROR", - "PERMISSION_TOKEN", - "SEND_IDENTITY_PROVIDER_LINK_ERROR", - "EXECUTE_ACTION_TOKEN_ERROR", - "SEND_VERIFY_EMAIL", - "EXECUTE_ACTIONS_ERROR", - "REMOVE_FEDERATED_IDENTITY", - "IDENTITY_PROVIDER_POST_LOGIN", - "IDENTITY_PROVIDER_LINK_ACCOUNT_ERROR", - "UPDATE_EMAIL", - "REGISTER_ERROR", - "REVOKE_GRANT_ERROR", - "EXECUTE_ACTION_TOKEN", - "LOGOUT_ERROR", - "UPDATE_EMAIL_ERROR", - "CLIENT_UPDATE_ERROR", - "UPDATE_PROFILE", - "CLIENT_REGISTER_ERROR", - "FEDERATED_IDENTITY_LINK", - "SEND_IDENTITY_PROVIDER_LINK", - "SEND_VERIFY_EMAIL_ERROR", - "RESET_PASSWORD", - "CLIENT_INITIATED_ACCOUNT_LINKING_ERROR", - "UPDATE_CONSENT", - "REMOVE_TOTP_ERROR", - "VERIFY_EMAIL_ERROR", - "SEND_RESET_PASSWORD_ERROR", - "CLIENT_UPDATE", - "CUSTOM_REQUIRED_ACTION_ERROR", - "IDENTITY_PROVIDER_POST_LOGIN_ERROR", - "UPDATE_TOTP_ERROR", - "CODE_TO_TOKEN", - "GRANT_CONSENT_ERROR", - "IDENTITY_PROVIDER_FIRST_LOGIN_ERROR" - ], - "adminEventsEnabled": true, + "enabledEventTypes": [], + "adminEventsEnabled": false, "adminEventsDetailsEnabled": false, "identityProviders": [ { diff --git a/infrastructure/keycloak/realm-export-dev.json b/infrastructure/keycloak/realm-export-dev.json index 50bd3821e..a90f8b88f 100644 --- a/infrastructure/keycloak/realm-export-dev.json +++ b/infrastructure/keycloak/realm-export-dev.json @@ -313,6 +313,7 @@ "attributes": {} } ], + "timekeeper-swagger": [], "react-timekeeper-client": [], "security-admin-console": [], "admin-cli": [], @@ -913,6 +914,63 @@ "offline_access", "microprofile-jwt" ] + }, + { + "id": "9eb912f2-7853-44f7-92bc-4a9972a52ae2", + "clientId": "timekeeper-swagger", + "description": "The client required by swagger, used to get read and write access on the API", + "surrogateAuthRequired": false, + "enabled": true, + "alwaysDisplayInConsole": false, + "clientAuthenticatorType": "client-secret", + "secret": "xbz32-any-secret-we-do-not-use-it", + "redirectUris": [ + "http://localhost:8081/swagger-ui/oauth2-redirect.html", + "http://localhost:8081/oauth2-redirect.html" + ], + "webOrigins": [], + "notBefore": 0, + "bearerOnly": false, + "consentRequired": false, + "standardFlowEnabled": true, + "implicitFlowEnabled": true, + "directAccessGrantsEnabled": true, + "serviceAccountsEnabled": false, + "publicClient": true, + "frontchannelLogout": false, + "protocol": "openid-connect", + "attributes": { + "saml.assertion.signature": "false", + "saml.force.post.binding": "false", + "saml.multivalued.roles": "false", + "saml.encrypt": "false", + "login_theme": "timekeeper", + "saml.server.signature": "false", + "saml.server.signature.keyinfo.ext": "false", + "exclude.session.state.from.auth.response": "false", + "saml_force_name_id_format": "false", + "saml.client.signature": "false", + "tls.client.certificate.bound.access.tokens": "false", + "saml.authnstatement": "false", + "display.on.consent.screen": "false", + "saml.onetimeuse.condition": "false" + }, + "authenticationFlowBindingOverrides": {}, + "fullScopeAllowed": true, + "nodeReRegistrationTimeout": -1, + "defaultClientScopes": [ + "web-origins", + "role_list", + "profile", + "roles", + "email" + ], + "optionalClientScopes": [ + "address", + "phone", + "offline_access", + "microprofile-jwt" + ] } ], "clientScopes": [ diff --git a/src/main/java/fr/lunatech/timekeeper/TimeKeeperApplication.java b/src/main/java/fr/lunatech/timekeeper/TimeKeeperApplication.java index 6a46264ce..0298787f8 100644 --- a/src/main/java/fr/lunatech/timekeeper/TimeKeeperApplication.java +++ b/src/main/java/fr/lunatech/timekeeper/TimeKeeperApplication.java @@ -3,8 +3,13 @@ import org.eclipse.microprofile.openapi.annotations.ExternalDocumentation; import org.eclipse.microprofile.openapi.annotations.OpenAPIDefinition; +import org.eclipse.microprofile.openapi.annotations.enums.SecuritySchemeIn; +import org.eclipse.microprofile.openapi.annotations.enums.SecuritySchemeType; import org.eclipse.microprofile.openapi.annotations.info.Contact; import org.eclipse.microprofile.openapi.annotations.info.Info; +import org.eclipse.microprofile.openapi.annotations.info.License; +import org.eclipse.microprofile.openapi.annotations.security.*; +import org.eclipse.microprofile.openapi.annotations.servers.Server; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @@ -15,9 +20,45 @@ info = @Info(title = "TimeKeeper API", description = "This API allows CRUD operations and interaction with TimeKeeper", version = "1.0", - contact = @Contact(name = "TimeKeeper GitHub", url = "https://github.com/lunatech-labs/lunatech-timekeeper")), - externalDocs = @ExternalDocumentation(url = "https://lunatech.atlassian.net/wiki/spaces/INTRANET/pages/1609695253/Timekeeper", description = "Lunatech doc about TimeKeeper on Confluence") + contact = @Contact(name = "TimeKeeper GitHub", url = "https://github.com/lunatech-labs/lunatech-timekeeper"), + license = @License(name = "Apache 2.0", url = "http://www.apache.org/licenses/LICENSE-2.0.html") + ), + servers = { + @Server( + url = "http://localhost:8081", + description = "DEV Server" + ), + @Server( + url = "https://acceptance.api.timekeeper.lunatech.fr", + description = "ACCEPTANCE Server" + ) + } + , security = { + @SecurityRequirement( name = "dev_timekeeperOAuth2" ,scopes = { "profile"}), + @SecurityRequirement( name = "acceptance_timekeeperOAuth2" ,scopes = { "profile"}) +} + , externalDocs = @ExternalDocumentation(url = "https://lunatech.atlassian.net/wiki/spaces/INTRANET/pages/1609695253/Timekeeper", description = "Lunatech doc about TimeKeeper on Confluence") + +) +// Quarkus Issue pending with redirect and OAuth2 here https://github.com/quarkusio/quarkus/issues/4766 +// To fix this issue I extracted the swagger oauth2-redirect.html file and saved it in the timekeeper folder +@SecurityScheme( + securitySchemeName = "dev_timekeeperOAuth2", + type = SecuritySchemeType.OAUTH2, + description = "authentication for OAuth2 access", + flows = @OAuthFlows( + implicit = @OAuthFlow(authorizationUrl = "http://localhost:8082/auth/realms/Timekeeper/protocol/openid-connect/auth") + ) ) +@SecurityScheme( + securitySchemeName = "acceptance_timekeeperOAuth2", + type = SecuritySchemeType.OAUTH2, + description = "authentication for OAuth2 access", + flows = @OAuthFlows( + implicit = @OAuthFlow(authorizationUrl = "https://acceptance.api.timekeeper.lunatech.fr/auth/realms/Timekeeper/protocol/openid-connect/auth") + ) +) + public class TimeKeeperApplication extends Application { } diff --git a/src/main/resources/META-INF/resources/oauth2-redirect.html b/src/main/resources/META-INF/resources/oauth2-redirect.html new file mode 100644 index 000000000..3bd096553 --- /dev/null +++ b/src/main/resources/META-INF/resources/oauth2-redirect.html @@ -0,0 +1,69 @@ + + +Timekeeper - Swagger UI: OAuth2 Redirect + +
Please wait...
+ + +