From 421ae3bfa4cc9af31071335e212bd2032c6923c2 Mon Sep 17 00:00:00 2001 From: pujavs <43700552+pujavs@users.noreply.github.com> Date: Thu, 22 Aug 2024 14:57:47 +0530 Subject: [PATCH] feat(config-api): new fido2 endpoint, swagger spec changes for SAML TR , Acr endpoint enhancement (#9240) * fix(config-api): asset mgt endpoint fixes Signed-off-by: pujavs * feat(config-api): asset upload mgt ehancement and fido Signed-off-by: pujavs * feat(config-api): asset upload mgt ehancement and fido Signed-off-by: pujavs * feat(config-api): asset upload mgt ehancement and fido Signed-off-by: pujavs * fix(config-api): asset upload Signed-off-by: pujavs * fix(config-api): lock review comments Signed-off-by: pujavs * feat(config-api): lock code review comments Signed-off-by: pujavs * feat(config-api): lock master renamed to lock server Signed-off-by: pujavs * feat(config-api): lock master renamed to lock server Signed-off-by: pujavs * feat(config-api): lock master renamed to lock server Signed-off-by: pujavs * feat(config-api): lock master renamed to lock server Signed-off-by: pujavs * feat(config-api): fido2 delete functionality Signed-off-by: pujavs * fix(config-api): acr validation Signed-off-by: pujavs * feat(config-api): doc(config-api): IDP schema attribute descriptions #9187 Signed-off-by: pujavs * feat(config-api): sync with main Signed-off-by: pujavs * feat(config-api): uploading assets via API generates 2 entries #9178 Signed-off-by: pujavs * feat(config-api): asset mgt, fido and IDP changes Signed-off-by: pujavs * feat(config-api): fido2 device endpoint Signed-off-by: pujavs * feat(config-api): fido2 endpoint Signed-off-by: pujavs * feat(config-api): fido2 endpoint Signed-off-by: pujavs * feat(config-api): sync with main Signed-off-by: pujavs * feat(config-api): sync with main Signed-off-by: pujavs * feat(config-api): sync with main Signed-off-by: pujavs * feat(config-api): resolved sonar review issues Signed-off-by: pujavs * feat(config-api): sonar review comment fix Signed-off-by: pujavs --------- Signed-off-by: pujavs Former-commit-id: a7d134e7b17b4dd503ec871908ce083365473129 --- .../configuration/ApiAppConfiguration.java | 39 +++-- .../configapi/util/ApiAccessConstants.java | 3 - .../docs/jans-config-api-swagger.yaml | 41 +++-- .../plugins/docs/fido2-plugin-swagger.yaml | 142 +++++++++++++++- .../plugins/docs/kc-saml-plugin-swagger.yaml | 40 +++++ .../plugins/docs/user-mgt-plugin-swagger.yaml | 4 +- .../plugin/fido2/rest/ApiApplication.java | 12 +- .../fido2/rest/Fido2ConfigResource.java | 9 +- .../fido2/rest/Fido2RegistrationResource.java | 119 +++++++++++-- .../service/Fido2RegistrationService.java | 160 +++++++++++++++--- .../plugin/fido2/util/Constants.java | 11 ++ .../plugin/saml/model/IdentityProvider.java | 31 ++++ .../default/config-api-test.properties | 2 +- .../profiles/jans-ui.jans.io/test.properties | 2 +- .../test.properties | 2 +- .../profiles/local/test.properties | 2 +- .../rest/resource/auth/AcrsResource.java | 65 +++++-- .../configapi/service/auth/AssetService.java | 24 ++- .../main/resources/config-api-rs-protect.json | 72 +++++++- .../jans-config-api/dynamic-conf.json | 3 + 20 files changed, 685 insertions(+), 98 deletions(-) diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/ApiAppConfiguration.java b/jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/ApiAppConfiguration.java index d400a7f7ec3..4753bb6f285 100644 --- a/jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/ApiAppConfiguration.java +++ b/jans-config-api/common/src/main/java/io/jans/configapi/model/configuration/ApiAppConfiguration.java @@ -79,6 +79,9 @@ public class ApiAppConfiguration implements Configuration { @Schema(description = "Maximum number of results per page in search endpoints.") private int maxCount; + @Schema(description = "List of ACR values that should be excluded from active validation check.") + private List acrExclusionList; + @Schema(description = "User attribute that should not be returned in response.") private List userExclusionAttributes; @@ -99,7 +102,7 @@ public class ApiAppConfiguration implements Configuration { @Schema(description = "Asset management configuration details.") private AssetMgtConfiguration assetMgtConfiguration; - + public String getServiceName() { return serviceName; } @@ -287,6 +290,14 @@ public void setMaxCount(int maxCount) { } } + public List getAcrExclusionList() { + return acrExclusionList; + } + + public void setAcrExclusionList(List acrExclusionList) { + this.acrExclusionList = acrExclusionList; + } + public List getUserExclusionAttributes() { return userExclusionAttributes; } @@ -345,20 +356,22 @@ public void setAssetMgtConfiguration(AssetMgtConfiguration assetMgtConfiguration @Override public String toString() { - return "ApiAppConfiguration [serviceName="+serviceName+", configOauthEnabled=" + configOauthEnabled + ", disableLoggerTimer=" - + disableLoggerTimer + ", disableAuditLogger=" + disableAuditLogger + return "ApiAppConfiguration [serviceName=" + serviceName + ", configOauthEnabled=" + configOauthEnabled + + ", disableLoggerTimer=" + disableLoggerTimer + ", disableAuditLogger=" + disableAuditLogger + ", customAttributeValidationEnabled=" + customAttributeValidationEnabled + ", acrValidationEnabled=" + acrValidationEnabled + ", apiApprovedIssuer=" + apiApprovedIssuer + ", apiProtectionType=" - + apiProtectionType + ", apiClientId=" + apiClientId + ", endpointInjectionEnabled=" - + endpointInjectionEnabled + ", authIssuerUrl=" + authIssuerUrl + ", authOpenidConfigurationUrl=" - + authOpenidConfigurationUrl + ", authOpenidIntrospectionUrl=" + authOpenidIntrospectionUrl - + ", authOpenidTokenUrl=" + authOpenidTokenUrl + ", authOpenidRevokeUrl=" + authOpenidRevokeUrl - + ", exclusiveAuthScopes=" + exclusiveAuthScopes + ", corsConfigurationFilters=" + + apiProtectionType + ", apiClientId=" + apiClientId + + ", endpointInjectionEnabled=" + endpointInjectionEnabled + ", authIssuerUrl=" + authIssuerUrl + + ", authOpenidConfigurationUrl=" + authOpenidConfigurationUrl + ", authOpenidIntrospectionUrl=" + + authOpenidIntrospectionUrl + ", authOpenidTokenUrl=" + authOpenidTokenUrl + ", authOpenidRevokeUrl=" + + authOpenidRevokeUrl + ", exclusiveAuthScopes=" + exclusiveAuthScopes + ", corsConfigurationFilters=" + corsConfigurationFilters + ", loggingLevel=" + loggingLevel + ", loggingLayout=" + loggingLayout + ", externalLoggerConfiguration=" + externalLoggerConfiguration + ", disableJdkLogger=" - + disableJdkLogger + ", maxCount=" + maxCount + ", userExclusionAttributes=" + userExclusionAttributes - + ", userMandatoryAttributes=" + userMandatoryAttributes + ", agamaConfiguration=" + agamaConfiguration - + ", auditLogConf=" + auditLogConf + ", dataFormatConversionConf=" + dataFormatConversionConf - + ", plugins=" + plugins + ", assetMgtConfiguration=" + assetMgtConfiguration + "]"; - } + + disableJdkLogger + ", maxCount=" + maxCount + ", acrExclusionList=" + acrExclusionList + + ", userExclusionAttributes=" + userExclusionAttributes + ", userMandatoryAttributes=" + + userMandatoryAttributes + ", agamaConfiguration=" + agamaConfiguration + ", auditLogConf=" + + auditLogConf + ", dataFormatConversionConf=" + dataFormatConversionConf + ", plugins=" + plugins + + ", assetMgtConfiguration=" + assetMgtConfiguration + "]"; + } + } diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiAccessConstants.java b/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiAccessConstants.java index f9d4ad07c6f..b69ce14b6c9 100644 --- a/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiAccessConstants.java +++ b/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiAccessConstants.java @@ -8,9 +8,6 @@ private ApiAccessConstants() { public static final String JANS_AUTH_CONFIG_READ_ACCESS = "https://jans.io/oauth/jans-auth-server/config/properties.readonly"; public static final String JANS_AUTH_CONFIG_WRITE_ACCESS = "https://jans.io/oauth/jans-auth-server/config/properties.write"; - public static final String FIDO2_CONFIG_READ_ACCESS = "https://jans.io/oauth/config/fido2.readonly"; - public static final String FIDO2_CONFIG_WRITE_ACCESS = "https://jans.io/oauth/config/fido2.write"; - public static final String ATTRIBUTES_READ_ACCESS = "https://jans.io/oauth/config/attributes.readonly"; public static final String ATTRIBUTES_WRITE_ACCESS = "https://jans.io/oauth/config/attributes.write"; public static final String ATTRIBUTES_DELETE_ACCESS = "https://jans.io/oauth/config/attributes.delete"; diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 0028cfa04d7..3c68a5cd94b 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -8366,21 +8366,21 @@ components: $ref: '#/components/schemas/AttributeValidation' tooltip: type: string + selected: + type: boolean + whitePagesCanView: + type: boolean userCanView: type: boolean userCanEdit: type: boolean - adminCanView: - type: boolean adminCanEdit: type: boolean - adminCanAccess: + adminCanView: type: boolean userCanAccess: type: boolean - selected: - type: boolean - whitePagesCanView: + adminCanAccess: type: boolean baseDn: type: string @@ -8531,6 +8531,15 @@ components: type: array items: type: string + applyXFrameOptionsHeaderIfUriContainsAny: + type: array + items: + type: string + xframeOptionsHeaderValue: + type: string + enum: + - SAMEORIGIN + - DENY responseTypesSupported: uniqueItems: true type: array @@ -9217,8 +9226,6 @@ components: type: boolean lockMessageConfig: $ref: '#/components/schemas/LockMessageConfig' - fapi: - type: boolean allResponseTypesSupported: uniqueItems: true type: array @@ -9228,6 +9235,8 @@ components: - code - token - id_token + fapi: + type: boolean AuthenticationFilter: required: - baseDn @@ -9994,10 +10003,10 @@ components: type: array items: type: object - displayValue: - type: string value: type: object + displayValue: + type: string LocalizedString: type: object properties: @@ -10109,6 +10118,14 @@ components: type: integer description: Maximum number of results per page in search endpoints. format: int32 + acrExclusionList: + type: array + description: List of ACR values that should be excluded from active validation + check. + items: + type: string + description: List of ACR values that should be excluded from active validation + check. userExclusionAttributes: type: array description: User attribute that should not be returned in response. @@ -10352,14 +10369,14 @@ components: type: boolean internal: type: boolean + locationPath: + type: string locationType: type: string enum: - ldap - db - file - locationPath: - type: string baseDn: type: string ScriptError: diff --git a/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml b/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml index 0fc0be84241..c0853c4b7c3 100644 --- a/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/fido2-plugin-swagger.yaml @@ -14,6 +14,7 @@ servers: description: The Jans server tags: - name: Fido2 - Configuration +- name: Fido2 - Registration paths: /fido2/fido2-config: get: @@ -62,6 +63,46 @@ paths: security: - oauth2: - https://jans.io/oauth/config/fido2.write + /fido2/registration/device/{uuid}: + delete: + tags: + - Fido2 - Registration + summary: Delete Fido2 Device Data based on device UID + description: Delete Fido2 Device Data based on device UID + operationId: delete-fido2-device-data + parameters: + - name: uuid + in: path + description: Unique identifier string (UUID) assigned to device. + required: true + schema: + type: string + responses: + "204": + description: No Content + "400": + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ApiError' + "401": + description: Unauthorized + "404": + description: Not Found + content: + application/json: + schema: + $ref: '#/components/schemas/ApiError' + "500": + description: InternalServerError + content: + application/json: + schema: + $ref: '#/components/schemas/ApiError' + security: + - oauth2: + - https://jans.io/oauth/config/fido2.delete /fido2/registration/entries/{username}: get: tags: @@ -92,6 +133,75 @@ paths: security: - oauth2: - https://jans.io/oauth/config/fido2.readonly + /fido2/registration: + get: + tags: + - Fido2 - Registration + summary: Get a list of Fido2RegistrationEntry. + description: Get a list of Fido2RegistrationEntry. + operationId: get-fido2-registration-data + parameters: + - name: limit + in: query + description: Search size - max size of the results to return + schema: + type: integer + format: int32 + default: 50 + - name: pattern + in: query + description: Search pattern + schema: + type: string + default: "" + - name: startIndex + in: query + description: The 1-based index of the first query result + schema: + type: integer + format: int32 + default: 0 + - name: sortBy + in: query + description: Data whose value will be used to order the returned response + schema: + type: string + default: jansId + - name: sortOrder + in: query + description: Order in which the sortBy param is applied. Allowed values are + "ascending" and "descending" + schema: + type: string + default: ascending + - name: fieldValuePair + in: query + description: Field and value pair for seraching + schema: + type: string + default: "" + examples: + Field value example: + description: Field value example + value: "mail=abc@mail.com,jansStatus=true" + responses: + "200": + description: Ok + content: + application/json: + schema: + $ref: '#/components/schemas/Fido2RegistrationEntryPagedResult' + examples: + Response example: + description: Response example + value: "" + "401": + description: Unauthorized + "500": + description: InternalServerError + security: + - oauth2: + - https://jans.io/oauth/config/fido2.readonly components: schemas: AppConfiguration: @@ -187,6 +297,15 @@ components: type: array items: type: string + ApiError: + type: object + properties: + code: + type: string + message: + type: string + description: + type: string Fido2DeviceData: type: object properties: @@ -328,6 +447,22 @@ components: writeOnly: true baseDn: type: string + Fido2RegistrationEntryPagedResult: + type: object + properties: + start: + type: integer + format: int32 + totalEntriesCount: + type: integer + format: int32 + entriesCount: + type: integer + format: int32 + entries: + type: array + items: + $ref: '#/components/schemas/Fido2RegistrationEntry' securitySchemes: oauth2: type: oauth2 @@ -335,7 +470,6 @@ components: clientCredentials: tokenUrl: "https://{op-hostname}/.../token" scopes: - https://jans.io/oauth/config/fido2.readonly: View fido2 configuration - related information - https://jans.io/oauth/config/fido2.write: Manage fido2 configuration related - information + https://jans.io/oauth/config/fido2.readonly: View fido2 related information + https://jans.io/oauth/config/fido2.write: Manage fido2 related information + https://jans.io/oauth/config/fido2.delete: Delete fido2 related information diff --git a/jans-config-api/plugins/docs/kc-saml-plugin-swagger.yaml b/jans-config-api/plugins/docs/kc-saml-plugin-swagger.yaml index 35af61863a2..a51a5c5ddc7 100644 --- a/jans-config-api/plugins/docs/kc-saml-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/kc-saml-plugin-swagger.yaml @@ -886,66 +886,103 @@ components: type: string inum: type: string + description: Unique identifier. creatorId: type: string + description: Creator of IDP. name: type: string + description: Name uniquely identifies an identity provider. displayName: maxLength: 60 minLength: 0 type: string + description: Identity provider display name. description: maxLength: 500 minLength: 0 type: string + description: Description of Identity provider. realm: type: string + description: Realm in which Identity provider is created. enabled: type: boolean + description: Indicates if Identity provider is enabled. signingCertificate: type: string + description: Digital certificate used to verify the authenticity of the + request. validateSignature: type: string singleLogoutServiceUrl: type: string + description: Url used to send logout requests. nameIDPolicyFormat: type: string + description: ' URI reference corresponding to a name identifier format.' principalAttribute: type: string + description: ' Name or Friendly Name of the attribute used to identify external + users.' principalType: type: string + description: Way to identify and track external users from the assertion. idpEntityId: type: string + description: Entity ID that will be used to uniquely identify this SAML + Service Provider. singleSignOnServiceUrl: type: string + description: Url used to send SAML authentication requests. encryptionPublicKey: type: string + description: Public key to use to encrypt the message. providerId: type: string + description: "IDP provider, should be SAML." trustEmail: type: boolean + description: "If enabled, email provided by this provider is not verified\ + \ even if verification is enabled for the realm." storeToken: type: boolean + description: Enable/disable if tokens must be stored after authenticating + users. addReadTokenRoleOnCreate: type: boolean + description: Enable/disable if new users can read any stored tokens. authenticateByDefault: type: boolean linkOnly: type: boolean + description: "If true, users cannot log in through this provider. They can\ + \ only link to this provider." firstBrokerLoginFlowAlias: type: string + description: "Alias of authentication flow, which is triggered after first\ + \ login with this identity provider. Term 'First Login' means that no\ + \ Keycloak account is currently linked to the authenticated identity provider\ + \ account." postBrokerLoginFlowAlias: type: string + description: "Alias of authentication flow, which is triggered after each\ + \ login with this identity provider." spMetaDataURL: type: string + description: SAML SP metadata file URL. spMetaDataLocation: type: string + description: SP metadata file location. idpMetaDataURL: type: string + description: SAML IDP metadata file URL. idpMetaDataLocation: type: string + description: SAML IDP metadata file location. status: type: string + description: IDP setup status. enum: - active - inactive @@ -953,6 +990,7 @@ components: - register validationStatus: type: string + description: IDP validation status. enum: - In Progress - Success @@ -960,8 +998,10 @@ components: - Failed validationLog: type: array + description: IDP validation log. items: type: string + description: IDP validation log. baseDn: type: string IdentityProviderPagedResult: diff --git a/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml b/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml index 9113a738b01..a23d9c4e828 100644 --- a/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml +++ b/jans-config-api/plugins/docs/user-mgt-plugin-swagger.yaml @@ -863,10 +863,10 @@ components: type: array items: type: object - displayValue: - type: string value: type: object + displayValue: + type: string CustomUser: type: object properties: diff --git a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/ApiApplication.java b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/ApiApplication.java index bc147f040e7..dd01d5ce6b4 100644 --- a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/ApiApplication.java +++ b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/ApiApplication.java @@ -1,6 +1,6 @@ package io.jans.configapi.plugin.fido2.rest; -import io.jans.configapi.util.ApiAccessConstants; +import io.jans.configapi.plugin.fido2.util.Constants; import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.enums.SecuritySchemeType; import io.swagger.v3.oas.annotations.info.*; @@ -18,13 +18,17 @@ license = @License(name = "Apache 2.0", url = "https://github.com/JanssenProject/jans/blob/main/LICENSE")), -tags = { @Tag(name = "Fido2 - Configuration")}, +tags = { @Tag(name = "Fido2 - Configuration"), + @Tag(name = "Fido2 - Registration") + }, servers = { @Server(url = "https://jans.io/", description = "The Jans server") }) @SecurityScheme(name = "oauth2", type = SecuritySchemeType.OAUTH2, flows = @OAuthFlows(clientCredentials = @OAuthFlow(tokenUrl = "https://{op-hostname}/.../token", scopes = { -@OAuthScope(name = ApiAccessConstants.FIDO2_CONFIG_READ_ACCESS, description = "View fido2 configuration related information"), -@OAuthScope(name = ApiAccessConstants.FIDO2_CONFIG_WRITE_ACCESS, description = "Manage fido2 configuration related information")} +@OAuthScope(name = Constants.FIDO2_CONFIG_READ_ACCESS, description = "View fido2 related information"), +@OAuthScope(name = Constants.FIDO2_CONFIG_WRITE_ACCESS, description = "Manage fido2 related information"), +@OAuthScope(name = Constants.FIDO2_CONFIG_DELETE_ACCESS, description = "Delete fido2 related information") +} ))) public class ApiApplication extends Application { diff --git a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2ConfigResource.java b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2ConfigResource.java index 4b89aad3767..20a8d697b7d 100644 --- a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2ConfigResource.java +++ b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2ConfigResource.java @@ -10,7 +10,6 @@ import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.plugin.fido2.service.Fido2Service; import io.jans.configapi.plugin.fido2.util.Fido2Util; -import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.plugin.fido2.util.Constants; import io.jans.fido2.model.conf.AppConfiguration; @@ -48,13 +47,13 @@ public class Fido2ConfigResource extends BaseResource { @Operation(summary = "Gets Jans Authorization Server Fido2 configuration properties", description = "Gets Jans Authorization Server Fido2 configuration properties", operationId = "get-properties-fido2", tags = { "Fido2 - Configuration" }, security = @SecurityRequirement(name = "oauth2", scopes = { - ApiAccessConstants.FIDO2_CONFIG_READ_ACCESS })) + Constants.FIDO2_CONFIG_READ_ACCESS })) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Ok", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AppConfiguration.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "500", description = "InternalServerError") }) @GET - @ProtectedApi(scopes = { ApiAccessConstants.FIDO2_CONFIG_READ_ACCESS }) + @ProtectedApi(scopes = { Constants.FIDO2_CONFIG_READ_ACCESS }) public Response getFido2Configuration() { AppConfiguration appConfiguration = this.fido2Service.find(); logger.debug("FIDO2 details appConfiguration():{}", appConfiguration); @@ -63,14 +62,14 @@ public Response getFido2Configuration() { @Operation(summary = "Updates Fido2 configuration properties", description = "Updates Fido2 configuration properties", operationId = "put-properties-fido2", tags = { "Fido2 - Configuration" }, security = @SecurityRequirement(name = "oauth2", scopes = { - ApiAccessConstants.FIDO2_CONFIG_WRITE_ACCESS })) + Constants.FIDO2_CONFIG_WRITE_ACCESS })) @RequestBody(description = "Fido2Config", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AppConfiguration.class))) @ApiResponses(value = { @ApiResponse(responseCode = "200", description = "Fido2Config", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = AppConfiguration.class))), @ApiResponse(responseCode = "401", description = "Unauthorized"), @ApiResponse(responseCode = "500", description = "InternalServerError") }) @PUT - @ProtectedApi(scopes = { ApiAccessConstants.FIDO2_CONFIG_WRITE_ACCESS }) + @ProtectedApi(scopes = { Constants.FIDO2_CONFIG_WRITE_ACCESS }) public Response updateFido2Configuration(@NotNull AppConfiguration appConfiguration) { logger.debug("FIDO2 details to be updated - appConfiguration:{} ", appConfiguration); checkResourceNotNull(appConfiguration, FIDO2_CONFIGURATION); diff --git a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2RegistrationResource.java b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2RegistrationResource.java index b1441f619bd..5130eba48b7 100644 --- a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2RegistrationResource.java +++ b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/rest/Fido2RegistrationResource.java @@ -1,32 +1,37 @@ package io.jans.configapi.plugin.fido2.rest; +import static io.jans.as.model.util.Util.escapeLog; +import io.jans.configapi.core.model.ApiError; import io.jans.configapi.core.rest.BaseResource; import io.jans.configapi.core.rest.ProtectedApi; import io.jans.configapi.plugin.fido2.service.Fido2RegistrationService; import io.jans.configapi.plugin.fido2.util.Constants; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; +import io.jans.model.SearchRequest; +import io.jans.orm.model.PagedResult; import io.jans.orm.model.fido2.Fido2RegistrationEntry; +import io.jans.util.exception.InvalidAttributeException; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.media.ArraySchema; import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.ExampleObject; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.security.*; - import jakarta.inject.Inject; import jakarta.validation.constraints.NotNull; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; -import org.slf4j.Logger; - import java.util.List; +import org.slf4j.Logger; + @Path(Constants.REGISTRATION) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @@ -38,19 +43,113 @@ public class Fido2RegistrationResource extends BaseResource { @Inject Fido2RegistrationService fido2RegistrationService; + private class Fido2RegistrationEntryPagedResult extends PagedResult { + }; + + @Operation(summary = "Get a list of Fido2RegistrationEntry.", description = "Get a list of Fido2RegistrationEntry.", operationId = "get-fido2-registration-data", tags = { + "Fido2 - Registration" }, security = @SecurityRequirement(name = "oauth2", scopes = { + Constants.FIDO2_CONFIG_READ_ACCESS })) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Ok", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = Fido2RegistrationEntryPagedResult.class), examples = @ExampleObject(name = "Response example", value = "example/fido2/get-all-fido2-data.json"))), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "500", description = "InternalServerError") }) + @GET + @ProtectedApi(scopes = { Constants.FIDO2_CONFIG_READ_ACCESS }, groupScopes = { + Constants.FIDO2_CONFIG_WRITE_ACCESS }, superScopes = { ApiAccessConstants.SUPER_ADMIN_READ_ACCESS }) + public Response getFido2RegistrationEntry( + @Parameter(description = "Search size - max size of the results to return") @DefaultValue(ApiConstants.DEFAULT_LIST_SIZE) @QueryParam(value = ApiConstants.LIMIT) int limit, + @Parameter(description = "Search pattern") @DefaultValue("") @QueryParam(value = ApiConstants.PATTERN) String pattern, + @Parameter(description = "The 1-based index of the first query result") @DefaultValue(ApiConstants.DEFAULT_LIST_START_INDEX) @QueryParam(value = ApiConstants.START_INDEX) int startIndex, + @Parameter(description = "Data whose value will be used to order the returned response") @DefaultValue(Constants.JANSID) @QueryParam(value = ApiConstants.SORT_BY) String sortBy, + @Parameter(description = "Order in which the sortBy param is applied. Allowed values are \"ascending\" and \"descending\"") @DefaultValue(ApiConstants.ASCENDING) @QueryParam(value = ApiConstants.SORT_ORDER) String sortOrder, + @Parameter(description = "Field and value pair for seraching", examples = @ExampleObject(name = "Field value example", value = "mail=abc@mail.com,jansStatus=true")) @DefaultValue("") @QueryParam(value = ApiConstants.FIELD_VALUE_PAIR) String fieldValuePair) { + + if (logger.isInfoEnabled()) { + logger.info( + "Fido2RegistrationEntry search param - limit:{}, pattern:{}, startIndex:{}, sortBy:{}, sortOrder:{}, fieldValuePair:{}", + escapeLog(limit), escapeLog(pattern), escapeLog(startIndex), escapeLog(sortBy), + escapeLog(sortOrder), escapeLog(fieldValuePair)); + } + + SearchRequest searchReq = createSearchRequest( + fido2RegistrationService.getBaseDnForFido2RegistrationEntries(null), pattern, sortBy, sortOrder, + startIndex, limit, null, null, fido2RegistrationService.getRecordMaxCount(), fieldValuePair, + Fido2RegistrationEntry.class); + + return Response.ok(this.doSearch(searchReq)).build(); + } + @Operation(summary = "Get details of connected FIDO2 devices registered to user", description = "Get details of connected FIDO2 devices registered to user", operationId = "get-registration-entries-fido2", tags = { - "Fido2 - Registration" }, security = @SecurityRequirement(name = "oauth2", scopes = { - "https://jans.io/oauth/config/fido2.readonly" })) + "Fido2 - Registration" }, security = @SecurityRequirement(name = "oauth2", scopes = { + Constants.FIDO2_CONFIG_READ_ACCESS })) @ApiResponses(value = { - @ApiResponse(responseCode = "200", description = "Ok", content = @Content(mediaType = MediaType.APPLICATION_JSON, array = @ArraySchema(schema = @Schema(implementation = Fido2RegistrationEntry.class)))), - @ApiResponse(responseCode = "401", description = "Unauthorized"), - @ApiResponse(responseCode = "500", description = "InternalServerError") }) + @ApiResponse(responseCode = "200", description = "Ok", content = @Content(mediaType = MediaType.APPLICATION_JSON, array = @ArraySchema(schema = @Schema(implementation = Fido2RegistrationEntry.class)))), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "500", description = "InternalServerError") }) @GET @Path(Constants.ENTRIES + ApiConstants.USERNAME_PATH) - @ProtectedApi(scopes = {ApiAccessConstants.FIDO2_CONFIG_READ_ACCESS}) - public Response findAllRegisteredByUsername(@Parameter(description = "User name") @PathParam("username") @NotNull String username) { + @ProtectedApi(scopes = { Constants.FIDO2_CONFIG_READ_ACCESS }) + public Response findAllRegisteredByUsername( + @Parameter(description = "User name") @PathParam("username") @NotNull String username) { logger.debug("FIDO2 registration entries by username."); List entries = fido2RegistrationService.findAllRegisteredByUsername(username); return Response.ok(entries).build(); } + + @Operation(summary = "Delete Fido2 Device Data based on device UID", description = "Delete Fido2 Device Data based on device UID", operationId = "delete-fido2-device-data", tags = { + "Fido2 - Registration" }, security = @SecurityRequirement(name = "oauth2", scopes = { + Constants.FIDO2_CONFIG_DELETE_ACCESS })) + @ApiResponses(value = { @ApiResponse(responseCode = "204", description = "No Content"), + @ApiResponse(responseCode = "400", description = "Bad Request", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ApiError.class, description = "BadRequestException"))), + @ApiResponse(responseCode = "401", description = "Unauthorized"), + @ApiResponse(responseCode = "404", description = "Not Found", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ApiError.class, description = "NotFoundException"))), + @ApiResponse(responseCode = "500", description = "InternalServerError", content = @Content(mediaType = MediaType.APPLICATION_JSON, schema = @Schema(implementation = ApiError.class, description = "InternalServerError"))), }) + @DELETE + @Path(Constants.DEVICE + Constants.UUID_PATH) + @ProtectedApi(scopes = { Constants.FIDO2_CONFIG_DELETE_ACCESS }) + public Response deleteFido2DeviceData( + @Parameter(description = "Unique identifier string (UUID) assigned to device.") @PathParam("uuid") @NotNull String uuid) { + if (logger.isInfoEnabled()) { + logger.info("Request to delete Fido2 device identified by uuid:{}", escapeLog(uuid)); + } + + try { + // delete device + fido2RegistrationService.removeFido2RegistrationEntry(uuid); + + if (logger.isInfoEnabled()) { + logger.info("Successfully deleted Fido2 Device with uuid:{}", escapeLog(uuid)); + } + + } catch (InvalidAttributeException iae) { + throwNotFoundException("Not Found", iae.getMessage()); + } catch (Exception ex) { + throwInternalServerException(ex); + } + return Response.noContent().build(); + } + + private Fido2RegistrationEntryPagedResult doSearch(SearchRequest searchReq) { + if (logger.isInfoEnabled()) { + logger.info("User search params - searchReq:{}", escapeLog(searchReq)); + } + + PagedResult pagedResult = fido2RegistrationService.searchFido2Registration(searchReq); + if (logger.isDebugEnabled()) { + logger.debug("Fido2RegistrationEntry - pagedResult:{}", pagedResult); + } + + Fido2RegistrationEntryPagedResult pagedFido2Registration = new Fido2RegistrationEntryPagedResult(); + if (pagedResult != null) { + logger.debug("Users fetched - pagedResult.getEntries():{}", pagedResult.getEntries()); + pagedFido2Registration.setStart(pagedResult.getStart()); + pagedFido2Registration.setEntriesCount(pagedResult.getEntriesCount()); + pagedFido2Registration.setTotalEntriesCount(pagedResult.getTotalEntriesCount()); + pagedFido2Registration.setEntries(pagedResult.getEntries()); + } + + logger.info("Fido2RegistrationEntry pagedFido2Registration:{}", pagedFido2Registration); + return pagedFido2Registration; + + } } diff --git a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/service/Fido2RegistrationService.java b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/service/Fido2RegistrationService.java index 1f3655a42fe..278fe1eccdd 100644 --- a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/service/Fido2RegistrationService.java +++ b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/service/Fido2RegistrationService.java @@ -6,19 +6,33 @@ package io.jans.configapi.plugin.fido2.service; +import static io.jans.as.model.util.Util.escapeLog; +import io.jans.as.common.service.OrganizationService; import io.jans.as.model.config.StaticConfiguration; +import io.jans.configapi.configuration.ConfigurationFactory; +import io.jans.configapi.util.ApiConstants; +import io.jans.model.SearchRequest; import io.jans.orm.PersistenceEntryManager; +import io.jans.orm.model.PagedResult; +import io.jans.orm.model.SortOrder; import io.jans.orm.model.base.SimpleBranch; import io.jans.orm.model.fido2.Fido2RegistrationEntry; import io.jans.orm.model.fido2.Fido2RegistrationStatus; import io.jans.orm.search.filter.Filter; import io.jans.util.StringHelper; +import io.jans.util.exception.InvalidAttributeException; + import jakarta.enterprise.context.ApplicationScoped; import jakarta.inject.Inject; +import jakarta.ws.rs.WebApplicationException; + +import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; /** * @author Yuriy Movchan @@ -33,30 +47,72 @@ public class Fido2RegistrationService { @Inject private StaticConfiguration staticConfiguration; + @Inject + OrganizationService organizationService; + + @Inject + ConfigurationFactory configurationFactory; + @Inject private UserFido2Service userFido2Srv; @Inject private PersistenceEntryManager persistenceEntryManager; - public List findAllByUsername(String username) { - String userInum = userFido2Srv.getUserInum(username); - if (userInum == null) { - return Collections.emptyList(); + public int getRecordMaxCount() { + log.trace(" MaxCount details - ApiAppConfiguration.MaxCount():{}, DEFAULT_MAX_COUNT:{} ", + configurationFactory.getApiAppConfiguration().getMaxCount(), ApiConstants.DEFAULT_MAX_COUNT); + return (configurationFactory.getApiAppConfiguration().getMaxCount() > 0 + ? configurationFactory.getApiAppConfiguration().getMaxCount() + : ApiConstants.DEFAULT_MAX_COUNT); + } + + public PagedResult searchFido2Registration(SearchRequest searchRequest) { + log.info("Search Fido2Registration with searchRequest:{}", searchRequest); + + Filter searchFilter = null; + List filters = new ArrayList<>(); + if (searchRequest.getFilterAssertionValue() != null && !searchRequest.getFilterAssertionValue().isEmpty()) { + + for (String assertionValue : searchRequest.getFilterAssertionValue()) { + String[] targetArray = new String[] { assertionValue }; + + Filter displayNameFilter = Filter.createSubstringFilter("displayName", null, targetArray, null); + Filter descriptionFilter = Filter.createSubstringFilter("jansRegistrationData", null, targetArray, + null); + Filter statusFilter = Filter.createSubstringFilter("jansStatus", null, targetArray, null); + Filter notificationConfFilter = Filter.createSubstringFilter("jansDeviceNotificationConf", null, + targetArray, null); + Filter deviceDataFilter = Filter.createSubstringFilter("jansDeviceData", null, targetArray, null); + Filter personInumFilter = Filter.createSubstringFilter("personInum", null, targetArray, null); + Filter inumFilter = Filter.createSubstringFilter("jansId", null, targetArray, null); + + filters.add(Filter.createORFilter(displayNameFilter, descriptionFilter, statusFilter, + notificationConfFilter, deviceDataFilter, personInumFilter, inumFilter)); + + } + searchFilter = Filter.createORFilter(filters); } - String baseDn = getBaseDnForFido2RegistrationEntries(userInum); - if (persistenceEntryManager.hasBranchesSupport(baseDn)) { - if (!containsBranch(baseDn)) { - return Collections.emptyList(); + log.debug("Fido2Registration pattern searchFilter:{}", searchFilter); + + List fieldValueFilters = new ArrayList<>(); + if (searchRequest.getFieldValueMap() != null && !searchRequest.getFieldValueMap().isEmpty()) { + for (Map.Entry entry : searchRequest.getFieldValueMap().entrySet()) { + Filter dataFilter = Filter.createEqualityFilter(entry.getKey(), entry.getValue()); + log.trace("Fido2Registration dataFilter:{}", dataFilter); + fieldValueFilters.add(Filter.createANDFilter(dataFilter)); } + searchFilter = Filter.createANDFilter(Filter.createORFilter(filters), + Filter.createANDFilter(fieldValueFilters)); } - Filter userFilter = Filter.createEqualityFilter("personInum", userInum); + log.debug("Fido2Registration searchFilter:{}", searchFilter); - List fido2RegistrationnEntries = persistenceEntryManager.findEntries(baseDn, Fido2RegistrationEntry.class, userFilter); + return persistenceEntryManager.findPagedEntries(getDnFido2RegistrationEntry(null), Fido2RegistrationEntry.class, + searchFilter, null, searchRequest.getSortBy(), SortOrder.getByValue(searchRequest.getSortOrder()), + searchRequest.getStartIndex(), searchRequest.getCount(), searchRequest.getMaxCount()); - return fido2RegistrationnEntries; } public List findAllRegisteredByUsername(String username) { @@ -66,17 +122,15 @@ public List findAllRegisteredByUsername(String username) } String baseDn = getBaseDnForFido2RegistrationEntries(userInum); - if (persistenceEntryManager.hasBranchesSupport(baseDn)) { - if (!containsBranch(baseDn)) { - return Collections.emptyList(); - } - } + if (persistenceEntryManager.hasBranchesSupport(baseDn) && !containsBranch(baseDn)) { + return Collections.emptyList(); - Filter registeredFilter = Filter.createEqualityFilter("jansStatus", Fido2RegistrationStatus.registered.getValue()); + } - List fido2RegistrationnEntries = persistenceEntryManager.findEntries(baseDn, Fido2RegistrationEntry.class, registeredFilter); + Filter registeredFilter = Filter.createEqualityFilter("jansStatus", + Fido2RegistrationStatus.registered.getValue()); - return fido2RegistrationnEntries; + return persistenceEntryManager.findEntries(baseDn, Fido2RegistrationEntry.class, registeredFilter); } public String getBaseDnForFido2RegistrationEntries(String userInum) { @@ -100,4 +154,72 @@ public String getDnForUser(String userInum) { public boolean containsBranch(final String baseDn) { return persistenceEntryManager.contains(baseDn, SimpleBranch.class); } + + public void removeFido2RegistrationEntry(String uuid) { + if (log.isInfoEnabled()) { + log.info("Remove Fido2RegistrationEntry request for device with uuid:{}", escapeLog(uuid)); + } + + if (StringUtils.isBlank(uuid)) { + throw new InvalidAttributeException("Device uuid is null!"); + } + + Fido2RegistrationEntry fido2RegistrationEntry = this.getFido2RegistrationEntryByDeviceId(uuid); + log.debug("Fido2RegistrationEntry identified by uuid:{} is:{}", uuid, fido2RegistrationEntry); + if (fido2RegistrationEntry == null) { + throw new InvalidAttributeException("No device found with uuid:{" + uuid + "}"); + } + + String dn = this.getDnFido2RegistrationEntry(fido2RegistrationEntry.getId()); + log.info("Remove Fido2RegistrationEntry with dn:{}", dn); + + // delete entry + persistenceEntryManager.removeRecursively(dn, Fido2RegistrationEntry.class); + + // verify post delete + fido2RegistrationEntry = this.getFido2RegistrationEntryByDeviceId(uuid); + if (fido2RegistrationEntry != null) { + throw new WebApplicationException( + "Fido2RegistrationEntry device with uuid:{" + uuid + "} could not be deleted!"); + } + log.info("Successfully deleted Fido2RegistrationEntry device with uuid:{}", uuid); + } + + public Fido2RegistrationEntry getFido2RegistrationEntryByDeviceId(String uuid) { + log.info("Get Fido2RegistrationEntry with device uuid:{}", uuid); + + if (StringUtils.isBlank(uuid)) { + throw new InvalidAttributeException("Device uuid is null!"); + } + + Fido2RegistrationEntry fido2RegistrationEntry = null; + try { + String[] targetArray = new String[] { uuid }; + Filter filter = Filter.createSubstringFilter("jansDeviceData", null, targetArray, null); + log.debug("Find device filter:{}", filter); + + List fido2List = persistenceEntryManager + .findEntries(getDnFido2RegistrationEntry(null), Fido2RegistrationEntry.class, filter); + log.debug("Fetched Fido2RegistrationEntry by uuid:{} are fido2List:{}", uuid, fido2List); + + if (fido2List != null && !fido2List.isEmpty()) { + fido2RegistrationEntry = fido2List.get(0); + } + + log.info("Fido2RegistrationEntry by uuid:{} are fido2RegistrationEntry:{}", uuid, fido2RegistrationEntry); + + } catch (Exception e) { + log.error("Error while finding Fido2RegistrationEntry with device uuid:{} is {}" + uuid, e); + } + return fido2RegistrationEntry; + } + + public String getDnFido2RegistrationEntry(String inum) { + String orgDn = organizationService.getDnForOrganization(); + if (StringHelper.isEmpty(inum)) { + return String.format("ou=fido2_register,%s", orgDn); + } + return String.format("jansId=%s,ou=fido2_register,%s", inum, orgDn); + } + } diff --git a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/util/Constants.java b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/util/Constants.java index 549312017e2..2097fc5f8b1 100644 --- a/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/util/Constants.java +++ b/jans-config-api/plugins/fido2-plugin/src/main/java/io/jans/configapi/plugin/fido2/util/Constants.java @@ -13,4 +13,15 @@ private Constants() {} public static final String FIDO2_CONFIG = "/fido2-config"; public static final String REGISTRATION = "/registration"; public static final String ENTRIES = "/entries"; + public static final String DEVICE = "/device"; + public static final String USER_DEVICE = "/userdevice"; + + public static final String USERNAME_PATH = "/{username}"; + public static final String UUID_PATH = "/{uuid}"; + + public static final String JANSID = "jansId"; + + public static final String FIDO2_CONFIG_READ_ACCESS = "https://jans.io/oauth/config/fido2.readonly"; + public static final String FIDO2_CONFIG_WRITE_ACCESS = "https://jans.io/oauth/config/fido2.write"; + public static final String FIDO2_CONFIG_DELETE_ACCESS = "https://jans.io/oauth/config/fido2.delete"; } \ No newline at end of file diff --git a/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/IdentityProvider.java b/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/IdentityProvider.java index 2fdc8d5f9ad..3579ceb4a08 100644 --- a/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/IdentityProvider.java +++ b/jans-config-api/plugins/kc-saml-plugin/src/main/java/io/jans/configapi/plugin/saml/model/IdentityProvider.java @@ -22,6 +22,8 @@ import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; +import io.swagger.v3.oas.annotations.media.Schema; + @DataEntry(sortBy = { "displayName" }) @ObjectClass(value = "jansTrustedIdp") @JsonInclude(JsonInclude.Include.NON_NULL) @@ -29,82 +31,104 @@ public class IdentityProvider extends Entry implements Serializable { @AttributeName(ignoreDuringUpdate = true) + @Schema(description = "Unique identifier.") private String inum; @NotNull @AttributeName + @Schema(description = "Creator of IDP.") private String creatorId; @NotNull @AttributeName(name = "name") + @Schema(description = "Name uniquely identifies an identity provider.") private String name; @NotNull @Size(min = 0, max = 60, message = "Length of the Display Name should not exceed 60") @AttributeName + @Schema(description = "Identity provider display name.") private String displayName; @NotNull @Size(min = 0, max = 500, message = "Length of the Description should not exceed 500") @AttributeName + @Schema(description = "Description of Identity provider.") private String description; @NotNull @AttributeName(name = "realm") + @Schema(description = "Realm in which Identity provider is created.") private String realm; @AttributeName(name = "jansEnabled") + @Schema(description = "Indicates if Identity provider is enabled.") private boolean enabled; @AttributeName(name = "signingCertificate") + @Schema(description = "Digital certificate used to verify the authenticity of the request.") private String signingCertificate; @AttributeName(name = "validateSignature") private String validateSignature; @AttributeName(name = "singleLogoutServiceUrl") + @Schema(description = "Url used to send logout requests.") private String singleLogoutServiceUrl; @AttributeName(name = "nameIDPolicyFormat") + @Schema(description = " URI reference corresponding to a name identifier format.") private String nameIDPolicyFormat; @AttributeName(name = "principalAttribute") + @Schema(description = " Name or Friendly Name of the attribute used to identify external users.") private String principalAttribute; @AttributeName(name = "principalType") + @Schema(description = "Way to identify and track external users from the assertion.") private String principalType; @AttributeName(name = "entityId") + @Schema(description = "Entity ID that will be used to uniquely identify this SAML Service Provider.") private String idpEntityId; @AttributeName(name = "singleSignOnServiceUrl") + @Schema(description = "Url used to send SAML authentication requests.") private String singleSignOnServiceUrl; @AttributeName(name = "encryptionPublicKey") + @Schema(description = "Public key to use to encrypt the message.") private String encryptionPublicKey; @AttributeName + @Schema(description = "IDP provider, should be SAML.") private String providerId; @AttributeName + @Schema(description = "If enabled, email provided by this provider is not verified even if verification is enabled for the realm.") private boolean trustEmail; @AttributeName + @Schema(description = "Enable/disable if tokens must be stored after authenticating users.") private boolean storeToken; @AttributeName + @Schema(description = "Enable/disable if new users can read any stored tokens.") private boolean addReadTokenRoleOnCreate; @AttributeName private boolean authenticateByDefault; @AttributeName + @Schema(description = "If true, users cannot log in through this provider. They can only link to this provider.") private boolean linkOnly; @AttributeName + @Schema(description = "Alias of authentication flow, which is triggered after first login with this identity provider. Term 'First Login' means that no Keycloak account is currently linked to the authenticated identity provider account.") private String firstBrokerLoginFlowAlias; @AttributeName + @Schema(description = "Alias of authentication flow, which is triggered after each login with this identity provider.") private String postBrokerLoginFlowAlias; @AttributeName(name = "jansSAMLspMetaDataFN") @@ -112,9 +136,11 @@ public class IdentityProvider extends Entry implements Serializable { private String spMetaDataFN; @AttributeName(name = "jansSAMLspMetaDataURL") + @Schema(description = "SAML SP metadata file URL.") private String spMetaDataURL; @AttributeName(name = "jansSAMLspMetaLocation") + @Schema(description = "SP metadata file location.") private String spMetaDataLocation; @AttributeName(name = "jansSAMLidpMetaDataFN") @@ -122,18 +148,23 @@ public class IdentityProvider extends Entry implements Serializable { private String idpMetaDataFN; @AttributeName(name = "jansSAMLidpMetaDataURL") + @Schema(description = "SAML IDP metadata file URL.") private String idpMetaDataURL; @AttributeName(name = "jansSAMLidpMetaLocation") + @Schema(description = "SAML IDP metadata file location.") private String idpMetaDataLocation; @AttributeName(name = "jansStatus") + @Schema(description = "IDP setup status.") private GluuStatus status; @AttributeName(name = "jansValidationStatus") + @Schema(description = "IDP validation status.") private ValidationStatus validationStatus; @AttributeName(name = "jansValidationLog") + @Schema(description = "IDP validation log.") private List validationLog; public String getInum() { diff --git a/jans-config-api/profiles/default/config-api-test.properties b/jans-config-api/profiles/default/config-api-test.properties index b08bf6d38c1..3711c79d887 100644 --- a/jans-config-api/profiles/default/config-api-test.properties +++ b/jans-config-api/profiles/default/config-api-test.properties @@ -1,7 +1,7 @@ # The URL of your Jans installation test.server=https://jenkins-config-api.gluu.org -test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write +test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write token.endpoint=https://jenkins-config-api.gluu.org/jans-auth/restv1/token token.grant.type=client_credentials diff --git a/jans-config-api/profiles/jans-ui.jans.io/test.properties b/jans-config-api/profiles/jans-ui.jans.io/test.properties index bf72142fb26..3ccb666fa39 100644 --- a/jans-config-api/profiles/jans-ui.jans.io/test.properties +++ b/jans-config-api/profiles/jans-ui.jans.io/test.properties @@ -1,4 +1,4 @@ -test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write +test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write # Test env Setting token.endpoint=https://jans-ui.jans.io/jans-auth/restv1/token diff --git a/jans-config-api/profiles/jenkins-config-api.gluu.org/test.properties b/jans-config-api/profiles/jenkins-config-api.gluu.org/test.properties index 5e63322174c..adf5c6ba663 100644 --- a/jans-config-api/profiles/jenkins-config-api.gluu.org/test.properties +++ b/jans-config-api/profiles/jenkins-config-api.gluu.org/test.properties @@ -1,6 +1,6 @@ test.server=https://jenkins-config-api.gluu.org -test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write +test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write token.endpoint=https://jenkins-config-api.gluu.org/jans-auth/restv1/token token.grant.type=client_credentials diff --git a/jans-config-api/profiles/local/test.properties b/jans-config-api/profiles/local/test.properties index 00d84095938..0760b0986ab 100644 --- a/jans-config-api/profiles/local/test.properties +++ b/jans-config-api/profiles/local/test.properties @@ -1,5 +1,5 @@ #LOCAL -test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write +test.scopes=https://jans.io/oauth/config/acrs.readonly https://jans.io/oauth/config/acrs.write https://jans.io/oauth/config/attributes.readonly https://jans.io/oauth/config/attributes.write https://jans.io/oauth/config/attributes.delete https://jans.io/oauth/config/cache.readonly https://jans.io/oauth/config/cache.write https://jans.io/oauth/config/openid/clients.readonly https://jans.io/oauth/config/openid/clients.write https://jans.io/oauth/config/openid/clients.delete https://jans.io/oauth/jans-auth-server/config/properties.readonly https://jans.io/oauth/jans-auth-server/config/properties.write https://jans.io/oauth/config/smtp.readonly https://jans.io/oauth/config/smtp.write https://jans.io/oauth/config/smtp.delete https://jans.io/oauth/config/scripts.readonly https://jans.io/oauth/config/scripts.write https://jans.io/oauth/config/scripts.delete https://jans.io/oauth/config/fido2.readonly https://jans.io/oauth/config/fido2.write https://jans.io/oauth/config/fido2.delete https://jans.io/oauth/config/jwks.readonly https://jans.io/oauth/config/jwks.write https://jans.io/oauth/config/jwks.delete https://jans.io/oauth/config/database/ldap.readonly https://jans.io/oauth/config/database/ldap.write https://jans.io/oauth/config/database/ldap.delete https://jans.io/oauth/config/logging.readonly https://jans.io/oauth/config/logging.write https://jans.io/oauth/config/scopes.readonly https://jans.io/oauth/config/scopes.write https://jans.io/oauth/config/scopes.delete https://jans.io/oauth/config/uma/resources.readonly https://jans.io/oauth/config/uma/resources.write https://jans.io/oauth/config/uma/resources.delete https://jans.io/oauth/config/database/sql.readonly https://jans.io/oauth/config/database/sql.write https://jans.io/oauth/config/database/sql.delete https://jans.io/oauth/config/stats.readonly jans_stat https://jans.io/scim/users.read https://jans.io/scim/users.write https://jans.io/oauth/config/scim/users.read https://jans.io/oauth/config/scim/users.write https://jans.io/scim/config.readonly https://jans.io/scim/config.write https://jans.io/oauth/config/organization.readonly https://jans.io/oauth/config/organization.write https://jans.io/oauth/config/user.readonly https://jans.io/oauth/config/user.write https://jans.io/oauth/config/user.delete https://jans.io/oauth/config/agama.readonly https://jans.io/oauth/config/agama.write https://jans.io/oauth/config/agama.delete https://jans.io/oauth/jans-auth-server/session.readonly https://jans.io/oauth/jans-auth-server/session.delete revoke_session https://jans.io/oauth/config/read-all https://jans.io/oauth/config/write-all https://jans.io/oauth/config/delete-all https://jans.io/oauth/config/openid-read https://jans.io/oauth/config/openid-write https://jans.io/oauth/config/openid-delete https://jans.io/oauth/config/uma-read https://jans.io/oauth/config/uma-write https://jans.io/oauth/config/uma-delete https://jans.io/oauth/jans-auth-server/config/adminui/user/role.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/role.write https://jans.io/oauth/jans-auth-server/config/adminui/read-all https://jans.io/oauth/jans-auth-server/config/adminui/write-all https://jans.io/oauth/jans-auth-server/config/adminui/user/role.delete https://jans.io/oauth/jans-auth-server/config/adminui/delete-all https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.write https://jans.io/oauth/jans-auth-server/config/adminui/user/permission.delete https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.readonly https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.write https://jans.io/oauth/jans-auth-server/config/adminui/user/rolePermissionMapping.delete https://jans.io/oauth/jans-auth-server/config/adminui/license.readonly https://jans.io/oauth/jans-auth-server/config/adminui/license.write https://jans.io/oauth/config/plugin.readonly https://jans.io/oauth/client/authorizations.readonly https://jans.io/oauth/client/authorizations.delete https://jans.io/oauth/config/cacherefresh.readonly https://jans.io/oauth/config/cacherefresh.write https://jans.io/oauth/config/saml.readonly https://jans.io/oauth/config/saml.write https://jans.io/oauth/config/saml-config.readonly https://jans.io/oauth/config/saml-config.write https://jans.io/oauth/config/saml-client-scope.readonly https://jans.io/oauth/config/saml-client-scope.write https://jans.io/idp/config.readonly https://jans.io/idp/config.write https://jans.io/idp/realm.readonly https://jans.io/idp/realm.write https://jans.io/idp/realm.write https://jans.io/idp/saml.readonly https://jans.io/idp/saml.write https://jans.io/oauth/config/app-version.readonly https://jans.io/oauth/kc-link-config.readonly https://jans.io/oauth/kc-link-config.write https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://pujavs-definite-dory.gluu.info/jans-config-api/api/v1/jans-assets/upload-asset https://jans.io/oauth/config/jans_asset-write https://jans.io/oauth/config/jans_asset-delete https://jans.io/oauth/lock/read-all https://jans.io/oauth/lock/write-all https://jans.io/oauth/lock-config.readonly https://jans.io/oauth/lock-config.write https://jans.io/oauth/lock/audit.readonly https://jans.io/oauth/lock/audit.write https://jans.io/oauth/lock/health.readonly https://jans.io/oauth/lock/health.write https://jans.io/oauth/lock/log.readonly https://jans.io/oauth/lock/log.write https://jans.io/oauth/lock/telemetry.readonly https://jans.io/oauth/lock/telemetry.write # jans.server token.endpoint=https://jans.server3/jans-auth/restv1/token diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AcrsResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AcrsResource.java index ac843ceac0b..5c4e334be94 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AcrsResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AcrsResource.java @@ -12,9 +12,11 @@ import io.jans.configapi.model.configuration.ApiAppConfiguration; import io.jans.configapi.rest.model.AuthenticationMethod; import io.jans.configapi.service.auth.ConfigurationService; +import io.jans.configapi.service.auth.LdapConfigurationService; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; import io.jans.model.custom.script.model.CustomScript; +import io.jans.model.ldap.GluuLdapConfiguration; import io.jans.service.custom.CustomScriptService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.parameters.RequestBody; @@ -26,6 +28,7 @@ import io.swagger.v3.oas.annotations.security.*; import java.util.List; +import java.util.Optional; import org.apache.commons.lang.StringUtils; @@ -57,6 +60,9 @@ public class AcrsResource extends ConfigBaseResource { @Inject CustomScriptService customScriptService; + @Inject + LdapConfigurationService ldapConfigurationService; + @Operation(summary = "Gets default authentication method.", description = "Gets default authentication method.", operationId = "get-acrs", tags = { "Default Authentication Method" }, security = @SecurityRequirement(name = "oauth2", scopes = { ApiAccessConstants.ACRS_READ_ACCESS, ApiAccessConstants.ACRS_WRITE_ACCESS, @@ -89,13 +95,13 @@ public Response getDefaultAuthenticationMethod() { @ProtectedApi(scopes = { ApiAccessConstants.ACRS_WRITE_ACCESS }, superScopes = { ApiAccessConstants.SUPER_ADMIN_WRITE_ACCESS }) public Response updateDefaultAuthenticationMethod(@NotNull AuthenticationMethod authenticationMethod) { - log.debug("ACRS details to update - authenticationMethod:{}", authenticationMethod); + log.info("ACRS details to update - authenticationMethod:{}", authenticationMethod); if (authenticationMethod == null || StringUtils.isBlank(authenticationMethod.getDefaultAcr())) { throwBadRequestException("Default authentication method should not be null or empty !"); } - if (authenticationMethod != null) { + if (StringUtils.isNotBlank(authenticationMethod.getDefaultAcr())) { validateAuthenticationMethod(authenticationMethod.getDefaultAcr()); final GluuConfiguration gluuConfiguration = configurationService.findGluuConfiguration(); @@ -106,25 +112,54 @@ public Response updateDefaultAuthenticationMethod(@NotNull AuthenticationMethod } private void validateAuthenticationMethod(String authenticationMode) { - log.debug("\n\n\n authenticationMethod:{}, appConfiguration.isAcrValidationEnabled():{}", authenticationMode, + log.debug("authenticationMethod:{}, appConfiguration.isAcrValidationEnabled():{}", authenticationMode, appConfiguration.isAcrValidationEnabled()); - List activeScripts = customScriptService.findActiveCustomScripts(); - log.debug("\n\n\n activeScripts:{}", activeScripts); - if (!appConfiguration.isAcrValidationEnabled() || StringUtils.isBlank(authenticationMode) - || activeScripts == null || activeScripts.isEmpty()) { - return; + // if authentication validation check is enabled then validate + boolean isAcrValid = isAcrValid(authenticationMode); + log.debug("isAcrValid:{}",isAcrValid); + if (appConfiguration.isAcrValidationEnabled() && (!isAcrValid)) { + throwBadRequestException("INVALID_ACR", + String.format("Authentication script {%s} is not valid/active", authenticationMode)); + } + } + + private boolean isAcrValid(String authenticationMode) { + boolean isValid = false; + log.debug(" Validate ACR being set - authenticationMethod:{}, appConfiguration.getAcrExclusionList():{}", authenticationMode, + appConfiguration.getAcrExclusionList()); - // if authentication validation check is enabled and acr being set is not active - // then throw error - if (appConfiguration.isAcrValidationEnabled()) { - final String authMethod = authenticationMode; - if (activeScripts.stream().noneMatch(e -> e.getName().equalsIgnoreCase(authMethod))) { - throwBadRequestException("INVALID_ACR", - String.format("Authentication script {%s} is not active", authenticationMode)); + if (appConfiguration.getAcrExclusionList() != null + && appConfiguration.getAcrExclusionList().contains(authenticationMode)) { + return true; + } + + List ldapConfigurations = ldapConfigurationService.findLdapConfigurations(); + log.debug(" ldapConfigurations:{}", ldapConfigurations); + if (ldapConfigurations != null && !ldapConfigurations.isEmpty()) { + Optional matchingLdapConfiguration = ldapConfigurations.stream() + .filter(d -> d.getConfigId().equals(authenticationMode)).findFirst(); + + if (matchingLdapConfiguration.isPresent()) { + GluuLdapConfiguration ldap = matchingLdapConfiguration.get(); + if (ldap != null) { + return true; + } } + } + + // if ACR being set is a script then it should be active + CustomScript script = customScriptService.getScriptByDisplayName(authenticationMode); + log.debug(" script:{}", script); + if (script != null && script.isEnabled()) { + log.debug(" script:{}, script.isEnabled():{}", script, script.isEnabled()); + return true; + } + log.debug(" isValid:{}", isValid); + + return isValid; } } \ No newline at end of file diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/AssetService.java b/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/AssetService.java index 38d791054cc..72f40f5fd15 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/AssetService.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/AssetService.java @@ -24,6 +24,7 @@ import io.jans.orm.PersistenceEntryManager; import io.jans.service.document.store.provider.DBDocumentStoreProvider; import io.jans.service.document.store.service.DBDocumentService; +import io.jans.service.document.store.conf.DocumentStoreType; import io.jans.service.document.store.service.Document; import io.jans.util.exception.InvalidAttributeException; import io.jans.util.exception.InvalidConfigurationException; @@ -194,14 +195,18 @@ public Document saveAsset(Document asset, InputStream documentStream, boolean is } // update asset revision - updateRevision(asset); + updateRevision(asset, isUpdate); // copy asset on jans-server if (documentStream != null && isAssetServerUploadEnabled()) { try (InputStream is = new Base64InputStream(getInputStream(bos), true)) { - String result = copyAssetOnServer(asset, is); - log.info("Result of asset saved on server :{}", result); + DocumentStoreType documentStoreProvider = this.getDocumentStoreType(); + log.info("Copy asset on server documentStoreProvider is:{}", documentStoreProvider); + if (documentStoreProvider == DocumentStoreType.LOCAL) { + String result = copyAssetOnServer(asset, is); + log.info("Result of asset saved on server :{}", result); + } } } @@ -337,8 +342,8 @@ private Document setAssetContent(Document asset, InputStream documentStream) thr return asset; } - private Document updateRevision(Document asset) { - log.debug("Update asset revision - asset:{}", asset); + private Document updateRevision(Document asset, boolean isUpdate) { + log.debug("Update asset revision - asset:{}, isUpdate:{}", asset, isUpdate); try { if (asset == null) { return asset; @@ -346,7 +351,10 @@ private Document updateRevision(Document asset) { int intRevision = asset.getJansRevision(); log.debug(" Current asset intRevision is:{}", intRevision); - asset.setJansRevision(++intRevision); + if (isUpdate) { + intRevision = intRevision + intRevision; + } + asset.setJansRevision(intRevision); log.info("Updated asset revision to asset.getJansRevision():{}", asset.getJansRevision()); } catch (Exception ex) { log.error("Exception while updating asset revision is - ", ex); @@ -655,4 +663,8 @@ private InputStream readDocumentAsStream(String name, String assetContent) { return new ByteArrayInputStream(assetContent.getBytes()); } + private DocumentStoreType getDocumentStoreType() { + return documentStoreService.getProviderType(); + } + } diff --git a/jans-config-api/server/src/main/resources/config-api-rs-protect.json b/jans-config-api/server/src/main/resources/config-api-rs-protect.json index 73228b34040..4c6d369f16f 100644 --- a/jans-config-api/server/src/main/resources/config-api-rs-protect.json +++ b/jans-config-api/server/src/main/resources/config-api-rs-protect.json @@ -802,7 +802,7 @@ ] }, { - "path": "/jans-config-api/api/v1/fido2/config", + "path": "/jans-config-api/api/v1/fido2/fido2-config", "conditions": [ { "httpMethods": [ @@ -847,6 +847,76 @@ } ] }, + { + "path": "/jans-config-api/api/v1/fido2/registration", + "conditions": [ + { + "httpMethods": [ + "GET" + ], + "scopes": [ + { + "inum": "1800.01.19", + "name": "https://jans.io/oauth/config/fido2.readonly" + } + ], + "groupScopes": [ + { + "inum": "1800.01.20", + "name": "https://jans.io/oauth/config/fido2.write" + } + ], + "superScopes": [ + { + "inum": "1800.03.1", + "name": "https://jans.io/oauth/config/read-all" + } + ] + }, + { + "httpMethods": [ + "POST", + "PUT" + ], + "scopes": [ + { + "inum": "1800.01.20", + "name": "https://jans.io/oauth/config/fido2.write" + } + ], + "groupScopes": [], + "superScopes": [ + { + "inum": "1800.03.2", + "name": "https://jans.io/oauth/config/write-all" + } + ] + }, + { + "httpMethods": [ + "DELETE" + ], + "scopes": [ + { + "inum": "1800.01.86", + "name": "https://jans.io/oauth/config/fido2.delete" + } + ], + "groupScopes": [ + { + "inum": "1800.01.20", + "name": "https://jans.io/oauth/config/fido2.write" + } + ], + "superScopes": [ + { + "inum": "1800.03.2", + "name": "https://jans.io/oauth/config/write-all" + } + ] + } + ] + }, { "path": "/jans-config-api/api/v1/config/jwks", "conditions": [ diff --git a/jans-linux-setup/jans_setup/templates/jans-config-api/dynamic-conf.json b/jans-linux-setup/jans_setup/templates/jans-config-api/dynamic-conf.json index d56d4a47dc5..f30eca0a408 100644 --- a/jans-linux-setup/jans_setup/templates/jans-config-api/dynamic-conf.json +++ b/jans-linux-setup/jans_setup/templates/jans-config-api/dynamic-conf.json @@ -20,6 +20,9 @@ "loggingLayout":"text", "externalLoggerConfiguration":"", "maxCount": 200, + "acrExclusionList": [ + "simple_password_auth" + ], "exclusiveAuthScopes": [ "jans_stat", "https://jans.io/scim/users.read",