From 5e4ef6979deac7a9aeed4630524826f0b7a27cd6 Mon Sep 17 00:00:00 2001 From: nipunaupeksha Date: Thu, 13 Jan 2022 10:32:50 +0530 Subject: [PATCH 1/5] mandatory organization-user-role mappings when creating a new organization. --- .../OrganizationManagementConstants.java | 4 +- .../service/constant/SQLConstants.java | 30 +++++ .../impl/OrganizationManagementDAOImpl.java | 105 ++++++++++++++++-- .../management/service/util/Utils.java | 7 ++ 4 files changed, 133 insertions(+), 13 deletions(-) diff --git a/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/constant/OrganizationManagementConstants.java b/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/constant/OrganizationManagementConstants.java index edb485e..8b9d5d7 100644 --- a/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/constant/OrganizationManagementConstants.java +++ b/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/constant/OrganizationManagementConstants.java @@ -136,7 +136,9 @@ public enum ErrorMessages { ERROR_CODE_ERROR_BUILDING_RESPONSE_HEADER_URL("65017", "Unable to build created organization URL.", "Server encountered an error while building URL for response header."), ERROR_CODE_ERROR_BUILDING_URL_FOR_RESPONSE_BODY("65018", "Unable to build the URL.", - "Server encountered an error while building URL for response body."); + "Server encountered an error while building URL for response body."), + ERROR_CODE_ERROR_ADDING_ORGANIZATION_ROLE_MAPPING("65019", "Unable to create organization-user-role mappings", + "Server encountered an error while creating user role mappings."); private final String code; private final String message; diff --git a/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/constant/SQLConstants.java b/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/constant/SQLConstants.java index 9ea302b..b3d4798 100644 --- a/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/constant/SQLConstants.java +++ b/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/constant/SQLConstants.java @@ -99,8 +99,32 @@ public class SQLConstants { SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_PARENT_ID + "; AND UM_TENANT_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + ";"; + public static final String GET_ALL_MANDATORY_ORGANIZATION_USER_ROLE_MAPPINGS = "SELECT * FROM UM_USER_ROLE_ORG" + + " WHERE ORG_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_PARENT_ID + + "; AND UM_TENANT_ID = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + + "; AND MANDATORY = :" + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_MANDATORY + ";"; + + public static final String ADD_MANDATORY_ORGANIZATION_USER_ROLE_MAPPINGS = "INSERT INTO UM_USER_ROLE_ORG (UM_ID, " + + "UM_USER_ID, UM_ROLE_ID," + + "UM_HYBRID_ROLE_ID, UM_TENANT_ID, ORG_ID, ASSIGNED_AT, MANDATORY) VALUES "; + public static final String ADD_MANDATORY_ORGANIZATION_USER_ROLE_MAPPINGS_MAPPING = "(:" + + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ID + "%1$d;,:" + + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_USER_ID + "%1$d;,:" + + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID + "%1$d;,:" + + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_HYBRID_ROLE_ID + "%1$d;,:" + + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID + "%1$d;,:" + + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ORG_ID + "%1$d;,:" + + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ASSIGNED_AT + "%1$d;,:" + + SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_MANDATORY + "%1$d;)"; + public static final String COUNT_COLUMN = "COUNT(1)"; + public static final String VIEW_ID_COLUMN = "UM_ID"; + public static final String VIEW_USER_ID_COLUMN = "UM_USER_ID"; + public static final String VIEW_ROLE_ID_COLUMN = "UM_ROLE_ID"; + public static final String VIEW_HYBRID_ROLE_ID_COLUMN = "UM_HYBRID_ROLE_ID"; + public static final String VIEW_ASSIGNED_AT_COLUMN = "ASSIGNED_AT"; + public static final String VIEW_MANDATORY_COLUMN = "MANDATORY"; /** * SQL Placeholders @@ -116,5 +140,11 @@ public static final class SQLPlaceholders { public static final String DB_SCHEMA_COLUMN_NAME_PARENT_ID = "PARENT_ID"; public static final String DB_SCHEMA_COLUMN_NAME_KEY = "KEY"; public static final String DB_SCHEMA_COLUMN_NAME_VALUE = "VALUE"; + public static final String DB_SCHEMA_COLUMN_NAME_MANDATORY = "MANDATORY"; + public static final String DB_SCHEMA_COLUMN_NAME_USER_ID = "USER_ID"; + public static final String DB_SCHEMA_COLUMN_NAME_HYBRID_ROLE_ID = "HYBRID_ROLE_ID"; + public static final String DB_SCHEMA_COLUMN_NAME_ROLE_ID = "ROLE_ID"; + public static final String DB_SCHEMA_COLUMN_NAME_ORG_ID = "ORG_ID"; + public static final String DB_SCHEMA_COLUMN_NAME_ASSIGNED_AT = "ASSIGNED_AT"; } } diff --git a/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/dao/impl/OrganizationManagementDAOImpl.java b/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/dao/impl/OrganizationManagementDAOImpl.java index 0f29203..79de062 100644 --- a/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/dao/impl/OrganizationManagementDAOImpl.java +++ b/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/dao/impl/OrganizationManagementDAOImpl.java @@ -30,6 +30,7 @@ import org.wso2.carbon.identity.organization.management.service.model.Operation; import org.wso2.carbon.identity.organization.management.service.model.Organization; import org.wso2.carbon.identity.organization.management.service.model.OrganizationAttribute; +import org.wso2.carbon.identity.organization.management.service.model.OrganizationUserRoleMapping; import org.wso2.carbon.identity.organization.management.service.util.Utils; import java.sql.Timestamp; @@ -41,6 +42,7 @@ import static java.time.ZoneOffset.UTC; import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_ERROR_ADDING_ORGANIZATION; +import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_ERROR_ADDING_ORGANIZATION_ROLE_MAPPING; import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_ERROR_CHECKING_ORGANIZATION_ATTRIBUTE_KEY_EXIST; import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_ERROR_CHECKING_ORGANIZATION_EXIST_BY_ID; import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.ErrorMessages.ERROR_CODE_ERROR_CHECKING_ORGANIZATION_EXIST_BY_NAME; @@ -68,6 +70,8 @@ import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.VIEW_LAST_MODIFIED_COLUMN; import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.VIEW_NAME_COLUMN; import static org.wso2.carbon.identity.organization.management.service.constant.OrganizationManagementConstants.VIEW_PARENT_ID_COLUMN; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.ADD_MANDATORY_ORGANIZATION_USER_ROLE_MAPPINGS; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.ADD_MANDATORY_ORGANIZATION_USER_ROLE_MAPPINGS_MAPPING; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.CHECK_CHILD_ORGANIZATIONS_EXIST; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.CHECK_ORGANIZATION_ATTRIBUTE_KEY_EXIST; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.CHECK_ORGANIZATION_EXIST_BY_ID; @@ -76,6 +80,7 @@ import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.DELETE_ORGANIZATION_ATTRIBUTE; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.DELETE_ORGANIZATION_ATTRIBUTES_BY_ID; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.DELETE_ORGANIZATION_BY_ID; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.GET_ALL_MANDATORY_ORGANIZATION_USER_ROLE_MAPPINGS; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.GET_CHILD_ORGANIZATIONS; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.GET_ORGANIZATIONS_BY_TENANT_ID; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.GET_ORGANIZATION_BY_ID; @@ -84,19 +89,30 @@ import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.INSERT_ORGANIZATION; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.PATCH_ORGANIZATION; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.PATCH_ORGANIZATION_CONCLUDE; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ASSIGNED_AT; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_CREATED_TIME; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_DESCRIPTION; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_HYBRID_ROLE_ID; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ID; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_KEY; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_LAST_MODIFIED; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_MANDATORY; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_NAME; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ORG_ID; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_PARENT_ID; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_ROLE_ID; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_TENANT_ID; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_USER_ID; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.SQLPlaceholders.DB_SCHEMA_COLUMN_NAME_VALUE; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.UPDATE_ORGANIZATION; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.UPDATE_ORGANIZATION_ATTRIBUTE_VALUE; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.UPDATE_ORGANIZATION_LAST_MODIFIED; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.VIEW_ASSIGNED_AT_COLUMN; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.VIEW_HYBRID_ROLE_ID_COLUMN; import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.VIEW_ID_COLUMN; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.VIEW_MANDATORY_COLUMN; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.VIEW_ROLE_ID_COLUMN; +import static org.wso2.carbon.identity.organization.management.service.constant.SQLConstants.VIEW_USER_ID_COLUMN; import static org.wso2.carbon.identity.organization.management.service.util.Utils.handleServerException; /** @@ -114,7 +130,7 @@ public void addOrganization(int tenantId, String tenantDomain, Organization orga NamedJdbcTemplate namedJdbcTemplate = Utils.getNewTemplate(); try { namedJdbcTemplate.withTransaction(template -> { - namedJdbcTemplate.executeInsert(INSERT_ORGANIZATION, namedPreparedStatement -> { + template.executeInsert(INSERT_ORGANIZATION, namedPreparedStatement -> { namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ID, organization.getId()); namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_NAME, organization.getName()); namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_DESCRIPTION, organization.getDescription()); @@ -130,26 +146,79 @@ public void addOrganization(int tenantId, String tenantDomain, Organization orga } return null; }); + //after adding organization we can add the mandatory roles coming from parent. + insertOrganizationUserRoleMappingsForMandatoryRoles(organization.getId(), + organization.getParent().getId(), tenantId); } catch (TransactionException e) { throw handleServerException(ERROR_CODE_ERROR_ADDING_ORGANIZATION, e, tenantDomain); } } + private void insertOrganizationUserRoleMappingsForMandatoryRoles(String organizationId, String parentId, + int tenantId) + throws OrganizationManagementServerException { + NamedJdbcTemplate namedJdbcTemplate = Utils.getNewTemplate(); + try { + List organizationUserRoleMappingList = + namedJdbcTemplate.executeQuery(GET_ALL_MANDATORY_ORGANIZATION_USER_ROLE_MAPPINGS, + (resultSet, resultRow) -> + new OrganizationUserRoleMapping(parentId, + resultSet.getString(VIEW_USER_ID_COLUMN), + resultSet.getInt(VIEW_HYBRID_ROLE_ID_COLUMN), + resultSet.getString(VIEW_ROLE_ID_COLUMN), + resultSet.getString(VIEW_ASSIGNED_AT_COLUMN), + resultSet.getInt(VIEW_MANDATORY_COLUMN) == 1), + namedPreparedStatement -> { + namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_PARENT_ID, parentId); + namedPreparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_TENANT_ID, tenantId); + namedPreparedStatement.setInt(DB_SCHEMA_COLUMN_NAME_MANDATORY, 1); + }); + if (CollectionUtils.isNotEmpty(organizationUserRoleMappingList)) { + int n = organizationUserRoleMappingList.size(); + namedJdbcTemplate.executeInsert(buildOrganizationUserRoleMappingQuery(n), + namedPreparedStatement -> { + for (int i = 0; i < n; i++) { + OrganizationUserRoleMapping organizationUserRoleMapping = + organizationUserRoleMappingList.get(i); + namedPreparedStatement.setString(String.format(DB_SCHEMA_COLUMN_NAME_ID + "%d", i), + Utils.generateUniqueID()); + namedPreparedStatement.setString(String.format(DB_SCHEMA_COLUMN_NAME_USER_ID + "%d", i), + organizationUserRoleMapping.getUserId()); + namedPreparedStatement.setString(String.format(DB_SCHEMA_COLUMN_NAME_ROLE_ID + "%d", i), + organizationUserRoleMapping.getRoleId()); + namedPreparedStatement.setInt(String.format(DB_SCHEMA_COLUMN_NAME_HYBRID_ROLE_ID + "%d", + i), organizationUserRoleMapping.getHybridRoleId()); + namedPreparedStatement.setInt(String.format(DB_SCHEMA_COLUMN_NAME_TENANT_ID + "%d", i), + tenantId); + namedPreparedStatement.setString(String.format(DB_SCHEMA_COLUMN_NAME_ORG_ID + "%d", i), + organizationId); + namedPreparedStatement.setString(String.format(DB_SCHEMA_COLUMN_NAME_ASSIGNED_AT + "%d", + i), parentId); + namedPreparedStatement.setInt(String.format(DB_SCHEMA_COLUMN_NAME_MANDATORY + "%d", i), + 1); //since mandatory + } + }, organizationUserRoleMappingList, false); + } + } catch (DataAccessException e) { + throw handleServerException(ERROR_CODE_ERROR_ADDING_ORGANIZATION_ROLE_MAPPING, e); + } + } + private void insertOrganizationAttributes(Organization organization) throws TransactionException { String organizationId = organization.getId(); NamedJdbcTemplate namedJdbcTemplate = Utils.getNewTemplate(); - namedJdbcTemplate.withTransaction(template -> { - template.executeBatchInsert(INSERT_ATTRIBUTE, (namedPreparedStatement -> { - for (OrganizationAttribute attribute : organization.getAttributes()) { - namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ID, organizationId); - namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_KEY, attribute.getKey()); - namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_VALUE, attribute.getValue()); - namedPreparedStatement.addBatch(); - } - }), organizationId); - return null; - }); + namedJdbcTemplate.withTransaction(template -> { + template.executeBatchInsert(INSERT_ATTRIBUTE, (namedPreparedStatement -> { + for (OrganizationAttribute attribute : organization.getAttributes()) { + namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_ID, organizationId); + namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_KEY, attribute.getKey()); + namedPreparedStatement.setString(DB_SCHEMA_COLUMN_NAME_VALUE, attribute.getValue()); + namedPreparedStatement.addBatch(); + } + }), organizationId); + return null; + }); } @Override @@ -535,4 +604,16 @@ private Organization buildOrganizationFromRawData(List Date: Thu, 13 Jan 2022 10:33:26 +0530 Subject: [PATCH 2/5] updating README.md file. --- README.md | 221 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) diff --git a/README.md b/README.md index 99da7e8..8d0f41c 100644 --- a/README.md +++ b/README.md @@ -1 +1,222 @@ # identity-organization-management +This is the **Organization Management** implementation for **WSO2 - Organization Management Feature for Identity Server**. +For now, the implementation was done as an **OSGI bundle** and uses **H2 database** and **WSO2 IS 5.12.0**. + +# Configurations + +- Do the following configurations in **deployment.toml** file in`{IS-HOME}/repository/conf/deployment.toml` + + - Add the following configurations to use inbuilt H2 database. + ``` + [database.identity_db] + type = "h2" + url = "jdbc:h2:./repository/database/WSO2IDENTITY_DB;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000" + username = "wso2carbon" + password = "wso2carbon" + ``` + ``` + [database.shared_db] + type = "h2" + url = "jdbc:h2:./repository/database/WSO2SHARED_DB;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000" + username = "wso2carbon" + password = "wso2carbon" + ``` + ``` + [database_configuration] + enable_h2_console = "true" + ``` + - Set H2 database as the primary user store. + ``` + [user_store] + type = "database_unique_id" + ``` + - Set `resource-access-control` to use the API. + ``` + [[resource.access_control]] + context="(.*)/api/identity/organization-mgt/v1.0/(.*)" + secure = "true" + http_method = "ALL" + ``` + - Next start the IS and go to the H2 console using, `http://localhost:8082` and provide the JDBC URL, username and password given above. + `JDBC URL = jdbc:h2:{IS-HOME}/repository/database/WSO2SHARED_DB` + `username = wso2carbon` + `password = wso2carbon` + + - Then use the following queries to add tables. + ``` + CREATE TABLE IF NOT EXISTS UM_ORG ( + UM_ID VARCHAR(255) NOT NULL, + UM_ORG_NAME VARCHAR(255) NOT NULL, + UM_ORG_DESCRIPTION VARCHAR(1024), + UM_CREATED_TIME TIMESTAMP NOT NULL, + UM_LAST_MODIFIED TIMESTAMP NOT NULL, + UM_STATUS VARCHAR(255) DEFAULT 'ACTIVE' NOT NULL, UM_TENANT_ID INTEGER DEFAULT 0, + UM_PARENT_ID VARCHAR(255), PRIMARY KEY (UM_ID), UNIQUE(UM_ORG_NAME, UM_TENANT_ID), FOREIGN KEY (UM_PARENT_ID) REFERENCES UM_ORG(UM_ID) ON DELETE CASCADE ); + ``` + + | UM_ID|UM_ORG_NAME|UM_ORG_DESCRIPTION|UM_CREATED_TIME|UM_LAST_MODIFIED|UM_STATUS|UM_TENANT_ID|UM_PARENT_ID + |---------|--------------------|------------------------------|-------------------------|-----------|--------------|--------------|----- + + ``` + CREATE TABLE IF NOT EXISTS UM_ORG_ATTRIBUTE ( + UM_ID INTEGER NOT NULL AUTO_INCREMENT, + UM_ORG_ID VARCHAR(255) NOT NULL, + UM_ATTRIBUTE_KEY VARCHAR(255) NOT NULL, + UM_ATTRIBUTE_VALUE VARCHAR(512), PRIMARY KEY (UM_ID), + UNIQUE (UM_ORG_ID, UM_ATTRIBUTE_KEY), + FOREIGN KEY (UM_ORG_ID) REFERENCES UM_ORG(UM_ID) ON DELETE CASCADE ); + ``` + | UM_ID|UM_ORG_ID|UM_ATTRIBUTE_KEY|UM_ATTRIBUTE_VALUE + |---------|--------------------|------------------------------|-------| + ``` + CREATE TABLE UM_USER_ROLE_ORG ( + UM_ID VARCHAR2(255) NOT NULL, + UM_USER_ID VARCHAR2(255) NOT NULL, + UM_ROLE_ID VARCHAR2(1024) NOT NULL, + UM_HYBRID_ROLE_ID INTEGER NOT NULL, + UM_TENANT_ID INTEGER DEFAULT 0, + ORG_ID VARCHAR2(255) NOT NULL, + ASSIGNED_AT VARCHAR2(255) NOT NULL, + MANDATORY INTEGER DEFAULT 0, + PRIMARY KEY (UM_ID), + CONSTRAINT FK_UM_USER_ROLE_ORG_UM_HYBRID_ROLE FOREIGN KEY (UM_HYBRID_ROLE_ID, UM_TENANT_ID) REFERENCES UM_HYBRID_ROLE(UM_ID, UM_TENANT_ID) ON DELETE CASCADE, + CONSTRAINT FK_UM_USER_ROLE_ORG_UM_ORG FOREIGN KEY (ORG_ID) REFERENCES UM_ORG(UM_ID) ON DELETE CASCADE, + CONSTRAINT FK_UM_USER_ROLE_ORG_ASSIGNED_AT FOREIGN KEY (ASSIGNED_AT) REFERENCES UM_ORG(UM_ID) ON DELETE CASCADE); + ``` + + | UM_ID|UM_USER_ID|UM_ROLE_ID|UM_HYBRID_ROLE_ID|UM_TENANT_ID|ORG_ID|ASSIGNED_AT|MANDATORY + |--------|---------|---------------|--------------------|---------------|-------------|---------|-----------| + +## Build + +This is a multi-module project containing two modules, +- `org.wso2.carbon.identity.organization.management.service` +- `org.wso2.carbon.identity.organization.management.endpoint` + +Type, +`mvn clean install` to generate the `jar` file in `core` module and `war` file in `endpoint` module. +Alternatively can use `mvn clean install -DskipTests` or `mvn clean install Dmaven.skip.test=true` to skip tests. + +- Copy the `api#identitiy#organization-mgt#v1.0.war` file to `{IS-HOME}/repository/deployment/server/webapps` +- Copy the `org.wso2.carbon.identity.organization.role.mgt.core-.jar` file to `{IS-HOME}/repository/components/dropins` + +## Check the OSGI Service is working + +Run **WSO2 IS** using the following command to check the **OSGI** service. +`sh wso2server.sh -dosgiConsole` +After deploying the **WSO2 IS** check the service is working or not by, +`ss ` and selecting the `jar` file. + +## Debugging + +To debug, open the **WSO2 IS** in remote debugging. +`sh wso2server.sh -debug ` +To disable checkstyle and findbugs plugins, comment from line 319-326. +``` + + com.github.spotbugs + spotbugs-maven-plugin + + + org.apache.maven.plugins + maven-checkstyle-plugin + +``` + +## Features +### Add organization +**API** +`https://localhost:9443/t/{tenant}/api/identity/organization-mgt/v1.0/organizations` + +**Sample Request Body** +``` +{ + "name": "org07", + "description": "building site", + "parentId": "orgid01", + "attributes": [ + { + "key": "Country", + "value": "France" + }, + { + "key": "Language", + "value": "" + }, + { + "key": "Color", + "value": "Blue" + } + ] +} +``` +- Here, an Organization is added to the database. And if there are mandatory organization-user-role mappings coming from the parent organization, those mandatory organization-user-role mappings are added too. + +### Get organization +**API** +`https://localhost:9443/t/{tenant}/api/identity/organization-mgt/v1.0/organizations/{org-id}` + +**Query Parameters** +`showChildren` + +- Here, the organization details are taken from the database using organization id. + +### List organizations +**API** +`https://localhost:9443/t/{tenant}/api/identity/organization-mgt/v1.0/organizations` + +- This gives the list of organizations created by the tenant. + +### Delete organization. +**API** +`https://localhost:9443/t/{tenant-id}/api/identity/organization-mgt/v1.0/organizations/{org-id}` + +**Query Parameters** +`force` + +- This enables the deletion of an organization. +- If the organization is in **ACTIVE** status it will give an error. To bypass such errors the query parameter `force` can be used. + +### Put organization. +**API** +`https://localhost:9443/t/{tenant}/api/identity/organization-mgt/v1.0/organizations/{org-id}` + +**Sample Request Body** +``` +{ + "name": "Test Org 1 Put update", + "description": "Building constructions update", + "attributes": [ + { + "key": "Language", + "value": "Sinhala" + } + ] +} +``` +- Updates the whole organization. + +### Patch organization. +`https://localhost:9443/t/{tenant}/api/identity/organization-mgt/v1.0/organizations/{org-id}` + +**Sample Request Body** +``` +[ + { + "operation": "ADD", + "path": "/description", + "value": "dew" + }, + { + "operation": "ADD", + "path": "/attributes/Country", + "value": "patchcountry" + }, + { + "operation": "ADD", + "path": "/attributes/test", + "value": "patchtest" + } +] +``` +- Can add, remove or replace the values residing inside an organization. \ No newline at end of file From f6692525c1b203159a06a5f0a94fcbef0776c4ce Mon Sep 17 00:00:00 2001 From: nipunaupeksha Date: Thu, 13 Jan 2022 10:34:04 +0530 Subject: [PATCH 3/5] mandatory organization-user-role mappings when creating a new organization. --- .../model/OrganizationUserRoleMapping.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/model/OrganizationUserRoleMapping.java diff --git a/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/model/OrganizationUserRoleMapping.java b/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/model/OrganizationUserRoleMapping.java new file mode 100644 index 0000000..443f55f --- /dev/null +++ b/components/org.wso2.carbon.identity.organization.management.service/src/main/java/org/wso2/carbon/identity/organization/management/service/model/OrganizationUserRoleMapping.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2021, WSO2 Inc. (http://www.wso2.com). + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.wso2.carbon.identity.organization.management.service.model; + +/** + * This class represents the Organization-User-Role mapping. + */ +public class OrganizationUserRoleMapping { + private String organizationId; + private String userId; + private int hybridRoleId; + private String roleId; + private String assignedLevelOrganizationId; + private String assignedLevelOrganizationName; + private boolean isMandatory; + + public OrganizationUserRoleMapping(String organizationId, String userId, int hybridRoleId, String roleId, + String assignedLevelOrganizationId, boolean isMandatory) { + this.organizationId = organizationId; + this.userId = userId; + this.hybridRoleId = hybridRoleId; + this.roleId = roleId; + this.assignedLevelOrganizationId = assignedLevelOrganizationId; + this.isMandatory = isMandatory; + } + + public OrganizationUserRoleMapping(String organizationId, String userId, String roleId, + String assignedLevelOrganizationId, String assignedLevelOrganizationName, + boolean isMandatory) { + this.organizationId = organizationId; + this.userId = userId; + this.roleId = roleId; + this.assignedLevelOrganizationId = assignedLevelOrganizationId; + this.assignedLevelOrganizationName = assignedLevelOrganizationName; + this.isMandatory = isMandatory; + } + + public OrganizationUserRoleMapping() { + } + + public String getOrganizationId() { + return organizationId; + } + + public void setOrganizationId(String organizationId) { + this.organizationId = organizationId; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public int getHybridRoleId() { + return hybridRoleId; + } + + public void setHybridRoleId(int hybridRoleId) { + this.hybridRoleId = hybridRoleId; + } + + public String getRoleId() { + return roleId; + } + + public void setRoleId(String roleId) { + this.roleId = roleId; + } + + public String getAssignedLevelOrganizationId() { + return assignedLevelOrganizationId; + } + + public void setAssignedLevelOrganizationId(String assignedLevelOrganizationId) { + this.assignedLevelOrganizationId = assignedLevelOrganizationId; + } + + public boolean isMandatory() { + return isMandatory; + } + + public void setMandatory(boolean mandatory) { + isMandatory = mandatory; + } + + public String getAssignedLevelOrganizationName() { + return assignedLevelOrganizationName; + } + +} From 3b00168587062a5d408972e2e2cc3e6f3ffd7e6e Mon Sep 17 00:00:00 2001 From: nipunaupeksha Date: Thu, 13 Jan 2022 10:36:29 +0530 Subject: [PATCH 4/5] update README.md file. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8d0f41c..003f77e 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ For now, the implementation was done as an **OSGI bundle** and uses **H2 databas ``` | UM_ID|UM_ORG_NAME|UM_ORG_DESCRIPTION|UM_CREATED_TIME|UM_LAST_MODIFIED|UM_STATUS|UM_TENANT_ID|UM_PARENT_ID - |---------|--------------------|------------------------------|-------------------------|-----------|--------------|--------------|----- + |---------|--------------------|------------------------------|-------------------------|-----------|--------------|--------------|----- ``` CREATE TABLE IF NOT EXISTS UM_ORG_ATTRIBUTE ( @@ -67,7 +67,7 @@ For now, the implementation was done as an **OSGI bundle** and uses **H2 databas FOREIGN KEY (UM_ORG_ID) REFERENCES UM_ORG(UM_ID) ON DELETE CASCADE ); ``` | UM_ID|UM_ORG_ID|UM_ATTRIBUTE_KEY|UM_ATTRIBUTE_VALUE - |---------|--------------------|------------------------------|-------| + |---------|--------------------|------------------------------|-------| ``` CREATE TABLE UM_USER_ROLE_ORG ( UM_ID VARCHAR2(255) NOT NULL, @@ -85,7 +85,7 @@ For now, the implementation was done as an **OSGI bundle** and uses **H2 databas ``` | UM_ID|UM_USER_ID|UM_ROLE_ID|UM_HYBRID_ROLE_ID|UM_TENANT_ID|ORG_ID|ASSIGNED_AT|MANDATORY - |--------|---------|---------------|--------------------|---------------|-------------|---------|-----------| + |--------|---------|---------------|--------------------|---------------|-------------|---------|-----------| ## Build From 1d69df8b56aac735497cc5b6104698671815b7a1 Mon Sep 17 00:00:00 2001 From: Nipuna Upeksha Date: Tue, 18 Jan 2022 00:51:31 +0530 Subject: [PATCH 5/5] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 003f77e..9f14c66 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ Type, Alternatively can use `mvn clean install -DskipTests` or `mvn clean install Dmaven.skip.test=true` to skip tests. - Copy the `api#identitiy#organization-mgt#v1.0.war` file to `{IS-HOME}/repository/deployment/server/webapps` -- Copy the `org.wso2.carbon.identity.organization.role.mgt.core-.jar` file to `{IS-HOME}/repository/components/dropins` +- Copy the `org.wso2.carbon.identity.organization.management.service-.jar` file to `{IS-HOME}/repository/components/dropins` ## Check the OSGI Service is working @@ -219,4 +219,4 @@ To disable checkstyle and findbugs plugins, comment from line 319-326. } ] ``` -- Can add, remove or replace the values residing inside an organization. \ No newline at end of file +- Can add, remove or replace the values residing inside an organization.