├── .github
├── ISSUE_TEMPLATE
│ └── config.yml
└── workflows
│ ├── on-pr-merge.yml
│ ├── pr-builder.yml
│ └── coverage-generator.yml
├── components
├── org.wso2.carbon.identity.scim2.provider
│ ├── src
│ │ └── main
│ │ │ ├── resources
│ │ │ └── META-INF
│ │ │ │ └── spring.schemas
│ │ │ ├── webapp
│ │ │ └── META-INF
│ │ │ │ ├── context.xml
│ │ │ │ └── webapp-classloading.xml
│ │ │ └── java
│ │ │ └── org
│ │ │ └── wso2
│ │ │ └── carbon
│ │ │ └── identity
│ │ │ ├── jaxrs
│ │ │ └── designator
│ │ │ │ └── PATCH.java
│ │ │ └── scim2
│ │ │ └── provider
│ │ │ ├── resources
│ │ │ ├── ServiceProviderConfigResource.java
│ │ │ ├── ResourceTypesResource.java
│ │ │ ├── SchemaResource.java
│ │ │ ├── AbstractResource.java
│ │ │ └── BulkResource.java
│ │ │ ├── impl
│ │ │ └── ApplicationInitializer.java
│ │ │ └── util
│ │ │ └── SCIMProviderConstants.java
│ └── pom.xml
└── org.wso2.carbon.identity.scim2.common
│ └── src
│ ├── test
│ ├── resources
│ │ ├── dbscripts
│ │ │ └── identity.sql
│ │ ├── charon-config-test.xml
│ │ └── testng.xml
│ └── java
│ │ └── org
│ │ └── wso2
│ │ └── carbon
│ │ └── identity
│ │ └── scim2
│ │ └── common
│ │ ├── test
│ │ ├── utils
│ │ │ └── CommonTestUtils.java
│ │ └── constants
│ │ │ └── TestConstants.java
│ │ ├── impl
│ │ ├── DefaultSCIMUserStoreErrorResolverTest.java
│ │ ├── IdentitySCIMManagerTest.java
│ │ └── IdentityResourceURLBuilderTest.java
│ │ ├── utils
│ │ ├── AuthenticationSchemaTest.java
│ │ ├── AdminAttributeUtilTest.java
│ │ ├── SCIMConfigProcessorTest.java
│ │ └── AdminAttributeUtilTestForGroup.java
│ │ ├── cache
│ │ └── SCIMSystemAttributeSchemaCacheTest.java
│ │ └── handlers
│ │ └── SCIMClaimOperationEventHandlerTest.java
│ └── main
│ ├── resources
│ └── META-INF
│ │ └── component.xml
│ └── java
│ └── org
│ └── wso2
│ └── carbon
│ └── identity
│ └── scim2
│ └── common
│ ├── exceptions
│ └── IdentitySCIMException.java
│ ├── cache
│ ├── SCIMAgentAttributeSchemaCacheEntry.java
│ ├── SCIMCustomAttributeSchemaCacheEntry.java
│ ├── SCIMSystemAttributeSchemaCacheEntry.java
│ ├── SCIMAgentAttributeSchemaCacheKey.java
│ ├── SCIMCustomAttributeSchemaCacheKey.java
│ ├── SCIMSystemAttributeSchemaCacheKey.java
│ ├── SCIMAgentAttributeSchemaCache.java
│ ├── SCIMCustomAttributeSchemaCache.java
│ └── SCIMSystemAttributeSchemaCache.java
│ ├── extenstion
│ ├── SCIMUserStoreException.java
│ └── SCIMUserStoreErrorResolver.java
│ ├── impl
│ ├── IdentityResourceURLBuilder.java
│ └── DefaultSCIMUserStoreErrorResolver.java
│ ├── utils
│ ├── AuthenticationSchema.java
│ └── SCIMConfigProcessor.java
│ ├── listener
│ └── SCIMTenantMgtListener.java
│ ├── DAO
│ └── SQLQueries.java
│ └── handlers
│ └── SCIMClaimOperationEventHandler.java
├── .gitignore
├── .travis.yml
├── features
├── org.wso2.carbon.identity.scim2.common.feature
│ ├── resources
│ │ ├── org.wso2.carbon.identity.scim2.common.feature.infer.json
│ │ ├── org.wso2.carbon.identity.scim2.common.feature.default.json
│ │ ├── p2.inf
│ │ ├── charon-config.xml
│ │ └── charon-config.xml.j2
│ └── pom.xml
├── org.wso2.carbon.identity.scim2.provider.feature
│ ├── resources
│ │ └── p2.inf
│ └── pom.xml
└── org.wso2.carbon.identity.scim2.server.feature
│ └── pom.xml
├── codecov.yml
├── issue_template.md
├── .connector-store
└── meta.json
├── README.md
└── pull_request_template.md
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: false
2 | contact_links:
3 | - name: Report an issue
4 | url: https://github.com/wso2/product-is/issues/new/choose
5 | about: Issue creation for this component is done in the product-is repo. Click "Open" to continue.
6 |
7 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.provider/src/main/resources/META-INF/spring.schemas:
--------------------------------------------------------------------------------
1 | http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
2 | http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans.xsd
3 |
4 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/test/resources/dbscripts/identity.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE IF NOT EXISTS IDN_SCIM_GROUP (
2 | ID INTEGER NOT NULL AUTO_INCREMENT,
3 | TENANT_ID INTEGER NOT NULL,
4 | ROLE_NAME VARCHAR(255) NOT NULL,
5 | ATTR_NAME VARCHAR(1024) NOT NULL,
6 | ATTR_VALUE VARCHAR(1024),
7 | PRIMARY KEY (ID)
8 | );
9 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 | target
3 | .classpath
4 | .settings
5 | .project
6 | *.iml
7 | *.iws
8 | *.ipr
9 | .idea
10 | *.DS_Store
11 |
12 | # Mobile Tools for Java (J2ME)
13 | .mtj.tmp/
14 |
15 | # Package Files #
16 | *.jar
17 | *.war
18 | *.ear
19 |
20 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
21 | hs_err_pid*
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | before_install:
2 | - wget https://archive.apache.org/dist/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.zip
3 | - unzip -qq apache-maven-3.3.9-bin.zip
4 | - export M2_HOME=$PWD/apache-maven-3.3.9
5 | - export PATH=$M2_HOME/bin:$PATH
6 | language: java
7 | jdk:
8 | - openjdk8
9 | install: /bin/true
10 | script: mvn clean install
11 |
--------------------------------------------------------------------------------
/features/org.wso2.carbon.identity.scim2.common.feature/resources/org.wso2.carbon.identity.scim2.common.feature.infer.json:
--------------------------------------------------------------------------------
1 | {
2 | "scim2.primary_authentication_scheme": {
3 | "oauth_bearer_token": {
4 | "scim2.oauth_bearer.primary": true,
5 | "scim2.http_basic.primary": false
6 | },
7 | "http_basic": {
8 | "scim2.oauth_bearer.primary": false,
9 | "scim2.http_basic.primary": true
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | codecov:
2 | require_ci_to_pass: yes
3 | notify:
4 | wait_for_ci: yes
5 | max_report_age: false
6 |
7 | coverage:
8 | status:
9 | project: off
10 | patch: off
11 |
12 | flag_management:
13 | default_rules:
14 | carryforward: true
15 | individual_flags:
16 | - name: unit
17 | statuses:
18 | - type: project
19 | target: auto
20 | threshold: null
21 | - type: patch
22 | target: 80%
23 | threshold: 40%
24 |
--------------------------------------------------------------------------------
/features/org.wso2.carbon.identity.scim2.provider.feature/resources/p2.inf:
--------------------------------------------------------------------------------
1 | instructions.configure = \
2 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/);\
3 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/);\
4 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\
5 | org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.scim2.provider_${feature.version}/scim2.war,target:${installFolder}/../../deployment/server/webapps/scim2.war,overwrite:true);\
--------------------------------------------------------------------------------
/features/org.wso2.carbon.identity.scim2.common.feature/resources/org.wso2.carbon.identity.scim2.common.feature.default.json:
--------------------------------------------------------------------------------
1 | {
2 | "scim2.enable_schema_extension": true,
3 | "scim2.enable_custom_schema_extension": true,
4 | "scim2.custom_user_schema_uri": "urn:scim:schemas:extension:custom:User",
5 | "scim2.max_bulk_operations": "1000",
6 | "scim2.max_bulk_payload": "1048576",
7 | "scim2.documentation_uri": "https://is.docs.wso2.com/en/latest/apis/scim2/",
8 | "scim2.oauth_bearer.primary": true,
9 | "scim2.http_basic.primary": false,
10 | "scim2.basic_auth_documentation_uri": "$ref{scim2.documentation_uri}",
11 | "scim2.enable_list_user_schemas": true
12 | }
13 |
--------------------------------------------------------------------------------
/issue_template.md:
--------------------------------------------------------------------------------
1 | **Description:**
2 |
3 |
4 | **Suggested Labels:**
5 |
6 |
7 | **Suggested Assignees:**
8 |
9 |
10 | **Affected Product Version:**
11 |
12 | **OS, DB, other environment details and versions:**
13 |
14 | **Steps to reproduce:**
15 |
16 |
17 | **Related Issues:**
18 |
--------------------------------------------------------------------------------
/.connector-store/meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "SCIM 2.0 Inbound Provisioning Connector",
3 | "owner": "WSO2",
4 | "category": "OAuth Client Authenticator",
5 | "documentationUrl": "https://docs.wso2.com/display/ISCONNECTORS/Configuring+SCIM+2.0+Provisioning+Connector",
6 | "description": "The System for Cross-domain Identity Management (SCIM) specification is designed to make managing user identities in cloud-based applications and services easier. SCIM 2.0 Inbound Provisioning Connector enables you to leverage the Identity Server as an SCIM 2.0 Provider to achieve seamless identity inbound provisioning.",
7 | "status": "Active",
8 | "labels": [
9 | "inbound-provisioning",
10 | "IS-5.3.0",
11 | "scim2"
12 | ],
13 | "releases": [
14 | {
15 | "tagName": "1.1.19",
16 | "products": [
17 | "IS 5.3.0"
18 | ]
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/.github/workflows/on-pr-merge.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run when a PR is merged and save the PR information for later use.
2 |
3 | name: 💡 PR Merged
4 |
5 | on:
6 | pull_request:
7 | types: [closed]
8 | branches: [master, main]
9 |
10 | jobs:
11 | save-pr-information:
12 | runs-on: ubuntu-latest
13 | if: github.event.pull_request.merged == true
14 | steps:
15 | - name: ⬇️ Checkout
16 | uses: actions/checkout@v3
17 |
18 | - name: ℹ️ Display PR Information
19 | run: echo "PR Number \#${{github.event.number}}"
20 |
21 | - name: 💾 Save PR Number for Later Use
22 | run: echo "${{github.event.number}}" > PR_NUMBER
23 |
24 | - name: 📦 Upload PR Number as Artifact
25 | uses: actions/upload-artifact@v4
26 | with:
27 | name: pr-number
28 | path: PR_NUMBER
29 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.provider/src/main/webapp/META-INF/context.xml:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/resources/META-INF/component.xml:
--------------------------------------------------------------------------------
1 |
17 |
18 |
19 |
20 |
21 |
22 | Identity Provisioning
23 | /permission/admin/configure/security/usermgt/provisioning
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.provider/src/main/java/org/wso2/carbon/identity/jaxrs/designator/PATCH.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.wso2.carbon.identity.jaxrs.designator;
18 |
19 | import javax.ws.rs.HttpMethod;
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | /**
26 | * Creates the PATCH HTTP method, since JAX-RS does not support it natively yet
27 | */
28 | @Target({ElementType.METHOD})
29 | @Retention(RetentionPolicy.RUNTIME)
30 | @HttpMethod("PATCH")
31 | public @interface PATCH {
32 | }
33 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/exceptions/IdentitySCIMException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.exceptions;
20 |
21 | import org.wso2.carbon.identity.base.IdentityException;
22 |
23 | public class IdentitySCIMException extends IdentityException {
24 |
25 | private static final long serialVersionUID = 3477076930789578976L;
26 |
27 | public IdentitySCIMException(String error) {
28 | super(error);
29 | }
30 |
31 | public IdentitySCIMException(String message, Throwable cause) {
32 | super(message, cause);
33 | }
34 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Welcome to the WSO2 Identity Server (IS) identity-inbound-provisioning-scim2.
2 |
3 | WSO2 IS is one of the best Identity Servers, which enables you to offload your identity and user entitlement management burden totally from your application. It comes with many features, supports many industry standards and most importantly it allows you to extent it according to your security requirements. This repo contains Authenticators written to work with different third party systems.
4 |
5 | With WSO2 IS, there are lot of provisioning capabilities available. There are 3 major concepts as Inbound, outbound provisioning and Just-In-Time provisioning. Inbound provisioning means , provisioning users and groups from an external system to IS. Outbound provisioning means , provisioning users from IS to other external systems. JIT provisioning means , once a user tries to login from an external IDP, a user can be created on the fly in IS with JIT. Repos under this account holds such components invlove in communicating with external systems.
6 |
7 | ## Building from the source
8 |
9 | If you want to build **identity-inbound-provisioning-scim2** from the source code:
10 |
11 | 1. Install Java 11 (or Java 17)
12 | 2. Install Apache Maven 3.x.x (https://maven.apache.org/download.cgi#)
13 | 3. Get a clone or download the source from this repository (https://github.com/wso2-extensions/identity-inbound-provisioning-scim2)
14 | 4. Run the Maven command ``mvn clean install`` from the ``identity-inbound-provisioning-scim2`` directory.
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/cache/SCIMAgentAttributeSchemaCacheEntry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3 | *
4 | * WSO2 LLC. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.cache;
20 |
21 | import org.wso2.charon3.core.schema.AttributeSchema;
22 |
23 | import java.io.Serializable;
24 |
25 | /**
26 | * This stores list of custom attributes of SCIM2 agent schema.
27 | */
28 | public class SCIMAgentAttributeSchemaCacheEntry implements Serializable {
29 |
30 | private static final long serialVersionUID = 3784848233717914595L;
31 |
32 | private final AttributeSchema attributeSchema;
33 |
34 | public SCIMAgentAttributeSchemaCacheEntry(AttributeSchema attributeSchema) {
35 |
36 | this.attributeSchema = attributeSchema;
37 | }
38 |
39 | public AttributeSchema getSCIMAgentAttributeSchema() {
40 |
41 | return attributeSchema;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/cache/SCIMCustomAttributeSchemaCacheEntry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.cache;
20 |
21 | import org.wso2.charon3.core.schema.AttributeSchema;
22 |
23 | import java.io.Serializable;
24 |
25 | /**
26 | * This stores list of custom attributes of SCIM2 custom schema.
27 | */
28 | public class SCIMCustomAttributeSchemaCacheEntry implements Serializable {
29 |
30 | private static final long serialVersionUID = -3352517105334401998L;
31 |
32 | private final AttributeSchema attributeSchema;
33 |
34 | public SCIMCustomAttributeSchemaCacheEntry(AttributeSchema attributeSchema) {
35 |
36 | this.attributeSchema = attributeSchema;
37 | }
38 |
39 | public AttributeSchema getSCIMCustomAttributeSchema() {
40 |
41 | return attributeSchema;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/cache/SCIMSystemAttributeSchemaCacheEntry.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.cache;
20 |
21 | import org.wso2.charon3.core.schema.AttributeSchema;
22 |
23 | import java.io.Serializable;
24 |
25 | /**
26 | * This stores list of custom attributes of SCIM2 system schema.
27 | */
28 | public class SCIMSystemAttributeSchemaCacheEntry implements Serializable {
29 |
30 | private static final long serialVersionUID = 3784848233717914594L;
31 |
32 | private final AttributeSchema attributeSchema;
33 |
34 | public SCIMSystemAttributeSchemaCacheEntry(AttributeSchema attributeSchema) {
35 |
36 | this.attributeSchema = attributeSchema;
37 | }
38 |
39 | public AttributeSchema getSCIMSystemAttributeSchema() {
40 |
41 | return attributeSchema;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.provider/src/main/webapp/META-INF/webapp-classloading.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
20 |
23 |
24 |
25 |
26 | false
27 |
28 |
33 | CXF3,Carbon
34 |
35 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/extenstion/SCIMUserStoreException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.extenstion;
20 |
21 | import org.wso2.carbon.identity.base.IdentityException;
22 |
23 | /**
24 | * This exception is used in the SCIM User Store Error Resolver extension point, to return any internal errors to
25 | * the SCIM API layer. Since SCIM API returns only an error message (detail) and http error code, this
26 | * exception is designed to accept only those two.
27 | */
28 | public class SCIMUserStoreException extends IdentityException {
29 |
30 | private static final long serialVersionUID = 3477076930782578976L;
31 | private final int httpStatusCode;
32 |
33 | public SCIMUserStoreException(String errorMessage, int httpStatusCode) {
34 |
35 | super(errorMessage);
36 | this.httpStatusCode = httpStatusCode;
37 | }
38 |
39 | public int getHttpStatusCode() {
40 |
41 | return httpStatusCode;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/.github/workflows/pr-builder.yml:
--------------------------------------------------------------------------------
1 | # This workflow will build the project on pull requests with tests
2 | # Uses:
3 | # OS: ubuntu-latest
4 | # JDK: Temurin JDK 11 and Adopt JDK 17
5 |
6 | name: PR Builder
7 |
8 | on:
9 | pull_request:
10 | branches: [main, master]
11 | workflow_dispatch:
12 |
13 | env:
14 | MAVEN_OPTS: -Xmx4g -Xms1g
15 |
16 | jobs:
17 | build:
18 | runs-on: ubuntu-latest
19 |
20 | env:
21 | JAVA_TOOL_OPTIONS: "-Djdk.util.zip.disableZip64ExtraFieldValidation=true -Djdk.nio.zipfs.allowDotZipEntry=true"
22 |
23 | strategy:
24 | matrix:
25 | java-version: [ 11, 17 ]
26 |
27 | steps:
28 | - uses: actions/checkout@v4
29 | - name: Set up Temurin JDK 11 and 17
30 | uses: actions/setup-java@v4
31 | with:
32 | java-version: ${{ matrix.java-version }}
33 | distribution: "temurin"
34 | - name: Cache local Maven repository
35 | id: cache-maven-m2
36 | uses: actions/cache@v4
37 | env:
38 | cache-name: cache-m2
39 | with:
40 | path: ~/.m2/repository
41 | key: ${{ runner.os }}-maven-${{ env.cache-name }}-${{ hashFiles('**/pom.xml') }}
42 | restore-keys: |
43 | ${{ runner.os }}-maven-${{ env.cache-name }}-
44 | ${{ runner.os }}-maven-
45 | ${{ runner.os }}-
46 | - name: Build with Maven
47 | run: mvn clean install -U -B
48 |
49 | - name: Generate coverage report
50 | run: mvn test jacoco:report
51 |
52 | - name: Upload coverage reports to Codecov
53 | uses: codecov/codecov-action@v4
54 | with:
55 | token: ${{ secrets.CODECOV_TOKEN }}
56 | files : target/site/jacoco/jacoco.xml
57 | flags: unit
58 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/cache/SCIMAgentAttributeSchemaCacheKey.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3 | *
4 | * WSO2 LLC. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.cache;
20 |
21 | import java.io.Serializable;
22 |
23 | /**
24 | * SCIM Agent Schema Cache key. This contains tenant ID as the key.
25 | */
26 | public class SCIMAgentAttributeSchemaCacheKey implements Serializable {
27 |
28 | private static final long serialVersionUID = -6137657709191460467L;
29 |
30 | private final int tenantId;
31 |
32 | public SCIMAgentAttributeSchemaCacheKey(int tenantId) {
33 |
34 | this.tenantId = tenantId;
35 | }
36 |
37 | public int getTenantId() {
38 |
39 | return tenantId;
40 | }
41 |
42 | @Override
43 | public boolean equals(Object o) {
44 |
45 | if (this == o) {
46 | return true;
47 | }
48 |
49 | if (!(o instanceof SCIMAgentAttributeSchemaCacheKey)) {
50 | return false;
51 | }
52 |
53 | SCIMAgentAttributeSchemaCacheKey that = (SCIMAgentAttributeSchemaCacheKey) o;
54 | return tenantId == that.tenantId;
55 | }
56 |
57 | @Override
58 | public int hashCode() {
59 |
60 | return tenantId;
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/cache/SCIMCustomAttributeSchemaCacheKey.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.cache;
20 |
21 | import java.io.Serializable;
22 |
23 | /**
24 | * SCIM Custom Schema Cache key. This contains tenant Id as the key.
25 | */
26 | public class SCIMCustomAttributeSchemaCacheKey implements Serializable {
27 |
28 | private static final long serialVersionUID = -1332814776225574523L;
29 |
30 | private final int tenantId;
31 |
32 | public SCIMCustomAttributeSchemaCacheKey(int tenantId) {
33 |
34 | this.tenantId = tenantId;
35 | }
36 |
37 | public int getTenantId() {
38 |
39 | return tenantId;
40 | }
41 |
42 | @Override
43 | public boolean equals(Object o) {
44 |
45 | if (this == o) {
46 | return true;
47 | }
48 |
49 | if (!(o instanceof SCIMCustomAttributeSchemaCacheKey)) {
50 | return false;
51 | }
52 |
53 | SCIMCustomAttributeSchemaCacheKey that = (SCIMCustomAttributeSchemaCacheKey) o;
54 | return tenantId == that.tenantId;
55 | }
56 |
57 | @Override
58 | public int hashCode() {
59 | return tenantId;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/cache/SCIMSystemAttributeSchemaCacheKey.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.cache;
20 |
21 | import java.io.Serializable;
22 |
23 | /**
24 | * SCIM System Schema Cache key. This contains tenant ID as the key.
25 | */
26 | public class SCIMSystemAttributeSchemaCacheKey implements Serializable {
27 |
28 | private static final long serialVersionUID = -6137657709191460466L;
29 |
30 | private final int tenantId;
31 |
32 | public SCIMSystemAttributeSchemaCacheKey(int tenantId) {
33 |
34 | this.tenantId = tenantId;
35 | }
36 |
37 | public int getTenantId() {
38 |
39 | return tenantId;
40 | }
41 |
42 | @Override
43 | public boolean equals(Object o) {
44 |
45 | if (this == o) {
46 | return true;
47 | }
48 |
49 | if (!(o instanceof SCIMSystemAttributeSchemaCacheKey)) {
50 | return false;
51 | }
52 |
53 | SCIMSystemAttributeSchemaCacheKey that = (SCIMSystemAttributeSchemaCacheKey) o;
54 | return tenantId == that.tenantId;
55 | }
56 |
57 | @Override
58 | public int hashCode() {
59 | return tenantId;
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.provider/src/main/java/org/wso2/carbon/identity/scim2/provider/resources/ServiceProviderConfigResource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 |
20 | package org.wso2.carbon.identity.scim2.provider.resources;
21 |
22 | import org.wso2.carbon.identity.scim2.provider.util.SupportUtils;
23 | import org.wso2.charon3.core.protocol.SCIMResponse;
24 | import org.wso2.charon3.core.protocol.endpoints.ServiceProviderConfigResourceManager;
25 |
26 | import javax.ws.rs.*;
27 | import javax.ws.rs.core.MediaType;
28 | import javax.ws.rs.core.Response;
29 |
30 | @Path("/")
31 | public class ServiceProviderConfigResource extends AbstractResource {
32 | @GET
33 | @Produces(MediaType.APPLICATION_JSON)
34 | public Response getUser() {
35 | // create charon-SCIM service provider config endpoint and hand-over the request.
36 | ServiceProviderConfigResourceManager serviceProviderConfigResourceManager =
37 | new ServiceProviderConfigResourceManager();
38 |
39 | SCIMResponse scimResponse = serviceProviderConfigResourceManager.get(null, null, null, null);
40 | // needs to check the code of the response and return 200 0k or other error codes
41 | // appropriately.
42 | return SupportUtils.buildResponse(scimResponse);
43 | }
44 | }
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/extenstion/SCIMUserStoreErrorResolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.extenstion;
20 |
21 | import org.wso2.carbon.user.api.UserStoreException;
22 |
23 | /**
24 | * This extension point can be used to define how internal errors should be mapped to relevant API errors.
25 | */
26 | public interface SCIMUserStoreErrorResolver {
27 |
28 | /**
29 | * Resolve a given user store exception to a proper Charon Exception with status code. implementation should
30 | * return null if the implementing class does not know or does not wish to translate the exception, so that
31 | * any other translator can get chance to do the resolving. The default resolver will resolve an exception
32 | * ultimately if no custom resolver resolves it.
33 | *
34 | * @param e User store exception thrown.
35 | * @return Resolved charon exception with proper http status code, NULL if the impl doesn't know how to resolve.
36 | */
37 | SCIMUserStoreException resolve(UserStoreException e);
38 |
39 | /**
40 | * Provide an order value for the implementation. Should be a positive integer.
41 | * implementation with the highest order get picked first.
42 | *
43 | * @return Order of the impl.
44 | */
45 | int getOrder();
46 | }
47 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.provider/src/main/java/org/wso2/carbon/identity/scim2/provider/resources/ResourceTypesResource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.provider.resources;
20 |
21 | import org.wso2.carbon.identity.scim2.common.impl.IdentityResourceTypeResourceManager;
22 | import org.wso2.carbon.identity.scim2.provider.util.SCIMProviderConstants;
23 | import org.wso2.carbon.identity.scim2.provider.util.SupportUtils;
24 | import org.wso2.charon3.core.protocol.SCIMResponse;
25 | import org.wso2.charon3.core.protocol.endpoints.ResourceTypeResourceManager;
26 |
27 | import javax.ws.rs.GET;
28 | import javax.ws.rs.Path;
29 | import javax.ws.rs.Produces;
30 | import javax.ws.rs.core.MediaType;
31 | import javax.ws.rs.core.Response;
32 |
33 | @Path("/")
34 | public class ResourceTypesResource extends AbstractResource {
35 | @GET
36 | @Produces({MediaType.APPLICATION_JSON, SCIMProviderConstants.APPLICATION_SCIM_JSON})
37 | public Response getUser() {
38 | // create charon-SCIM service provider config endpoint and hand-over the request.
39 | IdentityResourceTypeResourceManager resourceTypeResourceManager = new IdentityResourceTypeResourceManager();
40 |
41 | SCIMResponse scimResponse = resourceTypeResourceManager.get(null, null, null, null);
42 | // needs to check the code of the response and return 200 0k or other error codes
43 | // appropriately.
44 | return SupportUtils.buildResponse(scimResponse);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.provider/src/main/java/org/wso2/carbon/identity/scim2/provider/impl/ApplicationInitializer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.provider.impl;
20 |
21 | import org.apache.commons.logging.Log;
22 | import org.apache.commons.logging.LogFactory;
23 | import org.wso2.carbon.identity.scim2.common.impl.IdentitySCIMManager;
24 | import org.wso2.charon3.core.exceptions.CharonException;
25 |
26 | import javax.servlet.ServletContextEvent;
27 | import javax.servlet.ServletContextListener;
28 |
29 | /**
30 | * This performs one-time initialization tasks at the application startup.
31 | */
32 | public class ApplicationInitializer implements ServletContextListener {
33 |
34 | private static final Log logger = LogFactory.getLog(ApplicationInitializer.class);
35 |
36 | @Override
37 | public void contextInitialized(ServletContextEvent servletContextEvent) {
38 | if (logger.isDebugEnabled()) {
39 | logger.debug("Initializing SCIM Webapp...");
40 | }
41 | try {
42 | //initialize identity scim manager
43 | IdentitySCIMManager.getInstance();
44 |
45 | } catch (CharonException e) {
46 | logger.error("Error in initializing the IdentitySCIMManager at the initialization of " +
47 | "SCIM webapp", e);
48 | }
49 | }
50 |
51 | @Override
52 | public void contextDestroyed(ServletContextEvent servletContextEvent) {
53 | // Do nothing
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/features/org.wso2.carbon.identity.scim2.common.feature/resources/p2.inf:
--------------------------------------------------------------------------------
1 | instructions.configure = \
2 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository); \
3 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/conf); \
4 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/conf/identity); \
5 | org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.scim2.common_${feature.version}/charon-config.xml,target:${installFolder}/../../conf/identity/charon-config.xml,overwrite:true); \
6 | org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.scim2.common_${feature.version}/scim2-schema-extension.config,target:${installFolder}/../../conf/identity/scim2-schema-extension.config,overwrite:true); \
7 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/resources); \
8 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/resources/conf); \
9 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/resources/conf/templates); \
10 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/resources/conf/templates/repository); \
11 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/resources/conf/templates/repository/conf); \
12 | org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../../repository/resources/conf/templates/repository/conf/identity); \
13 | org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.scim2.common_${feature.version}/charon-config.xml.j2,target:${installFolder}/../../resources/conf/templates/repository/conf/identity/charon-config.xml.j2,overwrite:true);\
14 | org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.scim2.common_${feature.version}/org.wso2.carbon.identity.scim2.common.feature.default.json,target:${installFolder}/../../resources/conf/org.wso2.carbon.identity.scim2.common.feature.default.json,overwrite:true);\
15 | org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.identity.scim2.common_${feature.version}/org.wso2.carbon.identity.scim2.common.feature.infer.json,target:${installFolder}/../../resources/conf/org.wso2.carbon.identity.scim2.common.feature.infer.json,overwrite:true);\
16 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/impl/IdentityResourceURLBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.impl;
20 |
21 | import org.apache.commons.logging.Log;
22 | import org.apache.commons.logging.LogFactory;
23 | import org.wso2.carbon.identity.core.ServiceURLBuilder;
24 | import org.wso2.carbon.identity.core.URLBuilderException;
25 | import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
26 | import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonConstants;
27 | import org.wso2.charon3.core.exceptions.NotFoundException;
28 | import org.wso2.charon3.core.protocol.endpoints.DefaultResourceURLBuilder;
29 |
30 | /**
31 | * Class responsible for constructing SCIM2 resource endpoints with tenant context.
32 | */
33 | public class IdentityResourceURLBuilder extends DefaultResourceURLBuilder {
34 |
35 | private static final Log log = LogFactory.getLog(IdentityResourceURLBuilder.class);
36 |
37 | @Override
38 | public String build(String resource) throws NotFoundException {
39 |
40 | if (IdentityTenantUtil.isTenantQualifiedUrlsEnabled()) {
41 | try {
42 | String scimURL = ServiceURLBuilder.create().addPath(SCIMCommonConstants.SCIM2_ENDPOINT).build()
43 | .getAbsolutePublicURL();
44 | return scimURL + resource;
45 | } catch (URLBuilderException e) {
46 | if (log.isDebugEnabled()) {
47 | log.debug("Error occurred while building the SCIM2 endpoint with tenant " +
48 | "qualified URL.", e);
49 | }
50 | // Fallback to super class build method during error scenarios.
51 | return super.build(resource);
52 | }
53 | } else {
54 | return super.build(resource);
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/test/resources/charon-config-test.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 | true
21 | true
22 | http://example.com/help/scim.html
23 | true
24 | 1000
25 | 1048576
26 | true
27 | 200
28 | true
29 | false
30 | false
31 | 100
32 |
33 |
34 | OAuth Bearer Token
35 | Authentication scheme using the OAuth Bearer Token Standard
36 | http://www.rfc-editor.org/info/rfc6750
37 | http://example.com/help/oauth.html
38 | oauthbearertoken
39 | true
40 |
41 |
42 | HTTP Basic
43 | Authentication scheme using the HTTP Basic Standard
44 | http://www.rfc-editor.org/info/rfc2617
45 | http://example.com/help/httpBasic.html
46 | httpbasic
47 | false
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/test/utils/CommonTestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, WSO2 LLC. (http://www.wso2.org)
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.test.utils;
20 |
21 |
22 | import org.wso2.carbon.base.CarbonBaseConstants;
23 | import org.wso2.carbon.base.MultitenantConstants;
24 | import org.wso2.carbon.context.PrivilegedCarbonContext;
25 |
26 | import java.nio.file.Paths;
27 |
28 | public class CommonTestUtils {
29 |
30 | private CommonTestUtils() {
31 | }
32 |
33 | public static void initPrivilegedCarbonContext(String tenantDomain, int tenantID, String userName) throws Exception {
34 | String carbonHome = Paths.get(System.getProperty("user.dir"), "target").toString();
35 | System.setProperty(CarbonBaseConstants.CARBON_HOME, carbonHome);
36 | PrivilegedCarbonContext.startTenantFlow();
37 | PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain);
38 | PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantID);
39 | PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(userName);
40 | }
41 |
42 | public static void initPrivilegedCarbonContext(String tenantDomain, String userName) throws Exception {
43 | int tenantID = MultitenantConstants.SUPER_TENANT_ID;
44 | initPrivilegedCarbonContext(tenantDomain, tenantID, userName);
45 | }
46 |
47 | public static void initPrivilegedCarbonContext(String tenantDomain) throws Exception {
48 | int tenantID = MultitenantConstants.SUPER_TENANT_ID;
49 | String userName = "testUser";
50 |
51 | initPrivilegedCarbonContext(tenantDomain, tenantID, userName);
52 | }
53 |
54 | public static void initPrivilegedCarbonContext() throws Exception {
55 | String tenantDomain = MultitenantConstants.SUPER_TENANT_DOMAIN_NAME;
56 | int tenantID = MultitenantConstants.SUPER_TENANT_ID;
57 | String userName = "testUser";
58 |
59 | initPrivilegedCarbonContext(tenantDomain, tenantID, userName);
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Purpose
2 | > Describe the problems, issues, or needs driving this feature/fix and include links to related issues in the following format: Resolves issue1, issue2, etc.
3 |
4 | ## Goals
5 | > Describe the solutions that this feature/fix will introduce to resolve the problems described above
6 |
7 | ## Approach
8 | > Describe how you are implementing the solutions. Include an animated GIF or screenshot if the change affects the UI (email documentation@wso2.com to review all UI text). Include a link to a Markdown file or Google doc if the feature write-up is too long to paste here.
9 |
10 | ## User stories
11 | > Summary of user stories addressed by this change>
12 |
13 | ## Developer Checklist (Mandatory)
14 | - [ ] Complete the **Developer Checklist** in the related `product-is` issue to track any behavioral change or migration impact.
15 |
16 | ## Release note
17 | > Brief description of the new feature or bug fix as it will appear in the release notes
18 |
19 | ## Documentation
20 | > Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact
21 |
22 | ## Training
23 | > Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable
24 |
25 | ## Certification
26 | > Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why.
27 |
28 | ## Marketing
29 | > Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable
30 |
31 | ## Automation tests
32 | - Unit tests
33 | > Code coverage information
34 | - Integration tests
35 | > Details about the test cases and coverage
36 |
37 | ## Security checks
38 | - Followed secure coding standards in http://wso2.com/technical-reports/wso2-secure-engineering-guidelines? yes/no
39 | - Ran FindSecurityBugs plugin and verified report? yes/no
40 | - Confirmed that this PR doesn't commit any keys, passwords, tokens, usernames, or other secrets? yes/no
41 |
42 | ## Samples
43 | > Provide high-level details about the samples related to this feature
44 |
45 | ## Related PRs
46 | > List any other related PRs
47 |
48 | ## Migrations (if applicable)
49 | > Describe migration steps and platforms on which migration has been tested
50 |
51 | ## Test environment
52 | > List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested
53 |
54 | ## Learning
55 | > Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem.
--------------------------------------------------------------------------------
/features/org.wso2.carbon.identity.scim2.common.feature/resources/charon-config.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 | true
21 | true
22 | urn:scim:schemas:extension:custom:User
23 | true
24 | http://example.com/help/scim.html
25 | true
26 | 1000
27 | 1048576
28 | true
29 | 200
30 | true
31 | false
32 | false
33 | 100
34 | true
35 |
36 |
37 | OAuth Bearer Token
38 | Authentication scheme using the OAuth Bearer Token Standard
39 | http://www.rfc-editor.org/info/rfc6750
40 | http://example.com/help/oauth.html
41 | oauthbearertoken
42 | true
43 |
44 |
45 | HTTP Basic
46 | Authentication scheme using the HTTP Basic Standard
47 | http://www.rfc-editor.org/info/rfc2617
48 | http://example.com/help/httpBasic.html
49 | httpbasic
50 | false
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/test/resources/testng.xml:
--------------------------------------------------------------------------------
1 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/features/org.wso2.carbon.identity.scim2.common.feature/resources/charon-config.xml.j2:
--------------------------------------------------------------------------------
1 |
2 |
19 |
20 |
21 | {{scim2.enable_schema_extension}}
22 | {{scim2.enable_custom_schema_extension}}
23 | {{scim2.custom_user_schema_uri}}
24 | {{scim2.max_bulk_operations}}
25 | {{scim2.max_bulk_payload}}
26 | {{scim2.documentation_uri}}
27 | true
28 | true
29 | true
30 | 200
31 | true
32 | false
33 | false
34 | 100
35 | scim2.enable_list_user_schemas
36 |
37 |
38 | OAuth Bearer Token
39 | Authentication scheme using the OAuth Bearer Token Standard
40 | http://www.rfc-editor.org/info/rfc6750
41 | {{scim2.basic_auth_documentation_uri}}
42 | oauthbearertoken
43 | {{scim2.oauth_bearer.primary}}
44 |
45 |
46 | HTTP Basic
47 | Authentication scheme using the HTTP Basic Standard
48 | http://www.rfc-editor.org/info/rfc2617
49 | {{scim2.oauth_bearer_auth_documentation_uri}}
50 | httpbasic
51 | {{scim2.http_basic.primary}}
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/utils/AuthenticationSchema.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.utils;
20 |
21 | import java.util.Map;
22 |
23 | /**
24 | * this class is the blue print of authentication schemas used in ServiceProvidesConfig.
25 | */
26 | public class AuthenticationSchema {
27 |
28 | private String name;
29 | private String description;
30 | private String specUri;
31 | private String documentationUri;
32 | private String type;
33 | private String primary;
34 |
35 | public String getName() {
36 | return name;
37 | }
38 |
39 | public void setName(String name) {
40 | this.name = name;
41 | }
42 |
43 | public String getDescription() {
44 | return description;
45 | }
46 |
47 | public void setDescription(String description) {
48 | this.description = description;
49 | }
50 |
51 | public String getSpecUri() {
52 | return specUri;
53 | }
54 |
55 | public void setSpecUri(String specUri) {
56 | this.specUri = specUri;
57 | }
58 |
59 | public String getDocumentationUri() {
60 | return documentationUri;
61 | }
62 |
63 | public void setDocumentationUri(String documentationUri) {
64 | this.documentationUri = documentationUri;
65 | }
66 |
67 | public String getType() {
68 | return type;
69 | }
70 |
71 | public void setType(String type) {
72 | this.type = type;
73 | }
74 |
75 | public String getPrimary() {
76 | return primary;
77 | }
78 |
79 | public void setPrimary(String primary) {
80 | this.primary = primary;
81 | }
82 |
83 | public void setProperties(Map properties) {
84 | for (Map.Entry property : properties.entrySet()) {
85 | if (property.getKey().equals("name")) {
86 | setName(property.getValue());
87 | } else if (property.getKey().equals("description")) {
88 | setDescription(property.getValue());
89 | } else if (property.getKey().equals("specUri")) {
90 | setSpecUri(property.getValue());
91 | } else if (property.getKey().equals("documentationUri")) {
92 | setDocumentationUri(property.getValue());
93 | } else if (property.getKey().equals("type")) {
94 | setType(property.getValue());
95 | } else if (property.getKey().equals("primary")) {
96 | setPrimary(property.getValue());
97 | }
98 | }
99 | }
100 | }
101 |
102 |
103 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.provider/src/main/java/org/wso2/carbon/identity/scim2/provider/util/SCIMProviderConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.provider.util;
20 |
21 | public class SCIMProviderConstants {
22 |
23 | public static final String AUTHORIZATION = "Authorization";
24 | public static final String CONTENT_TYPE = "Content-Type";
25 | public static final String ATTRIBUTES = "attributes";
26 | public static final String EXCLUDE_ATTRIBUTES = "excludedAttributes";
27 | public static final String FILTER = "filter";
28 | public static final String START_INDEX = "startIndex";
29 | public static final String COUNT = "count";
30 | public static final String SORT_BY = "sortBy";
31 | public static final String SORT_ORDER = "sortOder";
32 | public static final String SCIM_VERSION = "scimVersion";
33 | public static final String SCIM_VERSION_V3 = "v3";
34 | public static final String APPLICATION_SCIM_JSON = "application/scim+json";
35 | public static final String APPLICATION__JSON = "application/json";
36 | public static final String APPLICATION_ALL = "application/*";
37 | public static final String CHARSET_UTF8= "charset=utf-8";
38 | public static final String SEMI_COLON = ";";
39 | public static final String CHARSET= "charset";
40 | public static final String ACCEPT_HEADER = "Accept";
41 | public static final String ID = "id";
42 | public static final String DOMAIN = "domain";
43 | public static final String GROUPS = "groups";
44 | public static final String USERS = "users";
45 |
46 | public static final String RESOURCE_STRING = "RESOURCE_STRING";
47 | public static final String HTTP_VERB = "HTTP_VERB";
48 | public static final String SEARCH = ".search";
49 | public static final String DEFAULT_USERNAME = "admin";
50 | public static final String ADD = "add";
51 | public static final String OPERATIONS = "Operations";
52 | public static final String OP = "op";
53 | public static final String PATH = "path";
54 | public static final String REMOVE = "remove";
55 | public static final String REPLACE = "replace";
56 | public static final String VALUE_EQ = "value eq";
57 |
58 | public static final String BULK_CREATE_ROLE_OPERATION_NAME = "createRole";
59 | public static final String BULK_UPDATE_ROLE_OPERATION_NAME = "updateRole";
60 | public static final String BULK_DELETE_ROLE_OPERATION_NAME = "deleteRole";
61 |
62 | public static final String SKIP_ENFORCE_ROLE_OPERATION_PERMISSION = "RoleMgt.SkipEnforceRoleOperationPermission";
63 |
64 | /*
65 | * This class contains constants related to SCIM Role operations.
66 | */
67 | public static class RoleV2Operations {
68 |
69 | public static final String UPDATE_ROLE_PERMISSIONS = "updateRolePermissions";
70 | public static final String UPDATE_ROLE_MEMBERS = "updateRoleMembers";
71 | public static final String UPDATE_ROLE_GROUPS = "updateRoleGroups";
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.provider/src/main/java/org/wso2/carbon/identity/scim2/provider/resources/SchemaResource.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.provider.resources;
20 |
21 | import org.apache.commons.logging.Log;
22 | import org.apache.commons.logging.LogFactory;
23 | import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
24 | import org.wso2.carbon.identity.scim2.common.impl.IdentitySCIMManager;
25 | import org.wso2.carbon.identity.scim2.provider.util.SCIMProviderConstants;
26 | import org.wso2.carbon.identity.scim2.provider.util.SupportUtils;
27 | import org.wso2.charon3.core.exceptions.CharonException;
28 | import org.wso2.charon3.core.extensions.UserManager;
29 | import org.wso2.charon3.core.protocol.SCIMResponse;
30 | import org.wso2.charon3.core.protocol.endpoints.SchemaResourceManager;
31 | import org.wso2.charon3.core.schema.SCIMConstants;
32 |
33 | import javax.ws.rs.GET;
34 | import javax.ws.rs.Path;
35 | import javax.ws.rs.PathParam;
36 | import javax.ws.rs.Produces;
37 | import javax.ws.rs.core.MediaType;
38 | import javax.ws.rs.core.Response;
39 |
40 | import static org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils.getTenantDomainFromContext;
41 |
42 | public class SchemaResource extends AbstractResource {
43 |
44 | private static final Log logger = LogFactory.getLog(SchemaResource.class);
45 |
46 | @GET
47 | @Produces(MediaType.APPLICATION_JSON)
48 | public Response getSchemas() {
49 |
50 | try {
51 | UserManager userManager = IdentitySCIMManager.getInstance().getUserManager();
52 |
53 | // create charon-SCIM schemas endpoint and hand-over the request.
54 | SchemaResourceManager schemaResourceManager = new SchemaResourceManager();
55 | SCIMResponse scimResponse = schemaResourceManager.get(null, userManager, null, null);
56 |
57 | return SupportUtils.buildResponse(scimResponse);
58 |
59 | } catch (CharonException e) {
60 | return handleCharonException(e);
61 | }
62 | }
63 |
64 | @GET
65 | @Path("/{id}")
66 | @Produces({MediaType.APPLICATION_JSON, SCIMProviderConstants.APPLICATION_SCIM_JSON})
67 | public Response getSchemasById(@PathParam(SCIMConstants.CommonSchemaConstants.ID) String id) {
68 |
69 | try {
70 | UserManager userManager = IdentitySCIMManager.getInstance().getUserManager();
71 |
72 | if (IdentityTenantUtil.isTenantQualifiedUrlsEnabled()) {
73 | String tenantDomain = getTenantDomainFromContext();
74 | }
75 |
76 | // create charon-SCIM schemas endpoint and hand-over the request.
77 | SchemaResourceManager schemaResourceManager = new SchemaResourceManager();
78 | SCIMResponse scimResponse = schemaResourceManager.get(id, userManager, null, null);
79 |
80 | return SupportUtils.buildResponse(scimResponse);
81 | } catch (CharonException e) {
82 | return handleCharonException(e);
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/impl/DefaultSCIMUserStoreErrorResolverTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, WSO2 LLC. (http://www.wso2.org)
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.impl;
20 |
21 | import org.apache.http.HttpStatus;
22 | import org.testng.annotations.DataProvider;
23 | import org.testng.annotations.Test;
24 | import org.wso2.carbon.identity.scim2.common.extenstion.SCIMUserStoreException;
25 | import org.wso2.carbon.user.api.UserStoreException;
26 |
27 | import static org.testng.Assert.assertEquals;
28 | import static org.testng.Assert.assertNull;
29 |
30 | /**
31 | * Contains the unit test cases for DefaultSCIMUserStoreErrorResolver.
32 | */
33 | public class DefaultSCIMUserStoreErrorResolverTest {
34 |
35 | @Test
36 | public void testGetOrder() {
37 |
38 | DefaultSCIMUserStoreErrorResolver defaultSCIMUserStoreErrorResolver = new DefaultSCIMUserStoreErrorResolver();
39 | assertEquals(defaultSCIMUserStoreErrorResolver.getOrder(), 0);
40 | }
41 |
42 | @DataProvider(name = "dataProviderForResolveUserNameMandatory")
43 | public Object[][] dataProviderForResolveUserNameMandatory() {
44 |
45 | return new Object[][]{
46 | {new UserStoreException("error: 30007"), HttpStatus.SC_NOT_FOUND},
47 | {new org.wso2.carbon.user.core.UserStoreException("error", "32102"), HttpStatus.SC_BAD_REQUEST},
48 | {new org.wso2.carbon.user.core.UserStoreClientException("error", "32103"), HttpStatus.SC_BAD_REQUEST},
49 | {new org.wso2.carbon.user.core.UserStoreClientException("error", "321xx"), HttpStatus.SC_BAD_REQUEST},
50 | {new org.wso2.carbon.user.core.UserStoreClientException("30012 - error", "xxx"), HttpStatus.SC_CONFLICT},
51 | {new org.wso2.carbon.user.core.UserStoreClientException("error", "65019"), HttpStatus.SC_CONFLICT},
52 | {new org.wso2.carbon.user.core.UserStoreClientException("error"), HttpStatus.SC_BAD_REQUEST},
53 | };
54 | }
55 |
56 | @Test(dataProvider = "dataProviderForResolveUserNameMandatory")
57 | public void testResolveHappyPath(Object userStoreException, int expected) {
58 |
59 | DefaultSCIMUserStoreErrorResolver defaultSCIMUserStoreErrorResolver = new DefaultSCIMUserStoreErrorResolver();
60 | SCIMUserStoreException scimUserStoreException = defaultSCIMUserStoreErrorResolver.
61 | resolve((UserStoreException) userStoreException);
62 | assertEquals(scimUserStoreException.getHttpStatusCode(), expected);
63 | }
64 |
65 | @DataProvider(name = "dataProviderForResolveUnHappyPath")
66 | public Object[][] dataProviderForResolveUnHappyPath() {
67 |
68 | return new Object[][]{
69 | {new UserStoreException("error: 30008")},
70 | {new org.wso2.carbon.user.core.UserStoreException("error", "32103")}
71 | };
72 | }
73 |
74 | @Test(dataProvider = "dataProviderForResolveUnHappyPath")
75 | public void testResolveUnHappyPath(Object userStoreException) {
76 |
77 | DefaultSCIMUserStoreErrorResolver defaultSCIMUserStoreErrorResolver = new DefaultSCIMUserStoreErrorResolver();
78 | SCIMUserStoreException scimUserStoreException = defaultSCIMUserStoreErrorResolver.
79 | resolve((UserStoreException) userStoreException);
80 | assertNull(scimUserStoreException);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/listener/SCIMTenantMgtListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.listener;
20 |
21 | import org.apache.commons.lang.StringUtils;
22 | import org.apache.commons.logging.Log;
23 | import org.apache.commons.logging.LogFactory;
24 | import org.wso2.carbon.identity.core.AbstractIdentityTenantMgtListener;
25 | import org.wso2.carbon.identity.organization.management.service.OrganizationManager;
26 | import org.wso2.carbon.identity.organization.management.service.exception.OrganizationManagementException;
27 | import org.wso2.carbon.identity.organization.management.service.util.Utils;
28 | import org.wso2.carbon.identity.scim2.common.internal.component.SCIMCommonComponentHolder;
29 | import org.wso2.carbon.identity.scim2.common.utils.AdminAttributeUtil;
30 | import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils;
31 | import org.wso2.carbon.stratos.common.exception.StratosException;
32 | import org.wso2.carbon.user.api.Tenant;
33 | import org.wso2.carbon.user.api.UserStoreException;
34 | import org.wso2.carbon.user.core.service.RealmService;
35 |
36 | /**
37 | * Tenant activation listener for SCIM component to do the task when the tenant get create.
38 | *
39 | */
40 | public class SCIMTenantMgtListener extends AbstractIdentityTenantMgtListener {
41 |
42 | private static final Log log = LogFactory.getLog(SCIMTenantMgtListener.class);
43 | @Override
44 | public void onTenantInitialActivation(int tenantId) throws StratosException {
45 |
46 | boolean isEnabled = isEnable();
47 | if (!isEnabled) {
48 | if (log.isDebugEnabled()) {
49 | log.debug("SCIMTenantMgtListener is disabled");
50 | }
51 | return;
52 | }
53 | RealmService realmService = SCIMCommonComponentHolder.getRealmService();
54 | try {
55 | Tenant tenant = realmService.getTenantManager().getTenant(tenantId);
56 | /*
57 | If the tenant has an associated organization id, and if the org id satisfies isOrganization() check, that
58 | organization creator is not inside the same organization. No need to update such admin claims.
59 | */
60 | String organizationID = tenant.getAssociatedOrganizationUUID();
61 | if (StringUtils.isNotBlank(organizationID)) {
62 | OrganizationManager organizationManager = SCIMCommonComponentHolder.getOrganizationManager();
63 | int organizationDepth = organizationManager.getOrganizationDepthInHierarchy(organizationID);
64 | if (organizationDepth >= Utils.getSubOrgStartLevel()) {
65 | return;
66 | }
67 | }
68 | if (log.isDebugEnabled()) {
69 | log.debug("SCIMTenantMgtListener is fired for Tenant ID : " + tenantId);
70 | }
71 | // Update admin user attributes.
72 | AdminAttributeUtil.updateAdminUser(tenantId, false);
73 | // Update admin group attributes.
74 | AdminAttributeUtil.updateAdminGroup(tenantId);
75 | // Update meta data of everyone role.
76 | SCIMCommonUtils.updateEveryOneRoleV2MetaData(tenantId);
77 | } catch (UserStoreException | OrganizationManagementException e) {
78 | log.error(e);
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/DAO/SQLQueries.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2025, WSO2 LLC. (https://www.wso2.com).
3 | *
4 | * WSO2 LLC. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.DAO;
20 |
21 | /**
22 | * SQL Queries for SCIM_IDENTITY_TABLE which persists SCIM_GROUP info.
23 | */
24 | public class SQLQueries {
25 |
26 | public static final String LIST_SCIM_GROUPS_SQL =
27 | "SELECT ROLE_NAME FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP.ATTR_NAME = ?";
28 | public static final String LIST_SCIM_GROUPS_BY_TENANT_ID_SQL =
29 | "SELECT ROLE_NAME FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP.TENANT_ID=? AND IDN_SCIM_GROUP.ATTR_NAME = ?";
30 | public static final String GET_ATTRIBUTES_SQL =
31 | "SELECT ATTR_NAME, ATTR_VALUE FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP.TENANT_ID=? AND " +
32 | "IDN_SCIM_GROUP.ROLE_NAME=?";
33 | public static final String GET_GROUP_ID_BY_NAME_SQL = "SELECT ATTR_VALUE FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP" +
34 | ".TENANT_ID=? AND IDN_SCIM_GROUP.ROLE_NAME=? AND IDN_SCIM_GROUP.ATTR_NAME=?";
35 | public static final String GET_GROUP_NAME_BY_ID_SQL =
36 | "SELECT ROLE_NAME FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP.TENANT_ID=? AND " +
37 | "IDN_SCIM_GROUP.ATTR_VALUE=? AND IDN_SCIM_GROUP.ATTR_NAME=?";
38 | public static final String ADD_ATTRIBUTES_SQL =
39 | "INSERT INTO IDN_SCIM_GROUP (TENANT_ID, ROLE_NAME, ATTR_NAME, ATTR_VALUE) VALUES (?, ?, ?, ?)";
40 | public static final String ADD_ATTRIBUTES_WITH_AUDIENCE_SQL =
41 | "INSERT INTO IDN_SCIM_GROUP (TENANT_ID, ROLE_NAME, AUDIENCE_REF_ID, ATTR_NAME, ATTR_VALUE) VALUES " +
42 | "(?, ?, ?, ?, ?)";
43 | public static final String CHECK_EXISTING_ATTRIBUTE_WITH_AUDIENCE_SQL =
44 | "SELECT TENANT_ID, ROLE_NAME, ATTR_NAME FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP.TENANT_ID=? AND " +
45 | "IDN_SCIM_GROUP.ROLE_NAME=? AND IDN_SCIM_GROUP.ATTR_NAME=? AND IDN_SCIM_GROUP.AUDIENCE_REF_ID=?";
46 | public static final String UPDATE_ATTRIBUTES_SQL =
47 | "UPDATE IDN_SCIM_GROUP SET ATTR_VALUE=? WHERE TENANT_ID=? AND ROLE_NAME=? AND ATTR_NAME=?";
48 | public static final String UPDATE_GROUP_NAME_SQL =
49 | "UPDATE IDN_SCIM_GROUP SET ROLE_NAME=? WHERE TENANT_ID=? AND ROLE_NAME=?";
50 | public static final String DELETE_GROUP_SQL =
51 | "DELETE FROM IDN_SCIM_GROUP WHERE TENANT_ID=? AND ROLE_NAME=?";
52 | public static final String CHECK_EXISTING_ATTRIBUTE_SQL =
53 | "SELECT TENANT_ID, ROLE_NAME, ATTR_NAME FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP.TENANT_ID=? AND " +
54 | "IDN_SCIM_GROUP.ROLE_NAME=? AND IDN_SCIM_GROUP.ATTR_NAME=?";
55 | public static final String LIST_SCIM_GROUPS_SQL_BY_ATT_AND_ATT_VALUE =
56 | "SELECT ROLE_NAME FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP.TENANT_ID=? AND " +
57 | "IDN_SCIM_GROUP.ATTR_NAME=? AND ATTR_VALUE LIKE ?";
58 | public static final String LIST_SCIM_GROUPS_SQL_BY_ATT_AND_ATT_VALUE_AND_ROLE_NAME =
59 | "SELECT ROLE_NAME FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP.TENANT_ID=? AND "
60 | + "IDN_SCIM_GROUP.ATTR_NAME=? AND ATTR_VALUE LIKE ? AND IDN_SCIM_GROUP.ROLE_NAME LIKE ?";
61 | public static final String LIST_SCIM_GROUPS_SQL_BY_ROLE_NAME =
62 | "SELECT DISTINCT ROLE_NAME FROM IDN_SCIM_GROUP WHERE IDN_SCIM_GROUP.TENANT_ID = ? AND "
63 | + "IDN_SCIM_GROUP.ROLE_NAME LIKE ?";
64 | private SQLQueries(){}
65 | }
66 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/cache/SCIMAgentAttributeSchemaCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, WSO2 LLC. (https://www.wso2.com).
3 | *
4 | * WSO2 LLC. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.cache;
20 |
21 | import org.apache.commons.logging.Log;
22 | import org.apache.commons.logging.LogFactory;
23 | import org.wso2.carbon.identity.application.common.cache.BaseCache;
24 | import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils;
25 | import org.wso2.charon3.core.schema.AttributeSchema;
26 |
27 | import java.util.List;
28 |
29 | /**
30 | * This stores agent AttributeSchema against tenants.
31 | */
32 | public class SCIMAgentAttributeSchemaCache
33 | extends BaseCache {
34 |
35 | private static final String SCIM_AGENT_SCHEMA_CACHE = "SCIMAgentAttributeSchemaCache";
36 | private static final Log LOG = LogFactory.getLog(SCIMAgentAttributeSchemaCache.class);
37 |
38 | private static volatile SCIMAgentAttributeSchemaCache instance;
39 |
40 | private SCIMAgentAttributeSchemaCache() {
41 |
42 | super(SCIM_AGENT_SCHEMA_CACHE);
43 | }
44 |
45 | public static SCIMAgentAttributeSchemaCache getInstance() {
46 |
47 | if (instance == null) {
48 | synchronized (SCIMAgentAttributeSchemaCache.class) {
49 | if (instance == null) {
50 | instance = new SCIMAgentAttributeSchemaCache();
51 | }
52 | }
53 | }
54 | return instance;
55 | }
56 |
57 | /**
58 | * Add agent attribute schema to cache against tenantId.
59 | *
60 | * @param tenantId TenantId.
61 | * @param agentAttributeSchema AgentAttributeSchema.
62 | */
63 | public void addSCIMAgentAttributeSchema(int tenantId, AttributeSchema agentAttributeSchema) {
64 |
65 | SCIMAgentAttributeSchemaCacheKey cacheKey = new SCIMAgentAttributeSchemaCacheKey(tenantId);
66 | SCIMAgentAttributeSchemaCacheEntry cacheEntry = new SCIMAgentAttributeSchemaCacheEntry(agentAttributeSchema);
67 | super.addToCache(cacheKey, cacheEntry);
68 | if (LOG.isDebugEnabled()) {
69 | LOG.debug("Successfully added scim agent attributes into SCIMAgentSchemaCache for the tenant:"
70 | + tenantId);
71 | }
72 | }
73 |
74 | /**
75 | * Get SCIM2 Agent AttributeSchema by tenantId.
76 | *
77 | * @param tenantId TenantId.
78 | * @return AttributeSchema.
79 | */
80 | public AttributeSchema getSCIMAgentAttributeSchemaByTenant(int tenantId) {
81 |
82 | SCIMAgentAttributeSchemaCacheKey cacheKey = new SCIMAgentAttributeSchemaCacheKey(tenantId);
83 | SCIMAgentAttributeSchemaCacheEntry cacheEntry = super.getValueFromCache(cacheKey);
84 | if (cacheEntry != null) {
85 | return cacheEntry.getSCIMAgentAttributeSchema();
86 | } else {
87 | if (LOG.isDebugEnabled()) {
88 | LOG.debug("Cache entry is null for tenantId: " + tenantId);
89 | }
90 | return null;
91 | }
92 | }
93 |
94 | /**
95 | * Clear SCIM2 Agent AttributeSchema by tenantId.
96 | *
97 | * For v0 organizations, this clears the cache of the current organization only.
98 | * For v1 organizations, this clears the caches of the current organization and its child organizations.
99 | *
100 | * @param tenantId TenantId.
101 | */
102 | public void clearSCIMAgentAttributeSchemaByTenant(int tenantId) {
103 |
104 | List tenantIdsToBeInvalidated = SCIMCommonUtils.getOrganizationsToInvalidateCaches(tenantId);
105 | for (Integer tenantIdToBeInvalidated : tenantIdsToBeInvalidated) {
106 | if (LOG.isDebugEnabled()) {
107 | LOG.debug("Clearing SCIMAgentAttributeSchemaCache entry by the tenant with id: " +
108 | tenantIdToBeInvalidated);
109 | }
110 | SCIMAgentAttributeSchemaCacheKey cacheKey = new SCIMAgentAttributeSchemaCacheKey(tenantIdToBeInvalidated);
111 | super.clearCacheEntry(cacheKey);
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/cache/SCIMCustomAttributeSchemaCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.cache;
20 |
21 | import org.apache.commons.logging.Log;
22 | import org.apache.commons.logging.LogFactory;
23 | import org.wso2.carbon.identity.application.common.cache.BaseCache;
24 | import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils;
25 | import org.wso2.charon3.core.schema.AttributeSchema;
26 |
27 | import java.util.List;
28 |
29 | /**
30 | * This stores custom AttributeSchema against tenants.
31 | */
32 | public class SCIMCustomAttributeSchemaCache extends BaseCache {
33 |
34 | private static final String SCIM_CUSTOM_SCHEMA_CACHE = "SCIMCustomAttributeSchemaCache";
35 | private static final Log log = LogFactory.getLog(SCIMCustomAttributeSchemaCache.class);
36 |
37 | private static volatile SCIMCustomAttributeSchemaCache instance;
38 |
39 | private SCIMCustomAttributeSchemaCache() {
40 |
41 | super(SCIM_CUSTOM_SCHEMA_CACHE);
42 | }
43 |
44 | public static SCIMCustomAttributeSchemaCache getInstance() {
45 |
46 | if (instance == null) {
47 | synchronized (SCIMCustomAttributeSchemaCache.class) {
48 | if (instance == null) {
49 | instance = new SCIMCustomAttributeSchemaCache();
50 | }
51 | }
52 | }
53 | return instance;
54 | }
55 |
56 | /**
57 | * Add custom attribute schema to cache against tenantId.
58 | *
59 | * @param tenantId TenantId.
60 | * @param customAttributeSchema CustomAttributeSchema.
61 | */
62 | public void addSCIMCustomAttributeSchema(int tenantId, AttributeSchema customAttributeSchema){
63 |
64 | SCIMCustomAttributeSchemaCacheKey cacheKey = new SCIMCustomAttributeSchemaCacheKey(tenantId);
65 | SCIMCustomAttributeSchemaCacheEntry cacheEntry = new SCIMCustomAttributeSchemaCacheEntry(customAttributeSchema);
66 | super.addToCache(cacheKey, cacheEntry);
67 | if (log.isDebugEnabled()) {
68 | log.debug("Successfully added scim custom attributes into SCIMCustomSchemaCache for the tenant:"
69 | + tenantId);
70 | }
71 |
72 | }
73 |
74 |
75 | /**
76 | * Get SCIM2 Custom AttributeSchema by tenantId.
77 | *
78 | * @param tenantId TenantId.
79 | * @return AttributeSchema.
80 | */
81 | public AttributeSchema getSCIMCustomAttributeSchemaByTenant(int tenantId) {
82 |
83 | SCIMCustomAttributeSchemaCacheKey cacheKey = new SCIMCustomAttributeSchemaCacheKey(tenantId);
84 | SCIMCustomAttributeSchemaCacheEntry cacheEntry = super.getValueFromCache(cacheKey);
85 | if (cacheEntry != null) {
86 | return cacheEntry.getSCIMCustomAttributeSchema();
87 | } else {
88 | if (log.isDebugEnabled()) {
89 | log.debug("Cache entry is null for tenantId: " + tenantId);
90 | }
91 | return null;
92 | }
93 | }
94 |
95 | /**
96 | * Clear SCIM2 Custom AttributeSchema by tenantId.
97 | *
98 | * For v0 organizations, this clears the cache of the current organization only.
99 | * For v1 organizations, this clears the caches of the current organization and its child organizations.
100 | *
101 | * @param tenantId TenantId.
102 | */
103 | public void clearSCIMCustomAttributeSchemaByTenant(int tenantId) {
104 |
105 | List tenantIdsToBeInvalidated = SCIMCommonUtils.getOrganizationsToInvalidateCaches(tenantId);
106 | for (Integer tenantIdToBeInvalidated : tenantIdsToBeInvalidated) {
107 | if (log.isDebugEnabled()) {
108 | log.debug("Clearing SCIMCustomAttributeSchemaCache entry by the tenant with id: " +
109 | tenantIdToBeInvalidated);
110 | }
111 | SCIMCustomAttributeSchemaCacheKey cacheKey = new SCIMCustomAttributeSchemaCacheKey(tenantIdToBeInvalidated);
112 | super.clearCacheEntry(cacheKey);
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/main/java/org/wso2/carbon/identity/scim2/common/cache/SCIMSystemAttributeSchemaCache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.cache;
20 |
21 | import org.apache.commons.logging.Log;
22 | import org.apache.commons.logging.LogFactory;
23 | import org.wso2.carbon.identity.application.common.cache.BaseCache;
24 | import org.wso2.carbon.identity.scim2.common.utils.SCIMCommonUtils;
25 | import org.wso2.charon3.core.schema.AttributeSchema;
26 |
27 | import java.util.List;
28 |
29 | /**
30 | * This stores system AttributeSchema against tenants.
31 | */
32 | public class SCIMSystemAttributeSchemaCache
33 | extends BaseCache {
34 |
35 | private static final String SCIM_SYSTEM_SCHEMA_CACHE = "SCIMSystemAttributeSchemaCache";
36 | private static final Log log = LogFactory.getLog(SCIMSystemAttributeSchemaCache.class);
37 |
38 | private static volatile SCIMSystemAttributeSchemaCache instance;
39 |
40 | private SCIMSystemAttributeSchemaCache() {
41 |
42 | super(SCIM_SYSTEM_SCHEMA_CACHE);
43 | }
44 |
45 | public static SCIMSystemAttributeSchemaCache getInstance() {
46 |
47 | if (instance == null) {
48 | synchronized (SCIMSystemAttributeSchemaCache.class) {
49 | if (instance == null) {
50 | instance = new SCIMSystemAttributeSchemaCache();
51 | }
52 | }
53 | }
54 | return instance;
55 | }
56 |
57 | /**
58 | * Add system attribute schema to cache against tenantId.
59 | *
60 | * @param tenantId TenantId.
61 | * @param systemAttributeSchema SystemAttributeSchema.
62 | */
63 | public void addSCIMSystemAttributeSchema(int tenantId, AttributeSchema systemAttributeSchema){
64 |
65 | SCIMSystemAttributeSchemaCacheKey cacheKey = new SCIMSystemAttributeSchemaCacheKey(tenantId);
66 | SCIMSystemAttributeSchemaCacheEntry cacheEntry = new SCIMSystemAttributeSchemaCacheEntry(systemAttributeSchema);
67 | super.addToCache(cacheKey, cacheEntry);
68 | if (log.isDebugEnabled()) {
69 | log.debug("Successfully added scim system attributes into SCIMSystemSchemaCache for the tenant:"
70 | + tenantId);
71 | }
72 |
73 | }
74 |
75 |
76 | /**
77 | * Get SCIM2 System AttributeSchema by tenantId.
78 | *
79 | * @param tenantId TenantId.
80 | * @return AttributeSchema.
81 | */
82 | public AttributeSchema getSCIMSystemAttributeSchemaByTenant(int tenantId) {
83 |
84 | SCIMSystemAttributeSchemaCacheKey cacheKey = new SCIMSystemAttributeSchemaCacheKey(tenantId);
85 | SCIMSystemAttributeSchemaCacheEntry cacheEntry = super.getValueFromCache(cacheKey);
86 | if (cacheEntry != null) {
87 | return cacheEntry.getSCIMSystemAttributeSchema();
88 | } else {
89 | if (log.isDebugEnabled()) {
90 | log.debug("Cache entry is null for tenantId: " + tenantId);
91 | }
92 | return null;
93 | }
94 | }
95 |
96 | /**
97 | * Clear SCIM2 System AttributeSchema by tenantId.
98 | *
99 | * For v0 organizations, this clears the cache of the current organization only.
100 | * For v1 organizations, this clears the caches of the current organization and its child organizations.
101 | *
102 | * @param tenantId TenantId.
103 | */
104 | public void clearSCIMSystemAttributeSchemaByTenant(int tenantId) {
105 |
106 | List tenantIdsToBeInvalidated = SCIMCommonUtils.getOrganizationsToInvalidateCaches(tenantId);
107 | for (Integer tenantIdToBeInvalidated : tenantIdsToBeInvalidated) {
108 | if (log.isDebugEnabled()) {
109 | log.debug("Clearing SCIMSystemAttributeSchemaCache entry by the tenant with id: " +
110 | tenantIdToBeInvalidated);
111 | }
112 | SCIMSystemAttributeSchemaCacheKey cacheKey = new SCIMSystemAttributeSchemaCacheKey(tenantIdToBeInvalidated);
113 | super.clearCacheEntry(cacheKey);
114 | }
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/utils/AuthenticationSchemaTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017, WSO2 LLC. (http://www.wso2.org)
3 | *
4 | * WSO2 Inc. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.utils;
20 |
21 | import org.testng.annotations.AfterMethod;
22 | import org.testng.annotations.BeforeMethod;
23 | import org.testng.annotations.Test;
24 |
25 | import java.util.HashMap;
26 | import java.util.Map;
27 |
28 | import static org.testng.Assert.assertEquals;
29 |
30 | public class AuthenticationSchemaTest {
31 |
32 | private String dummyName = "dummyName";
33 | private String dummyDescription = "dummyDescription";
34 | private String dummySpecUri = "dummySpecUri";
35 | private String dummyDocumentationUri = "dummyDocumentationUri";
36 | private String dummyType = "dummyType";
37 | private String dummyPrimary = "dummyPrimary";
38 | private AuthenticationSchema authenticationSchema;
39 |
40 | @BeforeMethod
41 | public void setUp() throws Exception {
42 | authenticationSchema = new AuthenticationSchema();
43 | Map properties = new HashMap<>();
44 | properties.put("name", dummyName);
45 | properties.put("description", dummyDescription);
46 | properties.put("specUri", dummySpecUri);
47 | properties.put("documentationUri", dummyDocumentationUri);
48 | properties.put("type", dummyType);
49 | properties.put("primary", dummyPrimary);
50 | authenticationSchema.setProperties(properties);
51 | }
52 |
53 | @AfterMethod
54 | public void tearDown() throws Exception {
55 |
56 | }
57 |
58 | @Test
59 | public void testGetName() throws Exception {
60 | assertEquals(authenticationSchema.getName(), dummyName);
61 | }
62 |
63 | @Test
64 | public void testSetName() throws Exception {
65 | dummyName = "dummyName2";
66 | authenticationSchema.setName(dummyName);
67 | assertEquals(authenticationSchema.getName(), dummyName);
68 | }
69 |
70 | @Test
71 | public void testGetDescription() throws Exception {
72 | assertEquals(authenticationSchema.getDescription(), dummyDescription);
73 | }
74 |
75 | @Test
76 | public void testSetDescription() throws Exception {
77 | dummyDescription = "dummyDescription2";
78 | authenticationSchema.setDescription(dummyDescription);
79 | assertEquals(authenticationSchema.getDescription(), dummyDescription);
80 | }
81 |
82 | @Test
83 | public void testGetSpecUri() throws Exception {
84 | assertEquals(authenticationSchema.getSpecUri(), dummySpecUri);
85 | }
86 |
87 | @Test
88 | public void testSetSpecUri() throws Exception {
89 | dummySpecUri = "dummySpecUri2";
90 | authenticationSchema.setSpecUri(dummySpecUri);
91 | assertEquals(authenticationSchema.getSpecUri(), dummySpecUri);
92 | }
93 |
94 | @Test
95 | public void testGetDocumentationUri() throws Exception {
96 | assertEquals(authenticationSchema.getDocumentationUri(), dummyDocumentationUri);
97 | }
98 |
99 | @Test
100 | public void testSetDocumentationUri() throws Exception {
101 | dummyDocumentationUri = "dummyDocumentationUri2";
102 | authenticationSchema.setDocumentationUri(dummyDocumentationUri);
103 | assertEquals(authenticationSchema.getDocumentationUri(), dummyDocumentationUri);
104 | }
105 |
106 | @Test
107 | public void testGetType() throws Exception {
108 | assertEquals(authenticationSchema.getType(), dummyType);
109 | }
110 |
111 | @Test
112 | public void testSetType() throws Exception {
113 | dummyType = "dummyType2";
114 | authenticationSchema.setType(dummyType);
115 | assertEquals(authenticationSchema.getType(), dummyType);
116 | }
117 |
118 | @Test
119 | public void testGetPrimary() throws Exception {
120 | assertEquals(authenticationSchema.getPrimary(), dummyPrimary);
121 | }
122 |
123 | @Test
124 | public void testSetPrimary() throws Exception {
125 | dummyPrimary = "dummyPrimary2";
126 | authenticationSchema.setPrimary(dummyPrimary);
127 | assertEquals(authenticationSchema.getPrimary(), dummyPrimary);
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/test/constants/TestConstants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2025, WSO2 LLC. (http://www.wso2.com).
3 | *
4 | * WSO2 LLC. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.test.constants;
20 |
21 | import java.util.Arrays;
22 | import java.util.List;
23 |
24 | /**
25 | * Constants used in the test classes.
26 | */
27 | public class TestConstants {
28 |
29 | public static final String TEST_USER_ID = "testUserId";
30 | public static final String TEST_USER_USERNAME = "testUser";
31 |
32 | public enum Claims {
33 | NEW_SINGLEVALUE_CLAIM1("http://wso2.org/claims/claim1", false, "value11", "value11", null),
34 | UPDATING_SINGLEVALUE_CLAIM2("http://wso2.org/claims/claim2", false, "value21", "value21", "value20"),
35 | UPDATING_MULTI_ATTRIBUTE_SEPARATOR_INCLUDED_SINGLEVALUE_CLAIM3("http://wso2.org/claims/claim3", false,
36 | "value31,value32,value33", "value31,value32,value33", "value30,value31"),
37 | DELETING_SINGLEVALUE_CLAIM4("http://wso2.org/claims/claim4", false, "value41", "", "value41"),
38 | DELETING_MULTI_ATTRIBUTE_SEPARATOR_INCLUDED_SINGLEVALUE_CLAIM5("http://wso2.org/claims/claim5", false,
39 | "value51,value52", "", "value51,value52"),
40 | NEW_MULTIVALUE_INPUT_VALUE_AS_STRING_LIST_CLAIM6("http://wso2.org/claims/claim6", true,
41 | Arrays.asList("value61", "value62", "value63"),
42 | new String[]{"value61", "value62", "value63"}, null),
43 | NEW_MULTIVALUE_INPUT_VALUE_AS_STRING_CLAIM6("http://wso2.org/claims/claim6", true, "value61,value62,value63",
44 | new String[]{"value61", "value62", "value63"}, null),
45 | UPDATING_MULTIVALUE_INPUT_VALUE_AS_STRING_LIST_CLAIM7("http://wso2.org/claims/claim7", true,
46 | Arrays.asList("value71", "value72"),
47 | new String[]{"value70", "value73", "value71", "value72"}, "value70,value73"),
48 | UPDATING_MULTIVALUE_INPUT_VALUE_AS_STRING_CLAIM7("http://wso2.org/claims/claim7", true, "value71,value72",
49 | new String[]{"value71", "value72"}, "value70,value73"),
50 | DELETING_MULTIVALUE_INPUT_VALUE_AS_STRING_LIST_CLAIM8("http://wso2.org/claims/claim8", true,
51 | Arrays.asList("value81", "value82"),
52 | new String[]{"value80"}, "value81,value80,value82"),
53 | DELETING_MULTIVALUE_INPUT_VALUE_AS_STRING_CLAIM8("http://wso2.org/claims/claim8", true,
54 | "value81,value80",
55 | new String[]{}, "value81,value80,value82"),
56 | FLOW_INITIATOR_SINGLEVALUE_IDENTITY_CLAIM1("http://wso2.org/claims/identity/adminForcedPasswordReset", false, "true", "false", null);
57 |
58 | private String claimURI;
59 | private boolean isMultiValued;
60 | private Object inputValue;
61 | private Object expectedValueInDTO;
62 | private String existingValueInUser;
63 |
64 | Claims(String claimURI, boolean isMultiValued, Object inputValue, Object expectedValueInDTO,
65 | String existingValueInUser) {
66 |
67 | this.claimURI = claimURI;
68 | this.isMultiValued = isMultiValued;
69 | this.inputValue = inputValue;
70 | this.expectedValueInDTO = expectedValueInDTO;
71 | this.existingValueInUser = existingValueInUser;
72 | }
73 |
74 | public String getClaimURI() {
75 |
76 | return claimURI;
77 | }
78 |
79 | public boolean isMultiValued() {
80 |
81 | return isMultiValued;
82 | }
83 |
84 | public String getInputValueAsString() {
85 |
86 | return String.valueOf(inputValue);
87 | }
88 |
89 | public List getInputValueAsStringList() {
90 |
91 | return (List) inputValue;
92 | }
93 |
94 | public String getExpectedValueInDTOAsString() {
95 |
96 | return String.valueOf(expectedValueInDTO);
97 | }
98 |
99 | public String[] getExpectedValueInDTOAsStringArray() {
100 |
101 | return (String[]) expectedValueInDTO;
102 | }
103 |
104 | public String getExistingValueInUser() {
105 |
106 | return existingValueInUser;
107 | }
108 | }
109 |
110 | private TestConstants() {
111 |
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/components/org.wso2.carbon.identity.scim2.common/src/test/java/org/wso2/carbon/identity/scim2/common/utils/AdminAttributeUtilTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2017-2024, WSO2 LLC. (http://www.wso2.com).
3 | *
4 | * WSO2 LLC. licenses this file to you under the Apache License,
5 | * Version 2.0 (the "License"); you may not use this file except
6 | * in compliance with the License.
7 | * You may obtain a copy of the License at
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing,
12 | * software distributed under the License is distributed on an
13 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | * KIND, either express or implied. See the License for the
15 | * specific language governing permissions and limitations
16 | * under the License.
17 | */
18 |
19 | package org.wso2.carbon.identity.scim2.common.utils;
20 |
21 | import org.mockito.ArgumentCaptor;
22 | import org.mockito.Mock;
23 | import org.mockito.MockedStatic;
24 | import org.testng.annotations.AfterMethod;
25 | import org.testng.annotations.BeforeMethod;
26 | import org.testng.annotations.DataProvider;
27 | import org.testng.annotations.Test;
28 | import org.wso2.carbon.identity.core.util.IdentityTenantUtil;
29 | import org.wso2.carbon.identity.scim2.common.internal.component.SCIMCommonComponentHolder;
30 | import org.wso2.carbon.stratos.common.util.ClaimsMgtUtil;
31 | import org.wso2.carbon.user.api.UserRealm;
32 | import org.wso2.carbon.user.api.UserStoreException;
33 | import org.wso2.carbon.user.core.UserStoreManager;
34 | import org.wso2.carbon.user.core.service.RealmService;
35 |
36 | import java.util.Map;
37 |
38 | import static org.mockito.ArgumentMatchers.anyInt;
39 | import static org.mockito.ArgumentMatchers.anyString;
40 | import static org.mockito.ArgumentMatchers.eq;
41 | import static org.mockito.Mockito.mockStatic;
42 | import static org.mockito.Mockito.verify;
43 | import static org.mockito.Mockito.when;
44 | import static org.mockito.MockitoAnnotations.initMocks;
45 |
46 | public class AdminAttributeUtilTest {
47 |
48 | @Mock
49 | RealmService realmService;
50 |
51 | @Mock
52 | UserRealm userRealm;
53 |
54 | @Mock
55 | UserStoreManager userStoreManager;
56 |
57 | AdminAttributeUtil adminAttributeUtil;
58 |
59 | private MockedStatic scimCommonComponentHolder;
60 | private MockedStatic claimsMgtUtil;
61 | private MockedStatic identityTenantUtil;
62 |
63 | @BeforeMethod
64 | public void setUp() throws Exception {
65 | initMocks(this);
66 | adminAttributeUtil = new AdminAttributeUtil();
67 | scimCommonComponentHolder = mockStatic(SCIMCommonComponentHolder.class);
68 | claimsMgtUtil = mockStatic(ClaimsMgtUtil.class);
69 | identityTenantUtil = mockStatic(IdentityTenantUtil.class);
70 | }
71 |
72 | @AfterMethod
73 | public void tearDown() throws Exception {
74 | scimCommonComponentHolder.close();
75 | claimsMgtUtil.close();
76 | identityTenantUtil.close();
77 | }
78 |
79 | @DataProvider(name = "testUpdateAdminUserData")
80 | public Object[][] testUpdateAdminUserData() {
81 | return new Object[][]{
82 | {true},
83 | {false}
84 | };
85 | }
86 |
87 | @Test(dataProvider = "testUpdateAdminUserData")
88 | public void testUpdateAdminUser(boolean validateSCIMID) throws Exception {
89 | String adminUsername = "admin";
90 |
91 | scimCommonComponentHolder.when(() -> SCIMCommonComponentHolder.getRealmService()).thenReturn(realmService);
92 | when(realmService.getTenantUserRealm(anyInt())).thenReturn(userRealm);
93 | when(userRealm.getUserStoreManager()).thenReturn(userStoreManager);
94 | when(userStoreManager.isSCIMEnabled()).thenReturn(true);
95 | claimsMgtUtil.when(() -> ClaimsMgtUtil.getAdminUserNameFromTenantId(eq(realmService), anyInt())).thenReturn(adminUsername);
96 | identityTenantUtil.when(() -> IdentityTenantUtil.getRealmService()).thenReturn(realmService);
97 | when(userStoreManager.getUserClaimValue(anyString(), anyString(), anyString())).thenReturn("");
98 |
99 | ArgumentCaptor