diff --git a/jans-cli/cli/jca.yaml b/jans-cli/cli/jca.yaml index db133a07e07..cf258fbba55 100644 --- a/jans-cli/cli/jca.yaml +++ b/jans-cli/cli/jca.yaml @@ -34,8 +34,7 @@ tags: - name: Statistics - User - name: Health - Check - name: Server Stats - - name: User Management - - name: SCIM - User Management + - name: Configuration – User Management - name: SCIM - Config Management - name: Organization Configuration - name: Auth Server Health - Check @@ -2398,10 +2397,10 @@ paths: '500': description: Internal Server Error - /jans-config-api/api/v1/user: + /jans-config-api/mgt/configuser: get: tags: - - User Management + - Configuration – User Management summary: Gets list of users description: Gets list of users operationId: get-user @@ -2456,7 +2455,7 @@ paths: description: Order in which the sortBy param is applied. Allowed values are "ascending" and "descending". post: tags: - - User Management + - Configuration – User Management summary: Create new User description: Create new User operationId: post-user @@ -2483,7 +2482,7 @@ paths: - oauth2: [https://jans.io/oauth/config/user.write] put: tags: - - User Management + - Configuration – User Management summary: Update User. description: Update User. operationId: put-user @@ -2509,7 +2508,7 @@ paths: description: Internal Server Error security: - oauth2: [https://jans.io/oauth/config/user.write] - /jans-config-api/api/v1/user/{inum}: + /jans-config-api/mgt/configuser/{inum}: parameters: - schema: type: string @@ -2519,7 +2518,7 @@ paths: required: true get: tags: - - User Management + - Configuration – User Management summary: Get User by Inum description: Get User by Inum. operationId: get-user-by-inum @@ -2538,7 +2537,7 @@ paths: - oauth2: [https://jans.io/oauth/config/user.readonly] delete: tags: - - User Management + - Configuration – User Management summary: Delete User. description: Delete User. operationId: delete-user @@ -2555,7 +2554,7 @@ paths: - oauth2: [https://jans.io/oauth/config/user.delete] patch: tags: - - User Management + - Configuration – User Management summary: Patch user properties by Inum. description: Patch user properties by Inum. operationId: patch-user-by-inum @@ -2584,443 +2583,7 @@ paths: security: - oauth2: [https://jans.io/oauth/config/user.write] - - /jans-config-api/scim/resource/user: - get: - tags: - - SCIM - User Management - x-cli-plugin: scim - summary: Gets list of SCIM users - description: Gets list of SCIM users - operationId: get-scim-users - responses: - '200': - description: Successful operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserListResponse' - application/json: - schema: - $ref: '#/components/schemas/UserListResponse' - '400': - description: Parameter count exceeds the maximum allowed value or the filter - supplied was unparsable - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - oauth2: [https://jans.io/oauth/config/scim/users.read https://jans.io/scim/users.read] - parameters: - - schema: - type: string - in: query - name: filter - description: Search filter pattern. For more details refer section 3.4.2.2 of RFC 7644 - example: userName co \"mi\", userName eq \"admin\", displayName co \"1111\" or displayName co \"Group\" - - schema: - type: integer - default: 1 - in: query - name: startIndex - description: The 1-based index of the first query result. - - schema: - type: integer - in: query - name: count - description: Search size - max size of the results to return. - - schema: - type: string - in: query - name: sortBy - description: The attribute whose value will be used to order the returned responses - - schema: - type: string - enum: - - '- ascending' - - '- descending' - in: query - name: sortOrder - description: Order in which the sortBy param is applied. Allowed values are "ascending" and "descending" - - schema: - type: string - in: query - name: attributes - description: A comma-separated list of attribute names to return in the response - - schema: - type: string - in: query - name: excludedAttributes - description: When specified, the response will contain a default set of attributes minus those listed here (as a comma-separated list). - - post: - tags: - - SCIM - User Management - x-cli-plugin: scim - operationId: post-create-user - summary: Create a SCIM user. - description: Allows creating a User resource via POST (see section 3.3 of RFC 7644) - security: - - oauth2: [https://jans.io/oauth/config/scim/users.write https://jans.io/scim/users.write] - parameters: - - name: attributes - in: query - description: A comma-separated list of attribute names to return in the response - schema: - type: string - - name: excludedAttributes - in: query - description: When specified, the response will contain a default set of attributes minus those listed here (as a comma-separated list) - schema: - type: string - requestBody: - description: Payload that represents the Group to create - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - required: true - responses: - '201': - description: Successful operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - '400': - description: An invalid value was passed in the payload - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '409': - description: There is a conflict with an already existing user. Uniqueness - is assumed over userName - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /jans-config-api/scim/resource/user/{id}: - get: - tags: - - SCIM - User Management - x-cli-plugin: scim - operationId: get-user-by-id - summary: Retrieves SCIM user by Id. - description: Retrieves a User resource by Id (see section 3.4.1 of RFC 7644) - security: - - oauth2: [https://jans.io/oauth/config/scim/users.read https://jans.io/scim/users.read] - parameters: - - name: attributes - in: query - description: A comma-separated list of attribute names to return in the response - schema: - type: string - - name: excludedAttributes - in: query - description: When specified, the response will contain a default set of attributes minus those listed here (as a comma-separated list) - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - responses: - 200: - description: Successful operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - 404: - description: Id passed unknown - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 500: - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - put: - tags: - - SCIM - User Management - x-cli-plugin: scim - operationId: put-update-user-by-id - summary: Updates an SCIM user. - description: "Updates a User resource (see section 3.5.1 of RFC 7644). Update\ - \ works in a replacement fashion&#58; every\nattribute value found in the\ - \ payload sent will replace the one in the existing resource representation.\ - \ Attributes \nnot passed in the payload will be left intact.\n" - security: - - oauth2: [https://jans.io/oauth/config/scim/users.write https://jans.io/scim/users.write] - parameters: - - name: attributes - in: query - description: A comma-separated list of attribute names to return in the response - schema: - type: string - - name: excludedAttributes - in: query - description: When specified, the response will contain a default set of attributes minus those listed here (as a comma-separated list) - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - requestBody: - description: Payload with the data to replace in the existing user identified - by the id param - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - required: true - responses: - 200: - description: Successful operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - 400: - description: | - An invalid value was passed in the payload or there was an attempt to update an immutable attribute - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 404: - description: Id passed unknown - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 409: - description: There is a conflict with an already existing group. Uniqueness - is assumed over displayName - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 500: - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - delete: - tags: - - SCIM - User Management - x-cli-plugin: scim - operationId: delete-user-by-id - summary: Deletes a SCIM user. - description: Deletes a user resource - security: - - oauth2: [https://jans.io/oauth/config/scim/users.write https://jans.io/scim/users.write] - parameters: - - name: id - in: path - description: Identifier of the resource to delete - required: true - schema: - type: string - responses: - 204: - description: Successful operation. Empty response - content: {} - 404: - description: Id passed unknown - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 500: - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - patch: - tags: - - SCIM - User Management - x-cli-plugin: scim - operationId: patch-user-by-id - summary: Patches SCIM User attributes. - description: "Updates one or more attributes of a User resource using a sequence\ - \ of additions, removals, and \nreplacements operations. See section 3.5.2\ - \ of RFC 7644\n" - security: - - oauth2: [https://jans.io/oauth/config/scim/users.write https://jans.io/scim/users.write] - parameters: - - name: attributes - in: query - description: A comma-separated list of attribute names to return in the response - schema: - type: string - - name: excludedAttributes - in: query - description: When specified, the response will contain a default set of attributes minus those listed here (as a comma-separated list) - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - requestBody: - description: Payload describing the patch operations to apply upon the resource - identified by param id - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ScimPatchRequest' - application/json: - schema: - $ref: '#/components/schemas/ScimPatchRequest' - application/json-patch+json: - schema: - $ref: '#/components/schemas/ScimPatchRequest' - required: true - responses: - 200: - description: Successful operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - 400: - description: | - One or more operations supplied in the request are specified incorrectly, there were attempts to - modify immutable attributes, or the resulting resource cannot pass intrinsic validations - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 500: - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /jans-config-api/scim/resource/user/.search: - post: - tags: - - SCIM - User Management - x-cli-plugin: scim - summary: Search SCIM user. - description: Gets list of users - operationId: post-search-scim-users - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/SearchRequest' - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/UserListResponse' - '400': - description: Parameter count exceeds the maximum allowed value or the filter supplied was unparsable - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: There was an unexpected failure executing the operation - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - oauth2: [https://jans.io/oauth/config/scim/users.read https://jans.io/scim/users.read] - + /jans-config-api/scim/config: get: summary: Retrieves SCIM App configuration. @@ -4705,6 +4268,11 @@ components: - OLDER - NEWER - FIRST + checkUserPresenceOnRefreshToken: + type: boolean + description: Check whether user exists and is active before creating RefreshToken. Set it to true if check is needed(Default value is false - don't check.) + example: false + default: false oxElevenTestModeToken: type: string description: oxEleven Test Mode Token. diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/exception/GlobalErrorHandler.java b/jans-config-api/common/src/main/java/io/jans/configapi/exception/GlobalErrorHandler.java index 3f82c6987d4..b23318b233b 100644 --- a/jans-config-api/common/src/main/java/io/jans/configapi/exception/GlobalErrorHandler.java +++ b/jans-config-api/common/src/main/java/io/jans/configapi/exception/GlobalErrorHandler.java @@ -6,7 +6,7 @@ package io.jans.configapi.exception; -import io.jans.configapi.rest.model.ApiError; +import io.jans.configapi.core.model.ApiError; import org.slf4j.Logger; import javax.inject.Inject; diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiConstants.java b/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiConstants.java index 4750279214e..3b3e4dc4f9a 100644 --- a/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiConstants.java +++ b/jans-config-api/common/src/main/java/io/jans/configapi/util/ApiConstants.java @@ -88,12 +88,9 @@ private ApiConstants() {} public static final String ALL = "all"; public static final String ACTIVE = "active"; - public static final String INACTIVE = "inactive"; + public static final String INACTIVE = "inactive"; - public static final String MISSING_ATTRIBUTE_MESSAGE = "A required attribute is missing."; - // Custom CODE - public static final String MISSING_ATTRIBUTE_CODE = "OCA001"; // API Protection public static final String PROTECTION_TYPE_OAUTH2 = "oauth2"; diff --git a/jans-config-api/docs/jans-config-api-swagger.yaml b/jans-config-api/docs/jans-config-api-swagger.yaml index 8220354c65e..cf258fbba55 100644 --- a/jans-config-api/docs/jans-config-api-swagger.yaml +++ b/jans-config-api/docs/jans-config-api-swagger.yaml @@ -34,8 +34,7 @@ tags: - name: Statistics - User - name: Health - Check - name: Server Stats - - name: User Management - - name: SCIM - User Management + - name: Configuration – User Management - name: SCIM - Config Management - name: Organization Configuration - name: Auth Server Health - Check @@ -2398,10 +2397,10 @@ paths: '500': description: Internal Server Error - /jans-config-api/api/v1/user: + /jans-config-api/mgt/configuser: get: tags: - - User Management + - Configuration – User Management summary: Gets list of users description: Gets list of users operationId: get-user @@ -2456,7 +2455,7 @@ paths: description: Order in which the sortBy param is applied. Allowed values are "ascending" and "descending". post: tags: - - User Management + - Configuration – User Management summary: Create new User description: Create new User operationId: post-user @@ -2483,7 +2482,7 @@ paths: - oauth2: [https://jans.io/oauth/config/user.write] put: tags: - - User Management + - Configuration – User Management summary: Update User. description: Update User. operationId: put-user @@ -2509,7 +2508,7 @@ paths: description: Internal Server Error security: - oauth2: [https://jans.io/oauth/config/user.write] - /jans-config-api/api/v1/user/{inum}: + /jans-config-api/mgt/configuser/{inum}: parameters: - schema: type: string @@ -2519,7 +2518,7 @@ paths: required: true get: tags: - - User Management + - Configuration – User Management summary: Get User by Inum description: Get User by Inum. operationId: get-user-by-inum @@ -2538,7 +2537,7 @@ paths: - oauth2: [https://jans.io/oauth/config/user.readonly] delete: tags: - - User Management + - Configuration – User Management summary: Delete User. description: Delete User. operationId: delete-user @@ -2555,7 +2554,7 @@ paths: - oauth2: [https://jans.io/oauth/config/user.delete] patch: tags: - - User Management + - Configuration – User Management summary: Patch user properties by Inum. description: Patch user properties by Inum. operationId: patch-user-by-inum @@ -2584,442 +2583,7 @@ paths: security: - oauth2: [https://jans.io/oauth/config/user.write] - /jans-config-api/scim/resource/user: - get: - tags: - - SCIM - User Management - x-cli-plugin: scim - summary: Gets list of SCIM users - description: Gets list of SCIM users - operationId: get-scim-users - responses: - '200': - description: Successful operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserListResponse' - application/json: - schema: - $ref: '#/components/schemas/UserListResponse' - '400': - description: Parameter count exceeds the maximum allowed value or the filter - supplied was unparsable - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - oauth2: [https://jans.io/oauth/config/scim/users.read https://jans.io/scim/users.read] - parameters: - - schema: - type: string - in: query - name: filter - description: Search filter pattern. For more details refer section 3.4.2.2 of RFC 7644 - example: userName co \"mi\", userName eq \"admin\", displayName co \"1111\" or displayName co \"Group\" - - schema: - type: integer - default: 1 - in: query - name: startIndex - description: The 1-based index of the first query result. - - schema: - type: integer - in: query - name: count - description: Search size - max size of the results to return. - - schema: - type: string - in: query - name: sortBy - description: The attribute whose value will be used to order the returned responses - - schema: - type: string - enum: - - '- ascending' - - '- descending' - in: query - name: sortOrder - description: Order in which the sortBy param is applied. Allowed values are "ascending" and "descending" - - schema: - type: string - in: query - name: attributes - description: A comma-separated list of attribute names to return in the response - - schema: - type: string - in: query - name: excludedAttributes - description: When specified, the response will contain a default set of attributes minus those listed here (as a comma-separated list). - - post: - tags: - - SCIM - User Management - x-cli-plugin: scim - operationId: post-create-user - summary: Create a SCIM user. - description: Allows creating a User resource via POST (see section 3.3 of RFC 7644) - security: - - oauth2: [https://jans.io/oauth/config/scim/users.write https://jans.io/scim/users.write] - parameters: - - name: attributes - in: query - description: A comma-separated list of attribute names to return in the response - schema: - type: string - - name: excludedAttributes - in: query - description: When specified, the response will contain a default set of attributes minus those listed here (as a comma-separated list) - schema: - type: string - requestBody: - description: Payload that represents the Group to create - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - required: true - responses: - '201': - description: Successful operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - '400': - description: An invalid value was passed in the payload - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '409': - description: There is a conflict with an already existing user. Uniqueness - is assumed over userName - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /jans-config-api/scim/resource/user/{id}: - get: - tags: - - SCIM - User Management - x-cli-plugin: scim - operationId: get-user-by-id - summary: Retrieves SCIM user by Id. - description: Retrieves a User resource by Id (see section 3.4.1 of RFC 7644) - security: - - oauth2: [https://jans.io/oauth/config/scim/users.read https://jans.io/scim/users.read] - parameters: - - name: attributes - in: query - description: A comma-separated list of attribute names to return in the response - schema: - type: string - - name: excludedAttributes - in: query - description: When specified, the response will contain a default set of attributes minus those listed here (as a comma-separated list) - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - responses: - 200: - description: Successful operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - 404: - description: Id passed unknown - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 500: - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - put: - tags: - - SCIM - User Management - x-cli-plugin: scim - operationId: put-update-user-by-id - summary: Updates an SCIM user. - description: "Updates a User resource (see section 3.5.1 of RFC 7644). Update\ - \ works in a replacement fashion&#58; every\nattribute value found in the\ - \ payload sent will replace the one in the existing resource representation.\ - \ Attributes \nnot passed in the payload will be left intact.\n" - security: - - oauth2: [https://jans.io/oauth/config/scim/users.write https://jans.io/scim/users.write] - parameters: - - name: attributes - in: query - description: A comma-separated list of attribute names to return in the response - schema: - type: string - - name: excludedAttributes - in: query - description: When specified, the response will contain a default set of attributes minus those listed here (as a comma-separated list) - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - requestBody: - description: Payload with the data to replace in the existing user identified - by the id param - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - required: true - responses: - 200: - description: Successful operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - 400: - description: | - An invalid value was passed in the payload or there was an attempt to update an immutable attribute - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 404: - description: Id passed unknown - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 409: - description: There is a conflict with an already existing group. Uniqueness - is assumed over displayName - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 500: - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - delete: - tags: - - SCIM - User Management - x-cli-plugin: scim - operationId: delete-user-by-id - summary: Deletes a SCIM user. - description: Deletes a user resource - security: - - oauth2: [https://jans.io/oauth/config/scim/users.write https://jans.io/scim/users.write] - parameters: - - name: id - in: path - description: Identifier of the resource to delete - required: true - schema: - type: string - responses: - 204: - description: Successful operation. Empty response - content: {} - 404: - description: Id passed unknown - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 500: - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - patch: - tags: - - SCIM - User Management - x-cli-plugin: scim - operationId: patch-user-by-id - summary: Patches SCIM User attributes. - description: "Updates one or more attributes of a User resource using a sequence\ - \ of additions, removals, and \nreplacements operations. See section 3.5.2\ - \ of RFC 7644\n" - security: - - oauth2: [https://jans.io/oauth/config/scim/users.write https://jans.io/scim/users.write] - parameters: - - name: attributes - in: query - description: A comma-separated list of attribute names to return in the response - schema: - type: string - - name: excludedAttributes - in: query - description: When specified, the response will contain a default set of attributes minus those listed here (as a comma-separated list) - schema: - type: string - - name: id - in: path - required: true - schema: - type: string - requestBody: - description: Payload describing the patch operations to apply upon the resource - identified by param id - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ScimPatchRequest' - application/json: - schema: - $ref: '#/components/schemas/ScimPatchRequest' - application/json-patch+json: - schema: - $ref: '#/components/schemas/ScimPatchRequest' - required: true - responses: - 200: - description: Successful operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/UserResource' - application/json: - schema: - $ref: '#/components/schemas/UserResource' - 400: - description: | - One or more operations supplied in the request are specified incorrectly, there were attempts to - modify immutable attributes, or the resulting resource cannot pass intrinsic validations - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - 500: - description: There was an unexpected failure executing the operation - content: - application/scim+json: - schema: - $ref: '#/components/schemas/ErrorResponse' - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - - /jans-config-api/scim/resource/user/.search: - post: - tags: - - SCIM - User Management - x-cli-plugin: scim - summary: Search SCIM user. - description: Gets list of users - operationId: post-search-scim-users - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/SearchRequest' - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/UserListResponse' - '400': - description: Parameter count exceeds the maximum allowed value or the filter supplied was unparsable - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - '500': - description: There was an unexpected failure executing the operation - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorResponse' - security: - - oauth2: [https://jans.io/oauth/config/scim/users.read https://jans.io/scim/users.read] - + /jans-config-api/scim/config: get: summary: Retrieves SCIM App configuration. diff --git a/jans-config-api/plugins/pom.xml b/jans-config-api/plugins/pom.xml index 2f4c43e0159..91612618e10 100644 --- a/jans-config-api/plugins/pom.xml +++ b/jans-config-api/plugins/pom.xml @@ -20,6 +20,7 @@ admin-ui-plugin scim-plugin + user-mgt-plugin diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ApiApplication.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ApiApplication.java index 0f3eec22eb0..7ef05eadbe5 100644 --- a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ApiApplication.java +++ b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ApiApplication.java @@ -12,8 +12,6 @@ public class ApiApplication extends Application { public Set> getClasses() { HashSet> classes = new HashSet<>(); - // General - classes.add(ScimResource.class); classes.add(ScimConfigResource.class); return classes; diff --git a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimResource.java b/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimResource.java deleted file mode 100644 index 7b1bff6ddc1..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/main/java/io/jans/configapi/plugin/scim/rest/ScimResource.java +++ /dev/null @@ -1,149 +0,0 @@ -package io.jans.configapi.plugin.scim.rest; - -import static io.jans.as.model.util.Util.escapeLog; -import io.jans.configapi.core.rest.ProtectedApi; -import io.jans.configapi.plugin.scim.service.ScimService; -import io.jans.scim.model.scim2.SearchRequest; -import io.jans.scim.model.scim2.patch.PatchRequest; -import io.jans.scim.model.scim2.user.UserResource; -import org.slf4j.Logger; - -import static io.jans.scim.model.scim2.Constants.MEDIA_TYPE_SCIM_JSON; -import static io.jans.scim.model.scim2.Constants.QUERY_PARAM_ATTRIBUTES; -import static io.jans.scim.model.scim2.Constants.QUERY_PARAM_COUNT; -import static io.jans.scim.model.scim2.Constants.QUERY_PARAM_EXCLUDED_ATTRS; -import static io.jans.scim.model.scim2.Constants.QUERY_PARAM_FILTER; -import static io.jans.scim.model.scim2.Constants.QUERY_PARAM_SORT_BY; -import static io.jans.scim.model.scim2.Constants.QUERY_PARAM_SORT_ORDER; -import static io.jans.scim.model.scim2.Constants.QUERY_PARAM_START_INDEX; -import static io.jans.scim.model.scim2.Constants.UTF8_CHARSET_FRAGMENT; - -import javax.inject.Inject; -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -@Path("/resource/user") -public class ScimResource { - - public static final String SEARCH_SUFFIX = ".search"; - @Inject - Logger log; - - @Inject - ScimService scimService; - - @GET - @Produces({ MEDIA_TYPE_SCIM_JSON + UTF8_CHARSET_FRAGMENT, MediaType.APPLICATION_JSON + UTF8_CHARSET_FRAGMENT }) - @HeaderParam("Accept") - @DefaultValue(MEDIA_TYPE_SCIM_JSON) - @ProtectedApi(scopes = { "https://jans.io/scim/users.read" }) - public Response searchUsers(@QueryParam(QUERY_PARAM_FILTER) String filter, - @QueryParam(QUERY_PARAM_START_INDEX) Integer startIndex, @QueryParam(QUERY_PARAM_COUNT) Integer count, - @QueryParam(QUERY_PARAM_SORT_BY) String sortBy, @QueryParam(QUERY_PARAM_SORT_ORDER) String sortOrder, - @QueryParam(QUERY_PARAM_ATTRIBUTES) String attrsList, - @QueryParam(QUERY_PARAM_EXCLUDED_ATTRS) String excludedAttrsList) throws Exception { - if (log.isTraceEnabled()) { - log.trace( - " Request to search User with filter:{}, startIndex:{}, sortBy:{}, sortOrder:{}, attrsList{}, excludedAttrsList:{}", - escapeLog(filter), escapeLog(startIndex), escapeLog(sortBy), escapeLog(sortOrder), - escapeLog(attrsList), escapeLog(excludedAttrsList)); - } - return scimService.serachScimUser(filter, startIndex, count, sortBy, sortOrder, attrsList, excludedAttrsList); - - } - - @Path(SEARCH_SUFFIX) - @POST - @Consumes({ MEDIA_TYPE_SCIM_JSON, MediaType.APPLICATION_JSON }) - @Produces({ MEDIA_TYPE_SCIM_JSON + UTF8_CHARSET_FRAGMENT, MediaType.APPLICATION_JSON + UTF8_CHARSET_FRAGMENT }) - @HeaderParam("Accept") - @DefaultValue(MEDIA_TYPE_SCIM_JSON) - @ProtectedApi(scopes = { "https://jans.io/scim/users.read" }) - public Response searchUsersPost(SearchRequest searchRequest) throws Exception { - if (log.isTraceEnabled()) { - log.trace(" Request to search User with SearchRequest object searchRequest:{}", escapeLog(searchRequest)); - } - return scimService.serachScimUserPost(searchRequest); - } - - @POST - @Consumes({ MEDIA_TYPE_SCIM_JSON, MediaType.APPLICATION_JSON }) - @Produces({ MEDIA_TYPE_SCIM_JSON + UTF8_CHARSET_FRAGMENT, MediaType.APPLICATION_JSON + UTF8_CHARSET_FRAGMENT }) - @HeaderParam("Accept") - @DefaultValue(MEDIA_TYPE_SCIM_JSON) - @ProtectedApi(scopes = { "https://jans.io/scim/users.write" }) - public Response createUser(UserResource user, @QueryParam(QUERY_PARAM_ATTRIBUTES) String attrsList, - @QueryParam(QUERY_PARAM_EXCLUDED_ATTRS) String excludedAttrsList) throws Exception { - if (log.isTraceEnabled()) { - log.trace(" Request to create User with user:{}, attrsList:{}, excludedAttrsList:{}", escapeLog(user), - escapeLog(attrsList), escapeLog(excludedAttrsList)); - } - return scimService.createScimUser(user, attrsList, excludedAttrsList); - } - - @Path("{id}") - @GET - @Produces({ MEDIA_TYPE_SCIM_JSON + UTF8_CHARSET_FRAGMENT, MediaType.APPLICATION_JSON + UTF8_CHARSET_FRAGMENT }) - @HeaderParam("Accept") - @DefaultValue(MEDIA_TYPE_SCIM_JSON) - @ProtectedApi(scopes = { "https://jans.io/scim/users.read" }) - public Response getUserById(@PathParam("id") String id, @QueryParam(QUERY_PARAM_ATTRIBUTES) String attrsList, - @QueryParam(QUERY_PARAM_EXCLUDED_ATTRS) String excludedAttrsList) throws Exception { - if (log.isTraceEnabled()) { - log.trace(" Request to search User with id:{}, attrsList:{}, excludedAttrsList:{}", escapeLog(id), - escapeLog(attrsList), escapeLog(excludedAttrsList)); - } - return scimService.getScimUserById(id, attrsList, excludedAttrsList); - } - - @Path("{id}") - @PUT - @Consumes({ MEDIA_TYPE_SCIM_JSON, MediaType.APPLICATION_JSON }) - @Produces({ MEDIA_TYPE_SCIM_JSON + UTF8_CHARSET_FRAGMENT, MediaType.APPLICATION_JSON + UTF8_CHARSET_FRAGMENT }) - @HeaderParam("Accept") - @DefaultValue(MEDIA_TYPE_SCIM_JSON) - @ProtectedApi(scopes = { "https://jans.io/scim/users.write" }) - public Response updateUser(UserResource user, @PathParam("id") String id, - @QueryParam(QUERY_PARAM_ATTRIBUTES) String attrsList, - @QueryParam(QUERY_PARAM_EXCLUDED_ATTRS) String excludedAttrsList) throws Exception { - if (log.isTraceEnabled()) { - log.trace(" Request to update User with user:{}, id:{}, attrsList:{}, excludedAttrsList:{} ", - escapeLog(user), escapeLog(id), escapeLog(attrsList), escapeLog(excludedAttrsList)); - } - return scimService.updateScimUser(user, id, attrsList, excludedAttrsList); - - } - - @Path("{id}") - @DELETE - @Produces({ MEDIA_TYPE_SCIM_JSON + UTF8_CHARSET_FRAGMENT, MediaType.APPLICATION_JSON + UTF8_CHARSET_FRAGMENT }) - @HeaderParam("Accept") - @DefaultValue(MEDIA_TYPE_SCIM_JSON) - @ProtectedApi(scopes = { "https://jans.io/scim/users.write" }) - public Response deleteUser(@PathParam("id") String id) throws Exception { - if (log.isTraceEnabled()) { - log.trace(" Request to delete User with id:{} ", escapeLog(id)); - } - return scimService.deleteScimUser(id); - } - - @Path("{id}") - @PATCH - @Consumes({ MEDIA_TYPE_SCIM_JSON, MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_PATCH_JSON }) - @Produces({ MEDIA_TYPE_SCIM_JSON + UTF8_CHARSET_FRAGMENT, MediaType.APPLICATION_JSON + UTF8_CHARSET_FRAGMENT }) - @HeaderParam("Accept") - @DefaultValue(MEDIA_TYPE_SCIM_JSON) - @ProtectedApi(scopes = { "https://jans.io/scim/users.write" }) - public Response patchUser(PatchRequest patchRequest, @PathParam("id") String id, - @QueryParam(QUERY_PARAM_ATTRIBUTES) String attrsList, - @QueryParam(QUERY_PARAM_EXCLUDED_ATTRS) String excludedAttrsList) throws Exception { - if (log.isTraceEnabled()) { - log.trace(" Request to patch User with patchRequest:{}, id:{}, attrsList:{}, excludedAttrsList:{}", - escapeLog(patchRequest), escapeLog(id), escapeLog(attrsList), escapeLog(excludedAttrsList)); - } - return scimService.patchScimUser(patchRequest, id, attrsList, excludedAttrsList); - - } - -} diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-search-request.json b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-search-request.json deleted file mode 100644 index dcc28f2826b..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-search-request.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "schemas": null, - "attributes": null, - "excludedAttributes": null, - "filter": "userName co \"mi\"", - "sortBy": null, - "sortOrder": null, - "startIndex": null, - "count": 1 -} diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user-patch.json b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user-patch.json deleted file mode 100644 index 2b287584397..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user-patch.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "schemas": [ - "urn:ietf:params:scim:api:messages:2.0:PatchOp" - ], - "Operations": [ - { - "op": "replace", - "path": "name", - "value": { - "familyName": "re-patched Jensen", - "givenName": "re-patched Barbara", - "middleName": "re-patched Jane" - } - }, - { - "op": "replace", - "path": "phoneNumbers", - "value": [ - { - "value": "re-patch 555 123 4567", - "type": "other" - }, - { - "value": "re-patch 666 000 1234", - "type": "work" - } - ] - }, - { - "op": "remove", - "path": "name.middleName" - } - ] -} \ No newline at end of file diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.feature b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.feature deleted file mode 100644 index 52d2066d593..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.feature +++ /dev/null @@ -1,84 +0,0 @@ - -Feature: Scim Users - -Background: -* def mainUrl = scim_user_url - - -Scenario: Fetch scim users without bearer token - Given url mainUrl - When method GET - Then status 401 - - -@Get-all -Scenario: Search user by filter - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And param filter = 'userName co \"mi\"' - When method GET - Then status 200 - And print response - #And assert response.length != 0 - - -@GetById -Scenario: Get an scim user by id - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - And print response.Resources[0].id - Given url mainUrl + '/' +response.Resources[0].id - And header Authorization = 'Bearer ' + accessToken - When method GET - Then status 200 - And print response - - -@SearchRequest -Scenario: Search user using SearchRequest - Given url mainUrl + '/.search' - And header Authorization = 'Bearer ' + accessToken - And request read('scim-search-request.json') - When method POST - Then status 200 - And print response - - - -@CreateUpdateDelete -Scenario: Create new user, update and delete - Given url mainUrl - And header Authorization = 'Bearer ' + accessToken - And request read('scim-user.json') - When method POST - Then status 201 - And print response - Then def result = response - Then def inum = result.id - Then def updated_displayName = 'Updated ' +result.displayName - Then set result.displayName = updated_displayName - And print 'Updating displayName' - Given url mainUrl + '/' +inum - And header Authorization = 'Bearer ' + accessToken - And request result - When method PUT - Then status 200 - And print response - And assert response.displayName == updated_displayName - And assert response.id == inum - And print 'Successfully updated displayName' - Given url mainUrl + '/' +inum - And header Authorization = 'Bearer ' + accessToken - And request read('scim-user-patch.json') - When method PATCH - Then status 200 - And print response - Then def result = response - Given url mainUrl + '/' +inum - And header Authorization = 'Bearer ' + accessToken - When method DELETE - Then status 204 - And print 'User successfully deleted' diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.json b/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.json deleted file mode 100644 index af970542d3b..00000000000 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/feature/scim/user/scim-user.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "schemas": [ - "urn:ietf:params:scim:schemas:core:2.0:User" - ], - "meta": { - "resourceType": "User", - "location": "https://jans.server1/jans-scim/restv1/v2/Users/48b44f61-ef93-40ff-b1e1-bc00be97225d" - }, - "userName": "test-admin-test1", - "name": { - "familyName": "User", - "givenName": "TestAdmin", - "middleName": "TestAdmin", - "formatted": "TestAdmin TestAdmin User" - }, - "displayName": "Test Admin User", - "nickName": "Test Admin", - "active": true, - "emails": [ - { - "value": "test.admin@jans.server", - "primary": false - } - ], - "groups": [ - { - "value": "60B7", - "display": "Jannsen Manager Group", - "type": "direct", - "$ref": "https://jans.server1/jans-scim/restv1/v2/Groups/60B7" - } - ] -} \ No newline at end of file diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config-jenkins.js b/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config-jenkins.js index 41a41720755..d4eb3421e76 100644 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config-jenkins.js +++ b/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config-jenkins.js @@ -44,7 +44,6 @@ function() { accessToken: '123', //scim - scim_user_url: baseUrl + '/jans-config-api/scim/resource/user', scim_config_url: baseUrl + '/jans-config-api/scim/config', }; diff --git a/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config.js b/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config.js index fb6ce5dca47..71d504a132f 100644 --- a/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config.js +++ b/jans-config-api/plugins/scim-plugin/src/test/resources/karate-config.js @@ -45,7 +45,6 @@ function() { //scim - scim_user_url: baseUrl + '/jans-config-api/scim/resource/user', scim_config_url: baseUrl + '/jans-config-api/scim/config', }; diff --git a/jans-config-api/plugins/user-mgt-plugin/config/microprofile-config.properties b/jans-config-api/plugins/user-mgt-plugin/config/microprofile-config.properties new file mode 100644 index 00000000000..a6430d33648 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/config/microprofile-config.properties @@ -0,0 +1,3 @@ +defaultMaxCount=200 +defaultListSize = "50"; +defaultListStartIndex = "1"; diff --git a/jans-config-api/plugins/user-mgt-plugin/pom.xml b/jans-config-api/plugins/user-mgt-plugin/pom.xml new file mode 100644 index 00000000000..c7a030c4fcd --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/pom.xml @@ -0,0 +1,203 @@ + + + + plugins + io.jans.jans-config-api.plugins + 1.0.0-SNAPSHOT + + 4.0.0 + io.jans.jans-config-api.plugins + user-mgt-plugin + + 4.4.14 + 4.5.13 + 1.0.0-SNAPSHOT + + + + + + + io.jans + jans-config-api-shared + ${jans.version} + + + io.jans + jans-config-api-server + ${jans.version} + + + io.jans + jans-orm-annotation + ${jans.version} + + + + + + io.smallrye + smallrye-config + 1.5.0 + + + + + commons-collections + commons-collections + + + org.apache.httpcomponents + httpclient + + + org.apache.httpcomponents + httpcore + + + org.apache.httpcomponents + httpcore-nio + ${httpcore.version} + + + + + io.rest-assured + rest-assured + test + + + com.intuit.karate + karate-junit5 + test + + + com.intuit.karate + karate-apache + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.junit.jupiter + junit-jupiter-engine + test + + + net.masterthought + cucumber-reporting + test + + + + + + + + ../../profiles/${cfg}/config-build.properties + ../../profiles/${cfg}/config-api-test.properties + + + + + src/test/resources + true + + karate.properties + karate_jenkins.properties + test.properties + *.* + + + + + + + src/main/resources + true + + **/*.xml + **/*.properties + **/*.json + META-INF/services/*.* + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + src/main/assembly/assembly.xml + + + + + + + + maven-surefire-plugin + + + + integration + + --tags ~@ignore + + + + + integration-tests + integration-test + + test + + + false + !integration + integration + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + deploy-to-local-folder + package + + copy-resources + + + ../target/plugins + + + ${project.build.directory} + *-distribution.jar + false + + + + + + + + + diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/assembly/assembly.xml b/jans-config-api/plugins/user-mgt-plugin/src/main/assembly/assembly.xml new file mode 100644 index 00000000000..2abddfa0029 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/assembly/assembly.xml @@ -0,0 +1,31 @@ + + + distribution + + jar + + false + + + + ${project.build.directory}/classes + / + + **/* + + + + \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/extensions/UserMgtExtension.java b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/extensions/UserMgtExtension.java new file mode 100644 index 00000000000..9b5c25aadd8 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/extensions/UserMgtExtension.java @@ -0,0 +1,6 @@ +package io.jans.configapi.plugin.mgt.extensions; + +import javax.enterprise.inject.spi.Extension; + +public class UserMgtExtension implements Extension { +} diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/model/config/MgmtConfiguration.java.bkp b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/model/config/MgmtConfiguration.java.bkp new file mode 100644 index 00000000000..92a0e7dfd67 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/model/config/MgmtConfiguration.java.bkp @@ -0,0 +1,26 @@ +package io.jans.configapi.plugin.mgmt.model.config; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import org.eclipse.microprofile.config.Config; +import org.eclipse.microprofile.config.inject.ConfigProperty; + +@ApplicationScoped +public class MgmtConfiguration { + + @Inject + Config config; + + @Inject + @ConfigProperty(name = "mgmt.relative.path") + private String mgmtRelativePath; + + public String getMgmtRelativePath() { + return mgmtRelativePath; + } + + public void setMgmtRelativePath(String mgmtRelativePath) { + this.mgmtRelativePath = mgmtRelativePath; + } + +} diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/model/config/UserMgtConfigSource.java b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/model/config/UserMgtConfigSource.java new file mode 100644 index 00000000000..81f705696f5 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/model/config/UserMgtConfigSource.java @@ -0,0 +1,81 @@ +package io.jans.configapi.plugin.mgt.model.config; + +import io.jans.exception.ConfigurationException; +import java.io.InputStream; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import javax.enterprise.context.ApplicationScoped; + +import org.eclipse.microprofile.config.spi.ConfigSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@ApplicationScoped +public class UserMgtConfigSource implements ConfigSource { + + private static Logger log = LoggerFactory.getLogger(UserMgtConfigSource.class); + private static final String FILE_CONFIG = "mgt.properties"; + private Properties properties = null; + Map propertiesMap = new HashMap<>(); + + public UserMgtConfigSource() { + this.loadProperties(); + } + + @Override + public Map getProperties() { + log.debug("Getting properties"); + return propertiesMap; + } + + @Override + public Set getPropertyNames() { + log.debug("Getting Property Names"); + try { + return properties.stringPropertyNames(); + + } catch (Exception e) { + log.error("Unable to read properties from file: " + FILE_CONFIG, e); + } + return Collections.emptySet(); + } + + @Override + public int getOrdinal() { + return 800; + } + + @Override + public String getValue(String name) { + log.debug("UserMgtConfigSource()::getValue() - name:{}", name); + try { + return properties.getProperty(name); + } catch (Exception e) { + log.error("Unable to read properties from file: " + FILE_CONFIG, e); + } + + return null; + } + + @Override + public String getName() { + return FILE_CONFIG; + } + + private Properties loadProperties() { + // Load the properties file + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + try ( InputStream inputStream = loader.getResourceAsStream(FILE_CONFIG)) { + properties = new Properties(); + properties.load(inputStream); + properties.stringPropertyNames().stream().forEach(key -> propertiesMap.put(key, properties.getProperty(key))); + return properties; + } catch (Exception e) { + throw new ConfigurationException("Failed to load configuration from "+ FILE_CONFIG, e); + } + } + +} diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/model/user/UserPatchRequest.java b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/model/user/UserPatchRequest.java similarity index 95% rename from jans-config-api/common/src/main/java/io/jans/configapi/model/user/UserPatchRequest.java rename to jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/model/user/UserPatchRequest.java index 51cc2602909..adcde5126e7 100644 --- a/jans-config-api/common/src/main/java/io/jans/configapi/model/user/UserPatchRequest.java +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/model/user/UserPatchRequest.java @@ -1,4 +1,4 @@ -package io.jans.configapi.model.user; +package io.jans.configapi.plugin.mgt.model.user; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/rest/ApiApplication.java b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/rest/ApiApplication.java new file mode 100644 index 00000000000..263c9cf518e --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/rest/ApiApplication.java @@ -0,0 +1,19 @@ + package io.jans.configapi.plugin.mgt.rest; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; +import java.util.HashSet; +import java.util.Set; + +@ApplicationPath("/mgt") +public class ApiApplication extends Application { + + @Override + public Set> getClasses() { + HashSet> classes = new HashSet<>(); + + classes.add(UserResource.class); + + return classes; + } +} diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UserResource.java b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/rest/UserResource.java similarity index 69% rename from jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UserResource.java rename to jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/rest/UserResource.java index df129c6dea4..dba7066984d 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UserResource.java +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/rest/UserResource.java @@ -1,22 +1,24 @@ -/* - * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. - * - * Copyright (c) 2020, Janssen Project - */ +package io.jans.configapi.plugin.mgt.rest; -package io.jans.configapi.rest.resource.auth; import com.github.fge.jsonpatch.JsonPatchException; + import static io.jans.as.model.util.Util.escapeLog; import io.jans.as.common.model.common.User; +import io.jans.as.common.service.common.EncryptionService; +import io.jans.configapi.core.rest.BaseResource; import io.jans.configapi.core.rest.ProtectedApi; -import io.jans.configapi.model.user.UserPatchRequest; -import io.jans.configapi.rest.model.SearchRequest; -import io.jans.configapi.service.auth.UserService; +import io.jans.configapi.plugin.mgt.model.config.UserMgtConfigSource; +import io.jans.configapi.plugin.mgt.model.user.UserPatchRequest; +import io.jans.configapi.plugin.mgt.service.UserService; +import io.jans.configapi.plugin.mgt.util.Constants; +import io.jans.configapi.plugin.mgt.util.MgtUtil; +import io.jans.configapi.core.model.SearchRequest; import io.jans.configapi.util.ApiAccessConstants; import io.jans.configapi.util.ApiConstants; import io.jans.orm.model.PagedResult; import io.jans.util.StringHelper; +import io.jans.util.security.StringEncrypter.EncryptionException; import java.io.IOException; import java.lang.reflect.InvocationTargetException; @@ -32,7 +34,7 @@ import org.slf4j.Logger; -@Path(ApiConstants.USER) +@Path(Constants.CONFIG_USER) @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @ApplicationScoped @@ -42,37 +44,43 @@ public class UserResource extends BaseResource { @Inject Logger logger; + + @Inject + EncryptionService encryptionService; + + @Inject + MgtUtil mgtUtil; @Inject UserService userSrv; @GET @ProtectedApi(scopes = { ApiAccessConstants.USER_READ_ACCESS }) - public Response getUsers(@DefaultValue(DEFAULT_LIST_SIZE) @QueryParam(value = ApiConstants.LIMIT) int limit, + public Response getUsers(@DefaultValue(ApiConstants.DEFAULT_LIST_SIZE) @QueryParam(value = ApiConstants.LIMIT) int limit, @DefaultValue("") @QueryParam(value = ApiConstants.PATTERN) String pattern, - @DefaultValue(DEFAULT_LIST_START_INDEX) @QueryParam(value = ApiConstants.START_INDEX) int startIndex, + @DefaultValue(ApiConstants.DEFAULT_LIST_START_INDEX) @QueryParam(value = ApiConstants.START_INDEX) int startIndex, @QueryParam(value = ApiConstants.SORT_BY) String sortBy, @QueryParam(value = ApiConstants.SORT_ORDER) String sortOrder) - throws IllegalAccessException, InvocationTargetException { + throws EncryptionException, IllegalAccessException, InvocationTargetException { if (logger.isDebugEnabled()) { logger.debug("User search param - limit:{}, pattern:{}, startIndex:{}, sortBy:{}, sortOrder:{}", escapeLog(limit), escapeLog(pattern), escapeLog(startIndex), escapeLog(sortBy), escapeLog(sortOrder)); } SearchRequest searchReq = createSearchRequest(userSrv.getPeopleBaseDn(), pattern, sortBy, sortOrder, startIndex, - limit, null, userSrv.getUserExclusionAttributesAsString()); + limit, null, userSrv.getUserExclusionAttributesAsString(),mgtUtil.getRecordMaxCount()); List users = this.doSearch(searchReq); logger.debug("User search result:{}", users); - return Response.ok(users).build(); + return Response.ok(getUsers(users)).build(); } @GET @ProtectedApi(scopes = { ApiAccessConstants.USER_WRITE_ACCESS }) @Path(ApiConstants.INUM_PATH) public Response getUserByInum(@PathParam(ApiConstants.INUM) @NotNull String inum) - throws IllegalAccessException, InvocationTargetException { + throws EncryptionException, IllegalAccessException, InvocationTargetException { if (logger.isDebugEnabled()) { logger.debug("User search by inum:{}", escapeLog(inum)); } @@ -83,13 +91,13 @@ public Response getUserByInum(@PathParam(ApiConstants.INUM) @NotNull String inum // excludedAttributes user = excludeUserAttributes(user); - return Response.ok(user).build(); + return Response.ok(decryptUserPassword(user)).build(); } @POST @ProtectedApi(scopes = { ApiAccessConstants.USER_WRITE_ACCESS }) public Response createUser(@Valid User user) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + throws EncryptionException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (logger.isDebugEnabled()) { logger.debug("User details to be added - user:{}", escapeLog(user)); } @@ -97,7 +105,7 @@ public Response createUser(@Valid User user) // checking mandatory attributes checkMissingAttributes(user); - user = userSrv.addUser(user, true); + user = userSrv.addUser(encryptUserPassword(user), true); logger.debug("User created {}", user); // excludedAttributes @@ -109,15 +117,15 @@ public Response createUser(@Valid User user) @PUT @ProtectedApi(scopes = { ApiAccessConstants.USER_WRITE_ACCESS }) public Response updateUser(@Valid User user) - throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + throws EncryptionException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (logger.isDebugEnabled()) { logger.debug("User details to be updated - user:{}", escapeLog(user)); } // checking mandatory attributes checkMissingAttributes(user); - - user = userSrv.updateUser((user)); + + user = userSrv.updateUser(encryptUserPassword(user)); logger.debug("Updated user:{}", user); // excludedAttributes @@ -131,7 +139,7 @@ public Response updateUser(@Valid User user) @Path(ApiConstants.INUM_PATH) public Response patchUser(@PathParam(ApiConstants.INUM) @NotNull String inum, @NotNull UserPatchRequest userPatchRequest) - throws IllegalAccessException, InvocationTargetException, JsonPatchException, IOException { + throws EncryptionException, IllegalAccessException, InvocationTargetException, JsonPatchException, IOException { if (logger.isDebugEnabled()) { logger.debug("User:{} to be patched with :{} ", escapeLog(inum), escapeLog(userPatchRequest)); } @@ -146,7 +154,7 @@ public Response patchUser(@PathParam(ApiConstants.INUM) @NotNull String inum, // excludedAttributes existingUser = excludeUserAttributes(existingUser); - return Response.ok(existingUser).build(); + return Response.ok(decryptUserPassword(existingUser)).build(); } @DELETE @@ -202,4 +210,31 @@ private void checkMissingAttributes(User user) throwMissingAttributeError(missingAttributes); } + + private List getUsers(List users) throws EncryptionException { + if (users != null && !users.isEmpty()) { + for (User user : users) { + if (StringHelper.isNotEmpty(user.getAttribute("userPassword"))) { + decryptUserPassword(user); + } + } + } + return users; + } + + private User encryptUserPassword(User user) throws EncryptionException { + if (StringHelper.isNotEmpty(user.getAttribute("userPassword"))) { + user.setAttribute("userPassword", encryptionService.encrypt(user.getAttribute("userPassword")), false); + } + return user; + } + + private User decryptUserPassword(User user) throws EncryptionException { + if (StringHelper .isNotEmpty(user.getAttribute("userPassword"))) { + user.setAttribute("userPassword", encryptionService.decrypt(user.getAttribute("userPassword")), false); + } + return user; + } + + } diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/UserService.java b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/service/UserService.java similarity index 97% rename from jans-config-api/server/src/main/java/io/jans/configapi/service/auth/UserService.java rename to jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/service/UserService.java index a5cead7920f..fae1908dd43 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/UserService.java +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/service/UserService.java @@ -1,20 +1,14 @@ -/* - * Janssen Project software is available under the Apache License (2004). See http://www.apache.org/licenses/ for full text. - * - * Copyright (c) 2020, Janssen Project - */ - -package io.jans.configapi.service.auth; +package io.jans.configapi.plugin.mgt.service; import com.github.fge.jsonpatch.JsonPatchException; import io.jans.as.common.model.common.User; import io.jans.as.common.util.AttributeConstants; import io.jans.as.model.config.StaticConfiguration; import io.jans.as.model.configuration.AppConfiguration; -import io.jans.configapi.util.AuthUtil; import io.jans.configapi.core.util.Jackson; -import io.jans.configapi.model.user.UserPatchRequest; -import io.jans.configapi.rest.model.SearchRequest; +import io.jans.configapi.plugin.mgt.model.user.UserPatchRequest; +import io.jans.configapi.core.model.SearchRequest; +import io.jans.configapi.util.AuthUtil; import io.jans.orm.model.PagedResult; import io.jans.orm.model.SortOrder; import io.jans.orm.model.base.CustomObjectAttribute; diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/util/Constants.java b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/util/Constants.java new file mode 100644 index 00000000000..13b2eff866d --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/util/Constants.java @@ -0,0 +1,21 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.plugin.mgt.util; + +public class Constants { + + private Constants() {} + + public static final String CONFIG_USER = "/configuser"; + public static final String LIMIT = "limit"; + public static final String START_INDEX = "startIndex"; + public static final String PATTERN = "pattern"; + public static final String STATUS = "status"; + public static final String INUM = "inum"; + public static final String SORT_BY = "sortBy"; + public static final String SORT_ORDER = "sortOrder"; +} \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/util/MgtUtil.java b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/util/MgtUtil.java new file mode 100644 index 00000000000..f4cb0098868 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/java/io/jans/configapi/plugin/mgt/util/MgtUtil.java @@ -0,0 +1,58 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.plugin.mgt.util; + +import io.jans.configapi.configuration.ConfigurationFactory; +import io.jans.configapi.plugin.mgt.model.config.UserMgtConfigSource; +import io.jans.configapi.util.ApiConstants; +import io.jans.util.StringHelper; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; + +import org.slf4j.Logger; + +@ApplicationScoped +public class MgtUtil { + + @Inject + Logger logger; + + @Inject + ConfigurationFactory configurationFactory; + + @Inject + UserMgtConfigSource configSource; + + public String getProperty(String propertyName) { + logger.error("configSource.getValue(propertyName:{} ",configSource.getValue(propertyName)); + return configSource.getValue(propertyName); + } + + public String getMaxCount() { + logger.error("default.max.count:{} ",getProperty("default.max.count")); + return getProperty("default.max.count"); + } + + public String getDefaultListSize() { + logger.error("default.max.count:{} ",getProperty("default.list.size")); + return (StringHelper.isNotEmpty(getProperty("default.list.size")) ? getProperty("default.list.size") : ApiConstants.DEFAULT_LIST_SIZE); + } + + public String getDefaultListStartIndex() { + logger.error("default.max.count:{} ",getProperty("default.list.start.index")); + return (StringHelper.isNotEmpty(getProperty("default.list.start.index")) ? getProperty("default.list.start.index") : ApiConstants.DEFAULT_LIST_SIZE); + } + + public int getRecordMaxCount() { + logger.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); + } +} \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/beans.xml b/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/beans.xml new file mode 100644 index 00000000000..bf2ab180c1c --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/beans.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension b/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension new file mode 100644 index 00000000000..3874c1e8d88 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension @@ -0,0 +1 @@ +io.jans.configapi.plugin.mgt.extensions.UserMgtExtension \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers b/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers new file mode 100644 index 00000000000..b2c9664d366 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/services/javax.ws.rs.ext.Providers @@ -0,0 +1,3 @@ +io.jans.configapi.filters.AuthorizationFilter +io.jans.configapi.filters.LoggingFilter + diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource b/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource new file mode 100644 index 00000000000..a010a44b4a8 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/resources/META-INF/services/org.eclipse.microprofile.config.spi.ConfigSource @@ -0,0 +1 @@ +io.jans.configapi.plugin.mgt.model.config.UserMgtConfigSource \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/main/resources/mgt.properties b/jans-config-api/plugins/user-mgt-plugin/src/main/resources/mgt.properties new file mode 100644 index 00000000000..6c5c08a213b --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/main/resources/mgt.properties @@ -0,0 +1,3 @@ +default.max.count=200 +default.list.size = "50"; +default.list.start.index = "1"; diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java new file mode 100644 index 00000000000..d039e1f2040 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/JenkinsTestRunner.java @@ -0,0 +1,47 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi; + +import com.intuit.karate.Results; +import com.intuit.karate.Runner; + +import io.jans.as.common.model.registration.Client; +import net.masterthought.cucumber.Configuration; +import net.masterthought.cucumber.ReportBuilder; +import org.apache.commons.io.FileUtils; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author Yuriy Zabrovarnyy + */ +public class JenkinsTestRunner { + + @Test + public void testParallel() { + System.setProperty("karate.env", "jenkins"); + Results results = Runner.path("src/test/resources/feature").tags("~@ignore").parallel(1); + generateReport(results.getReportDir()); + Assertions.assertEquals(0, results.getFailCount(), results.getErrorMessages()); + } + + public static void generateReport(String karateOutputPath) { + Collection jsonFiles = FileUtils.listFiles(new File(karateOutputPath), new String[] { "json" }, true); + List jsonPaths = new ArrayList(jsonFiles.size()); + jsonFiles.forEach(file -> jsonPaths.add(file.getAbsolutePath())); + Configuration config = new Configuration(new File("target"), "karateTesting"); + ReportBuilder reportBuilder = new ReportBuilder(jsonPaths, config); + reportBuilder.generateReports(); + } +} diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java new file mode 100644 index 00000000000..34da4586ef9 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/java/io/jans/configapi/KarateTestRunner.java @@ -0,0 +1,18 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi; + +import com.intuit.karate.junit5.Karate; + +public class KarateTestRunner { + + @Karate.Test + Karate testFullPath() throws Exception { + return Karate.run("src/test/resources/feature"); + } + +} diff --git a/jans-config-api/server/src/test/resources/feature/user/user-patch.json b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-patch.json similarity index 100% rename from jans-config-api/server/src/test/resources/feature/user/user-patch.json rename to jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-patch.json diff --git a/jans-config-api/server/src/test/resources/feature/user/user-ref.json b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-ref.json similarity index 100% rename from jans-config-api/server/src/test/resources/feature/user/user-ref.json rename to jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user-ref.json diff --git a/jans-config-api/server/src/test/resources/feature/user/user.feature b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user.feature similarity index 100% rename from jans-config-api/server/src/test/resources/feature/user/user.feature rename to jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user.feature diff --git a/jans-config-api/server/src/test/resources/feature/user/user.json b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user.json similarity index 96% rename from jans-config-api/server/src/test/resources/feature/user/user.json rename to jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user.json index 7ccf1434a05..edaea34b0ae 100644 --- a/jans-config-api/server/src/test/resources/feature/user/user.json +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/feature/mgt/user/user.json @@ -244,6 +244,15 @@ ], "value": "America/Chicago", "displayValue": "America/Chicago" + }, + { + "name": "userPassword", + "multiValued": false, + "values": [ + "pwd123" + ], + "value": "pwd123", + "displayValue": "pwd123" } ] } \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config-jenkins.js b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config-jenkins.js new file mode 100644 index 00000000000..bffd51af405 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config-jenkins.js @@ -0,0 +1,58 @@ +function() { + + var stream = read('classpath:karate_jenkins.properties'); + var props = new java.util.Properties(); + props.load(stream); + + var env = props.get('karate.env'); // get java system property 'karate.env' + karate.configure("ssl", true); + + if (!env) { + env = 'dev'; //env can be anything: dev, qa, staging, etc. + } + + var url = props.get('karate.test.url'); + var port = props.get('karate.test.port'); + var baseUrl = url + (port ? ':' + port : ''); + + karate.log('karate_jenkins env :', env); + karate.log('karate_jenkins url :', url); + karate.log('karate_jenkins port :', port); + karate.log('karate_jenkins baseUrl :', baseUrl); + + var testStream = read('classpath:test.properties'); + var testProps = new java.util.Properties(); + testProps.load(testStream); + karate.log(' testProps = '+testProps); + var testClientId = testProps.get('test.client.id'); + var testClientSecret = testProps.get('test.client.secret'); + var tokenEndpoint = testProps.get('token.endpoint'); + var testScopes = testProps.get('test.scopes'); + var issuer = testProps.get('test.issuer'); + karate.log(' testClientId = '+testClientId); + karate.log(' testClientSecret = '+testClientSecret); + karate.log(' tokenEndpoint = '+tokenEndpoint); + karate.log(' testScopes = '+testScopes); + karate.log(' issuer = '+issuer); + + + var config = { + env: env, + baseUrl: baseUrl, + testProps: testProps, + issuer: issuer, + accessToken: '123', + + //mgt + user_url: baseUrl + '/jans-config-api/mgt/configuser', + }; + + karate.configure('connectTimeout', 30000); + karate.configure('readTimeout', 60000); + + var result = karate.callSingle('classpath:token.feature', config); + print(' result.response = '+result.response); + config.accessToken = result.response.access_token; + + return config; +} \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config.js b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config.js new file mode 100644 index 00000000000..ac0472c4dd1 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate-config.js @@ -0,0 +1,59 @@ +function() { + + var stream = read('classpath:karate.properties'); + var props = new java.util.Properties(); + props.load(stream); + + var env = props.get('karate.env'); // get java system property 'karate.env' + karate.configure("ssl", true); + + if (!env) { + env = 'dev'; //env can be anything: dev, qa, staging, etc. + } + + var url = props.get('karate.test.url'); + var port = props.get('karate.test.port'); + var baseUrl = url + (port ? ':' + port : ''); + + karate.log('karate env :', env); + karate.log('karate url :', url); + karate.log('karate port :', port); + karate.log('karate baseUrl :', baseUrl); + + var testStream = read('classpath:test.properties'); + var testProps = new java.util.Properties(); + testProps.load(testStream); + karate.log(' testProps = '+testProps); + var testClientId = testProps.get('test.client.id'); + var testClientSecret = testProps.get('test.client.secret'); + var tokenEndpoint = testProps.get('token.endpoint'); + var testScopes = testProps.get('test.scopes'); + var issuer = testProps.get('test.issuer'); + karate.log(' testClientId = '+testClientId); + karate.log(' testClientSecret = '+testClientSecret); + karate.log(' tokenEndpoint = '+tokenEndpoint); + karate.log(' testScopes = '+testScopes); + karate.log(' issuer = '+issuer); + + + var config = { + env: env, + baseUrl: baseUrl, + testProps: testProps, + issuer: issuer, + accessToken: '123', + + + //mgt + user_url: baseUrl + '/jans-config-api/mgt/configuser', + }; + + karate.configure('connectTimeout', 30000); + karate.configure('readTimeout', 60000); + + var result = karate.callSingle('classpath:token.feature', config); + print(' result.response = '+result.response); + config.accessToken = result.response.access_token; + + return config; +} \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate.properties b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate.properties new file mode 100644 index 00000000000..a849093586c --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate.properties @@ -0,0 +1,6 @@ +#LOCAL +karate.test.url=http://localhost +karate.test.port=8080 +#karate.test.url=https://jenkins-config-api.gluu.org/jans-config-api +#karate.test.port=443 +#karate.test.url=https://jenkins-config-api.gluu.org diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate_jenkins.properties b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate_jenkins.properties new file mode 100644 index 00000000000..0b44a8d7b13 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/karate_jenkins.properties @@ -0,0 +1,2 @@ +karate.test.url=${test.server} +#karate.test.port=443 diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/logback-test.xml b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/logback-test.xml new file mode 100644 index 00000000000..fea195eb039 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/logback-test.xml @@ -0,0 +1,24 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + target/karate.log + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + + + + \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties new file mode 100644 index 00000000000..43b105ffc20 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/test.properties @@ -0,0 +1,75 @@ +#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/database/couchbase.readonly https://jans.io/oauth/config/database/couchbase.write https://jans.io/oauth/config/database/couchbase.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/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 + +# Test env Setting +#token.endpoint=https://jenkins-config-api.gluu.org/jans-auth/restv1/token +#token.grant.type=client_credentials +#test.client.id=1801.f35446a2-b9cb-40af-a26e-c1221f3ca0cb +#test.client.secret=lye8TNJmNpze +#test.issuer=https://jenkins-config-api.gluu.org + +# Local Setting +#pujavs.jans.server +#token.endpoint=https://pujavs.jans.server/jans-auth/restv1/token +#token.grant.type=client_credentials +#test.client.id=1802.9dcd98ad-fe2c-4fd9-b717-d9436d9f2009 +#test.client.secret=test1234 +#test.issuer=https://pujavs.jans.server + +# pujavs.jans.server2 +#token.endpoint=https://pujavs.jans.server2/jans-auth/restv1/token +#token.grant.type=client_credentials +#test.client.id=1801.86d83471-fe91-4522-ac47-a256956c0f23 +#test.client.secret=wndq7RoRnyqm +#test.issuer=https:// pujavs.jans.server2 + +# pujavs.jans.server5 +#token.endpoint=https://pujavs.jans.server5/jans-auth/restv1/token +#token.grant.type=client_credentials +#test.client.id=1800.0f2aeab1-efee-4b89-a7f1-570c15a68ff3 +#test.client.secret=fxa2iV1Oi0HS +#test.issuer=https:// pujavs.jans.server5 + + +# pujavs.jans.server3 +#token.endpoint=https://pujavs.jans.server2/jans-auth/restv1/token +#token.grant.type=client_credentials +#test.client.id=1801.e0396ed5-055d-4986-9afc-342373995f0e +#test.client.secret=Dk3RaLUYSdJn +#test.issuer=https:// pujavs.jans.server3 + +# jans.server1 +#token.endpoint=https://jans.server1/jans-auth/restv1/token +#token.grant.type=client_credentials +#test.client.id=1800.d166622d-6771-4d5a-8fab-555566b20091 +#test.client.secret=slkveBOhwJn5 +#test.issuer=https://jans.server1 + +# jans.server2 +#token.endpoint=https://jans.server2/jans-auth/restv1/token +#token.grant.type=client_credentials +#test.client.id=1800.5ad89818-e1c6-45ba-873d-d549dfad67a4 +#test.client.secret=9ZW2HaDakqD4 +#test.issuer=https://jans.server2 + +# jans.server3 +#token.endpoint=https://jans.server3/jans-auth/restv1/token +#token.grant.type=client_credentials +#test.client.id=1800.1adcb34a-e1a5-4b4d-86d0-f92c62aab52b +#test.client.secret=aDiH4IuuGddZ +#test.issuer=https://jans.server3 + +# jans.server4 +#token.endpoint=https://jans.server4/jans-auth/restv1/token +#token.grant.type=client_credentials +#test.client.id=1800.7e78990f-fdae-40e9-9433-4fe20645851d +#test.client.secret=GfUrIapPM71X +#test.issuer=https://jans.server4 + + +# jans.server +token.endpoint=https://jans.server/jans-auth/restv1/token +token.grant.type=client_credentials +test.client.id=1800.5cfac798-9a5d-4a92-8efe-4cecc4f0c196 +test.client.secret=SSj633EttZdV +test.issuer=https://jans.server \ No newline at end of file diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/testClient.feature b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/testClient.feature new file mode 100644 index 00000000000..34cfdffc438 --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/testClient.feature @@ -0,0 +1,13 @@ +@ignore +Feature: This Feature is to get token to test the test cases + +Background: +* def mainUrl = test_url + +Scenario: Get Token +Given url mainUrl +And print url +And request '' +When method POST +Then status 204 +And print response diff --git a/jans-config-api/plugins/user-mgt-plugin/src/test/resources/token.feature b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/token.feature new file mode 100644 index 00000000000..ef0ad0d262d --- /dev/null +++ b/jans-config-api/plugins/user-mgt-plugin/src/test/resources/token.feature @@ -0,0 +1,45 @@ +@ignore +Feature: This Feature is to get token to test the test cases - Do not remove ignore tag + +Background: +* def mainUrl = testProps.get('token.endpoint'); +* def grantType = testProps.get('token.grant.type'); +* def clientId = testProps.get('test.client.id'); +* def clientSecret = testProps.get('test.client.secret'); +* def scopes = testProps.get('test.scopes'); +* def authStr = clientId+':'+clientSecret +* def Base64 = Java.type('java.util.Base64') +* def encodedAuth = Base64.encoder.encodeToString(authStr.bytes) +* def encodedScopes = java.net.URLDecoder.decode(scopes, 'UTF-8') + + +Scenario: Get Token +Given url mainUrl +And print 'mainUrl = '+mainUrl +And print 'grantType = '+grantType +And print 'clientId = '+clientId +And print 'clientSecret = '+clientSecret +And print 'scopes = '+scopes +And print 'authStr = '+authStr +And print 'encodedAuth = '+encodedAuth +And print 'encodedScopes = '+encodedScopes +And header Accept = 'application/json' +And header Authorization = 'Basic '+encodedAuth +And form field grant_type = grantType +And form field scope = scopes +When method POST +Then status 200 +And print 'token response = '+response + + + + +#Scenario: Get Token +#Given url 'https://pujavs.jans.server/jans-auth/restv1/token' +#And header Accept = 'application/json' +#And header Authorization = 'Basic MTgwMi45ZGNkOThhZC1mZTJjLTRmZDktYjcxNy1kOTQzNmQ5ZjIwMDk6dGVzdDEyMzQ=' +#And form field grant_type = 'client_credentials' +#And form field scope = 'https://jans.io/oauth/config/openid/clients.readonly' +#When method POST +#Then status 200 +#And print 'token response = '+response diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/ApiApplication.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/ApiApplication.java index 6b49f3a553e..91638787dc4 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/ApiApplication.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/ApiApplication.java @@ -48,7 +48,6 @@ public Set> getClasses() { classes.add(HealthCheckResource.class); classes.add(OrganizationResource.class); classes.add(SqlConfigurationResource.class); - classes.add(UserResource.class); return classes; } diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/health/ApiHealthCheck.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/health/ApiHealthCheck.java index c9ff46d3468..d3fdac3c584 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/health/ApiHealthCheck.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/health/ApiHealthCheck.java @@ -7,7 +7,7 @@ package io.jans.configapi.rest.health; import io.jans.configapi.model.status.StatsData; -import io.jans.configapi.rest.resource.auth.BaseResource; +import io.jans.configapi.rest.resource.auth.ConfigBaseResource; import io.jans.configapi.service.auth.ConfigurationService; import io.jans.configapi.util.ApiConstants; @@ -24,7 +24,7 @@ @Path(ApiConstants.HEALTH) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) -public class ApiHealthCheck extends BaseResource { +public class ApiHealthCheck extends ConfigBaseResource { @Inject Logger logger; 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 4cd2fe3894e..7fb203597a1 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 @@ -27,7 +27,7 @@ @Path(ApiConstants.ACRS) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) -public class AcrsResource extends BaseResource { +public class AcrsResource extends ConfigBaseResource { @Inject Logger log; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AttributesResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AttributesResource.java index bba38615068..ebc73dba19c 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AttributesResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/AttributesResource.java @@ -35,7 +35,7 @@ @Path(ApiConstants.ATTRIBUTES) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) -public class AttributesResource extends BaseResource { +public class AttributesResource extends ConfigBaseResource { private static final String GLUU_ATTRIBUTE = "gluu attribute"; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CacheConfigurationResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CacheConfigurationResource.java index daa2ea9c03a..d9b6ddb3381 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CacheConfigurationResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CacheConfigurationResource.java @@ -31,7 +31,7 @@ @Path(ApiConstants.CONFIG + ApiConstants.CACHE) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) -public class CacheConfigurationResource extends BaseResource { +public class CacheConfigurationResource extends ConfigBaseResource { @Inject Logger log; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ClientsResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ClientsResource.java index f3b35c4fcda..bebdeb4a7b8 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ClientsResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ClientsResource.java @@ -12,7 +12,7 @@ import io.jans.as.common.service.common.EncryptionService; import io.jans.as.common.service.common.InumService; import io.jans.configapi.core.rest.ProtectedApi; -import io.jans.configapi.rest.model.SearchRequest; +import io.jans.configapi.core.model.SearchRequest; import io.jans.configapi.service.auth.ClientService; import io.jans.configapi.service.auth.ConfigurationService; import io.jans.configapi.util.ApiAccessConstants; @@ -47,7 +47,7 @@ @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @ApplicationScoped -public class ClientsResource extends BaseResource { +public class ClientsResource extends ConfigBaseResource { private static final String OPENID_CONNECT_CLIENT = "openid connect client"; @@ -81,7 +81,7 @@ public Response getOpenIdConnectClients( } SearchRequest searchReq = createSearchRequest(clientService.getDnForClient(null), pattern, sortBy, sortOrder, - startIndex, limit, null, null); + startIndex, limit, null, null, this.getMaxCount()); final List clients = this.doSearch(searchReq); logger.trace("Client serach result:{}", clients); diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigBaseResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigBaseResource.java new file mode 100644 index 00000000000..eccf21c00c0 --- /dev/null +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigBaseResource.java @@ -0,0 +1,44 @@ +/* + * Janssen Project software is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text. + * + * Copyright (c) 2020, Janssen Project + */ + +package io.jans.configapi.rest.resource.auth; + +import io.jans.configapi.core.rest.BaseResource; +import io.jans.configapi.util.ApiConstants; +import io.jans.configapi.configuration.ConfigurationFactory; + +import javax.inject.Inject; + +import org.slf4j.Logger; + +/** + * @author Mougang T.Gasmyr + * + */ +public class ConfigBaseResource extends BaseResource { + + @Inject + Logger log; + + @Inject + ConfigurationFactory configurationFactory; + + protected static final String READ_ACCESS = "config-api-read"; + protected static final String WRITE_ACCESS = "config-api-write"; + protected static final String DEFAULT_LIST_SIZE = ApiConstants.DEFAULT_LIST_SIZE; + // Pagination + protected static final String DEFAULT_LIST_START_INDEX = ApiConstants.DEFAULT_LIST_START_INDEX; + protected static final int DEFAULT_MAX_COUNT = ApiConstants.DEFAULT_MAX_COUNT; + + protected int getMaxCount() { + log.trace(" MaxCount details - ApiAppConfiguration.MaxCount():{}, DEFAULT_MAX_COUNT:{} ", + configurationFactory.getApiAppConfiguration().getMaxCount(), DEFAULT_MAX_COUNT); + return (configurationFactory.getApiAppConfiguration().getMaxCount() > 0 + ? configurationFactory.getApiAppConfiguration().getMaxCount() + : DEFAULT_MAX_COUNT); + } + +} diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigResource.java index 4d891f7eb01..f8164b2e348 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigResource.java @@ -26,7 +26,7 @@ @Path(ApiConstants.JANS_AUTH + ApiConstants.CONFIG) @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class ConfigResource extends BaseResource { +public class ConfigResource extends ConfigBaseResource { @Inject Logger log; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigSmtpResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigSmtpResource.java index 629252494e5..36ff161d70e 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigSmtpResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ConfigSmtpResource.java @@ -32,7 +32,7 @@ @Path(ApiConstants.CONFIG + ApiConstants.SMTP) @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class ConfigSmtpResource extends BaseResource { +public class ConfigSmtpResource extends ConfigBaseResource { @Inject Logger log; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CouchbaseConfigurationResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CouchbaseConfigurationResource.java index 5824d380b60..ce74e096160 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CouchbaseConfigurationResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CouchbaseConfigurationResource.java @@ -29,7 +29,7 @@ @Path(ApiConstants.CONFIG + ApiConstants.DATABASE + ApiConstants.COUCHBASE) @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class CouchbaseConfigurationResource extends BaseResource { +public class CouchbaseConfigurationResource extends ConfigBaseResource { @Inject Logger log; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CustomScriptResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CustomScriptResource.java index a139940d050..e7f1c245c1f 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CustomScriptResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/CustomScriptResource.java @@ -29,7 +29,7 @@ @Path(ApiConstants.CONFIG + ApiConstants.SCRIPTS) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) -public class CustomScriptResource extends BaseResource { +public class CustomScriptResource extends ConfigBaseResource { private static final String CUSTOM_SCRIPT = "custom script"; private static final String PATH_SEPARATOR = "/"; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/Fido2ConfigResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/Fido2ConfigResource.java index 87418bb73b9..fa746dbd539 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/Fido2ConfigResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/Fido2ConfigResource.java @@ -24,7 +24,7 @@ @Path(ApiConstants.FIDO2 + ApiConstants.CONFIG) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) -public class Fido2ConfigResource extends BaseResource { +public class Fido2ConfigResource extends ConfigBaseResource { private static final String FIDO2_CONFIGURATION = "fido2Configuration"; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/HealthCheckResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/HealthCheckResource.java index 85ac23ab757..0109eb30a43 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/HealthCheckResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/HealthCheckResource.java @@ -14,7 +14,7 @@ import org.slf4j.Logger; @Path(ApiConstants.JANS_AUTH + ApiConstants.HEALTH) -public class HealthCheckResource extends BaseResource { +public class HealthCheckResource extends ConfigBaseResource { private static final String HEALTH_CHECK_URL = "/jans-auth/sys/health-check"; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/JwksResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/JwksResource.java index 2f98785d1ba..75dfe25627c 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/JwksResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/JwksResource.java @@ -31,7 +31,7 @@ @Path(ApiConstants.CONFIG + ApiConstants.JWKS) @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class JwksResource extends BaseResource { +public class JwksResource extends ConfigBaseResource { @Inject Logger log; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LdapConfigurationResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LdapConfigurationResource.java index fc1a229a298..347cc0f3665 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LdapConfigurationResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/LdapConfigurationResource.java @@ -29,7 +29,7 @@ @Path(ApiConstants.CONFIG + ApiConstants.DATABASE + ApiConstants.LDAP) @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class LdapConfigurationResource extends BaseResource { +public class LdapConfigurationResource extends ConfigBaseResource { @Inject Logger log; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/OrganizationResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/OrganizationResource.java index 6f1eaaf727f..1775d7a69c4 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/OrganizationResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/OrganizationResource.java @@ -28,7 +28,7 @@ @Path(ApiConstants.ORG) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) -public class OrganizationResource extends BaseResource { +public class OrganizationResource extends ConfigBaseResource { @Inject OrganizationService organizationService; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ScopesResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ScopesResource.java index 374a5e29bd4..ef879fe5294 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ScopesResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/ScopesResource.java @@ -41,7 +41,7 @@ @Path(ApiConstants.SCOPES) @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class ScopesResource extends BaseResource { +public class ScopesResource extends ConfigBaseResource { private static final String SCOPE = "scope"; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/SqlConfigurationResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/SqlConfigurationResource.java index b5e1cff7fc0..d94b0d64f8d 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/SqlConfigurationResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/SqlConfigurationResource.java @@ -28,7 +28,7 @@ @Path(ApiConstants.CONFIG + ApiConstants.DATABASE + ApiConstants.SQL) @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) -public class SqlConfigurationResource extends BaseResource { +public class SqlConfigurationResource extends ConfigBaseResource { @Inject Logger log; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/StatResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/StatResource.java index 5815dfa8957..ea46b5cf476 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/StatResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/StatResource.java @@ -17,7 +17,7 @@ import org.slf4j.Logger; @Path(ApiConstants.STATISTICS) -public class StatResource extends BaseResource { +public class StatResource extends ConfigBaseResource { private final String statUrl = "/jans-auth/restv1/internal/stat"; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UmaResourcesResource.java b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UmaResourcesResource.java index aef74692e9d..7f0073d2ec0 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UmaResourcesResource.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/UmaResourcesResource.java @@ -35,7 +35,7 @@ @Path(ApiConstants.UMA + ApiConstants.RESOURCES) @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) -public class UmaResourcesResource extends BaseResource { +public class UmaResourcesResource extends ConfigBaseResource { private static final String UMA_RESOURCE = "Uma resource"; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/ClientService.java b/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/ClientService.java index b129de05ec9..a9e44524985 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/ClientService.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/service/auth/ClientService.java @@ -14,7 +14,7 @@ import io.jans.as.model.common.SubjectType; import io.jans.as.model.crypto.signature.SignatureAlgorithm; import io.jans.as.model.register.ApplicationType; -import io.jans.configapi.rest.model.SearchRequest; +import io.jans.configapi.core.model.SearchRequest; import io.jans.orm.PersistenceEntryManager; import io.jans.orm.model.PagedResult; import io.jans.orm.model.SortOrder; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java b/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java index 38e5b913fcb..b4d0e5d2fbc 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java +++ b/jans-config-api/server/src/main/java/io/jans/configapi/util/AuthUtil.java @@ -376,7 +376,7 @@ public boolean containsField(List allFields, String attribute) { public List getAllFields(Class type) { List allFields = new ArrayList<>(); allFields = getAllFields(allFields, type); - log.debug("All Fields of User class:{} ", allFields); + log.debug("Fields:{} of type:{} ", allFields, type); return allFields; } @@ -392,4 +392,6 @@ public List getAllFields(List fields, Class type) { return fields; } + + } 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 592169f1d90..3877e22726d 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 @@ -591,72 +591,6 @@ } ] }, - { - "path":"/jans-config-api/scim/resource/user", - "conditions":[ - { - "httpMethods":["GET"], - "scopes":[ - "https://jans.io/oauth/config/scim/users.read", - "https://jans.io/scim/users.read" - ] - }, - { - "httpMethods":["POST"], - "scopes":[ - "https://jans.io/oauth/config/scim/users.write", - "https://jans.io/scim/users.write" - ] - } - - ] - }, - { - "path":"/jans-config-api/scim/resource/user/{id}", - "conditions":[ - { - "httpMethods":["GET"], - "scopes":[ - "https://jans.io/oauth/config/scim/users.read", - "https://jans.io/scim/users.read" - ] - }, - { - "httpMethods":["PUT"], - "scopes":[ - "https://jans.io/oauth/config/scim/users.write", - "https://jans.io/scim/users.write" - ] - }, - { - "httpMethods":["DELETE"], - "scopes":[ - "https://jans.io/oauth/config/scim/users.write", - "https://jans.io/scim/users.write" - ] - }, - { - "httpMethods":["PATCH"], - "scopes":[ - "https://jans.io/oauth/config/scim/users.write", - "https://jans.io/scim/users.write" - ] - } - - ] - }, - { - "path":"/jans-config-api/scim/resource/user/.search", - "conditions":[ - { - "httpMethods":["GET"], - "scopes":[ - "https://jans.io/oauth/config/scim/users.read", - "https://jans.io/scim/users.read" - ] - } - ] - }, { "path":"/jans-config-api/scim/config", "conditions":[ @@ -692,7 +626,7 @@ ] }, { - "path":"/jans-config-api/api/v1/user", + "path":"/jans-config-api/mgt/configuser", "conditions":[ { "httpMethods":["GET"], diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/rest/model/ApiError.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/model/ApiError.java similarity index 98% rename from jans-config-api/common/src/main/java/io/jans/configapi/rest/model/ApiError.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/model/ApiError.java index 84bd394c6f2..abae91b266a 100644 --- a/jans-config-api/common/src/main/java/io/jans/configapi/rest/model/ApiError.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/model/ApiError.java @@ -4,7 +4,7 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.rest.model; +package io.jans.configapi.core.model; import java.io.Serializable; diff --git a/jans-config-api/common/src/main/java/io/jans/configapi/rest/model/SearchRequest.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/model/SearchRequest.java similarity index 98% rename from jans-config-api/common/src/main/java/io/jans/configapi/rest/model/SearchRequest.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/model/SearchRequest.java index 6f85af32c41..a0e40401ce9 100644 --- a/jans-config-api/common/src/main/java/io/jans/configapi/rest/model/SearchRequest.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/model/SearchRequest.java @@ -1,4 +1,4 @@ -package io.jans.configapi.rest.model; +package io.jans.configapi.core.model; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; diff --git a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/BaseResource.java b/jans-config-api/shared/src/main/java/io/jans/configapi/core/rest/BaseResource.java similarity index 76% rename from jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/BaseResource.java rename to jans-config-api/shared/src/main/java/io/jans/configapi/core/rest/BaseResource.java index a35e098d94f..480006515a9 100644 --- a/jans-config-api/server/src/main/java/io/jans/configapi/rest/resource/auth/BaseResource.java +++ b/jans-config-api/shared/src/main/java/io/jans/configapi/core/rest/BaseResource.java @@ -4,13 +4,11 @@ * Copyright (c) 2020, Janssen Project */ -package io.jans.configapi.rest.resource.auth; +package io.jans.configapi.core.rest; import static io.jans.as.model.util.Util.escapeLog; -import io.jans.configapi.rest.model.ApiError; -import io.jans.configapi.rest.model.SearchRequest; -import io.jans.configapi.util.ApiConstants; -import io.jans.configapi.configuration.ConfigurationFactory; +import io.jans.configapi.core.model.ApiError; +import io.jans.configapi.core.model.SearchRequest; import io.jans.orm.model.SortOrder; import javax.inject.Inject; @@ -22,24 +20,14 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; -/** - * @author Mougang T.Gasmyr - * - */ public class BaseResource { - @Inject - Logger log; + // Custom CODE + public static final String MISSING_ATTRIBUTE_CODE = "OCA001"; + public static final String MISSING_ATTRIBUTE_MESSAGE = "A required attribute is missing."; @Inject - ConfigurationFactory configurationFactory; - - protected static final String READ_ACCESS = "config-api-read"; - protected static final String WRITE_ACCESS = "config-api-write"; - protected static final String DEFAULT_LIST_SIZE = ApiConstants.DEFAULT_LIST_SIZE; - // Pagination - protected static final String DEFAULT_LIST_START_INDEX = ApiConstants.DEFAULT_LIST_START_INDEX; - protected static final int DEFAULT_MAX_COUNT = ApiConstants.DEFAULT_MAX_COUNT; + Logger log; public static void checkResourceNotNull(T resource, String objectName) { if (resource == null) { @@ -52,7 +40,7 @@ public static void checkNotNull(String attribute, String attributeName) { throw new BadRequestException(getMissingAttributeError(attributeName)); } } - + public static void throwMissingAttributeError(String attributeName) { if (StringUtils.isNotEmpty(attributeName)) { throw new BadRequestException(getMissingAttributeError(attributeName)); @@ -80,8 +68,8 @@ public static void thorwBadRequestException(String msg) { * @return */ protected static Response getMissingAttributeError(String attributeName) { - ApiError error = new ApiError.ErrorBuilder().withCode(ApiConstants.MISSING_ATTRIBUTE_CODE) - .withMessage(ApiConstants.MISSING_ATTRIBUTE_MESSAGE) + ApiError error = new ApiError.ErrorBuilder().withCode(MISSING_ATTRIBUTE_CODE) + .withMessage(MISSING_ATTRIBUTE_MESSAGE) .andDescription("The attribute " + attributeName + " is required for this operation").build(); return Response.status(Response.Status.BAD_REQUEST).entity(error).build(); } @@ -103,26 +91,28 @@ protected static Response getBadRequestException(String msg) { .withCode(String.valueOf(Response.Status.BAD_REQUEST.getStatusCode())).withMessage(msg).build(); return Response.status(Response.Status.BAD_REQUEST).entity(error).build(); } - + protected static Response getInternalServerException(String msg) { ApiError error = new ApiError.ErrorBuilder() - .withCode(String.valueOf(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())).withMessage(msg).build(); + .withCode(String.valueOf(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode())).withMessage(msg) + .build(); return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(error).build(); } protected SearchRequest createSearchRequest(String schemas, String filter, String sortBy, String sortOrder, - Integer startIndex, Integer count, String attrsList, String excludedAttrsList) { + Integer startIndex, Integer count, String attrsList, String excludedAttrsList, int maximumRecCount) { if (log.isDebugEnabled()) { log.debug( - "Search Request params:: - schemas:{}, filter:{}, sortBy:{}, sortOrder:{}, startIndex:{}, count:{}, attrsList:{}, excludedAttrsList:{} ", + "Search Request params:: - schemas:{}, filter:{}, sortBy:{}, sortOrder:{}, startIndex:{}, count:{}, attrsList:{}, excludedAttrsList:{}, maximumRecCount:{}", escapeLog(schemas), escapeLog(filter), escapeLog(sortBy), escapeLog(sortOrder), - escapeLog(startIndex), escapeLog(count), escapeLog(attrsList), escapeLog(excludedAttrsList)); + escapeLog(startIndex), escapeLog(count), escapeLog(attrsList), escapeLog(excludedAttrsList), + escapeLog(maximumRecCount)); } SearchRequest searchRequest = new SearchRequest(); // Validation checkNotEmpty(schemas, "Schema"); - int maxCount = getMaxCount(); + int maxCount = maximumRecCount; log.debug(" count:{}, maxCount:{}", count, maxCount); if (count > maxCount) { thorwBadRequestException("Maximum number of results per page is " + maxCount); @@ -150,18 +140,10 @@ protected SearchRequest createSearchRequest(String schemas, String filter, Strin searchRequest.setSortOrder(sortOrder); searchRequest.setStartIndex(startIndex); searchRequest.setCount(count); - searchRequest.setMaxCount(getMaxCount()); + searchRequest.setMaxCount(maximumRecCount); return searchRequest; } - protected int getMaxCount() { - log.trace(" MaxCount details - ApiAppConfiguration.MaxCount():{}, DEFAULT_MAX_COUNT:{} ", - configurationFactory.getApiAppConfiguration().getMaxCount(), DEFAULT_MAX_COUNT); - return (configurationFactory.getApiAppConfiguration().getMaxCount() > 0 - ? configurationFactory.getApiAppConfiguration().getMaxCount() - : DEFAULT_MAX_COUNT); - } - }