Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce role properties object to store role related properties #6194

Merged
merged 1 commit into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ private RoleConstants() {
// Role management service configurations.
public static final String ALLOW_SYSTEM_PREFIX_FOR_ROLES = "RoleMgt.AllowSystemPrefixForRoles";

// Role properties
public static final String IS_SHARED_ROLE_PROP_NAME = "isSharedRole";

/**
* Grouping of constants related to database table names.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleAudience;
import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleBasicInfo;
import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleDTO;
import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleProperty;
import org.wso2.carbon.identity.role.v2.mgt.core.model.UserBasicInfo;
import org.wso2.carbon.identity.role.v2.mgt.core.util.GroupIDResolver;
import org.wso2.carbon.identity.role.v2.mgt.core.util.UserIDResolver;
Expand Down Expand Up @@ -213,6 +214,7 @@ public class RoleDAOImpl implements RoleDAO {
private static final String GROUPS = "groups";
private static final String PERMISSIONS = "permissions";
private static final String ASSOCIATED_APPLICATIONS = "associatedApplications";
private static final String PROPERTIES = "properties";

@Override
public RoleBasicInfo addRole(String roleName, List<String> userList, List<String> groupList,
Expand Down Expand Up @@ -465,6 +467,10 @@ private List<Role> getRolesRequestedAttributes(List<RoleBasicInfo> roles, List<S
role.setAssociatedApplications(associatedApplications);
}
}
if (requiredAttributes.contains(PROPERTIES)) {
role.setRoleProperty(buildRoleProperty(RoleConstants.IS_SHARED_ROLE_PROP_NAME,
String.valueOf(isSharedRole(roleBasicInfo.getId(), tenantDomain))));
}
}
rolesList.add(role);
}
Expand Down Expand Up @@ -500,13 +506,25 @@ public Role getRole(String roleId, String tenantDomain) throws IdentityRoleManag
role.setGroups(getGroupListOfRole(roleId, tenantDomain));
role.setIdpGroups(getIdpGroupListOfRole(roleId, tenantDomain));
if (isSharedRole(roleId, tenantDomain)) {
role.setRoleProperty(buildRoleProperty(RoleConstants.IS_SHARED_ROLE_PROP_NAME,
String.valueOf(Boolean.TRUE)));
role.setPermissions(getPermissionsOfSharedRole(roleId, tenantDomain));
} else {
role.setRoleProperty(buildRoleProperty(RoleConstants.IS_SHARED_ROLE_PROP_NAME,
String.valueOf(Boolean.FALSE)));
role.setPermissions(getPermissions(roleId, tenantDomain));
}
return role;
}

private RoleProperty buildRoleProperty(String propertyName, String propertyValue) {

RoleProperty roleProperty = new RoleProperty();
roleProperty.setName(propertyName);
roleProperty.setValue(propertyValue);
return roleProperty;
}

@Override
public Role getRole(String roleId) throws IdentityRoleManagementException {

Expand Down Expand Up @@ -977,8 +995,12 @@ public Role getRoleWithoutUsers(String roleId, String tenantDomain) throws Ident
role.setGroups(getGroupListOfRole(roleId, tenantDomain));
role.setIdpGroups(getIdpGroupListOfRole(roleId, tenantDomain));
if (isSharedRole(roleId, tenantDomain)) {
role.setRoleProperty(buildRoleProperty(RoleConstants.IS_SHARED_ROLE_PROP_NAME,
String.valueOf(Boolean.TRUE)));
role.setPermissions(getPermissionsOfSharedRole(roleId, tenantDomain));
} else {
role.setRoleProperty(buildRoleProperty(RoleConstants.IS_SHARED_ROLE_PROP_NAME,
String.valueOf(Boolean.FALSE)));
role.setPermissions(getPermissions(roleId, tenantDomain));
}
return role;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2023, WSO2 LLC. (http://www.wso2.com).
* Copyright (c) 2023-2024, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
Expand All @@ -18,6 +18,7 @@

package org.wso2.carbon.identity.role.v2.mgt.core.model;

import java.util.ArrayList;
import java.util.List;

/**
Expand All @@ -37,6 +38,7 @@ public class Role {
private String audienceId;
private String audienceName;
private List<AssociatedApplication> associatedApplications;
private List<RoleProperty> roleProperties = new ArrayList<>();

public Role() {

Expand Down Expand Up @@ -281,4 +283,34 @@ public void setAssociatedApplications(List<AssociatedApplication> associatedAppl

this.associatedApplications = associatedApplications;
}

/**
* Get the role properties.
*
* @return properties list of a role.
*/
public List<RoleProperty> getRoleProperties() {

return roleProperties;
}

/**
* Set the role properties.
*
* @param roleProperties properties list of a role.
*/
public void setRoleProperties(List<RoleProperty> roleProperties) {

this.roleProperties = roleProperties;
}

/**
* Set a role property to the role properties list.
*
* @param roleProperty a property of a role.
*/
public void setRoleProperty(RoleProperty roleProperty) {

this.roleProperties.add(roleProperty);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright (c) 2024, WSO2 LLC. (http://www.wso2.com).
*
* WSO2 LLC. 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.role.v2.mgt.core.model;

import java.io.Serializable;

/**
* Role property object to store the role specific property details.
*/
public class RoleProperty implements Serializable {

private static final long serialVersionUID = 1231265490501221547L;
private String name;
private String value;

/**
* Get the value of the property.
*
* @return value.
*/
public String getValue() {

return value;
}

/**
* Set the value of the property.
*
* @param value Value of the property.
*/
public void setValue(String value) {

this.value = value;
}

/**
* Get the name of the property.
*
* @return Name (This is the key).
*/
public String getName() {

return name;
}

/**
* Set the name of the property.
*
* @param name (This is the key).
*/
public void setName(String name) {

this.name = name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import org.wso2.carbon.identity.role.v2.mgt.core.internal.RoleManagementServiceComponentHolder;
import org.wso2.carbon.identity.role.v2.mgt.core.model.IdpGroup;
import org.wso2.carbon.identity.role.v2.mgt.core.model.Permission;
import org.wso2.carbon.identity.role.v2.mgt.core.model.Role;
import org.wso2.carbon.identity.role.v2.mgt.core.model.RoleBasicInfo;
import org.wso2.carbon.identity.role.v2.mgt.core.model.UserBasicInfo;
import org.wso2.carbon.identity.role.v2.mgt.core.util.GroupIDResolver;
Expand Down Expand Up @@ -127,6 +128,8 @@ public class RoleDAOTest {
private static final String UPDATED_SHARED_ORG_ROLE_NAME = "new-sharing-org-role-001";
private static final String SUB_ORG_ROLE_NAME = "sub-org-role-200";
private static final String MOCKED_EXCEPTION = "Mocked Exception";
private static final String ROLE_PROPERTIES = "properties";
private static final String IS_SHARED_ROLE = "isSharedRole";

private static Map<String, BasicDataSource> dataSourceMap = new HashMap<>();
private List<String> userNamesList = new ArrayList<>();
Expand Down Expand Up @@ -315,6 +318,95 @@ public void testGetRoles() throws Exception {
Assert.assertEquals(getRoleNamesList(roles), expectedRoles);
}

@Test
public void testGetRolesWithRequiredAttributes() throws Exception {

RoleDAOImpl roleDAO = spy(new RoleDAOImpl());
mockCacheClearing(roleDAO);
identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getUserDBConnection(anyBoolean()))
.thenAnswer(invocation -> getConnection());
identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getDBConnection(anyBoolean()))
.thenAnswer(invocation -> getConnection());
identityUtil.when(IdentityUtil::getPrimaryDomainName).thenReturn(USER_DOMAIN_PRIMARY);
identityUtil.when(() -> IdentityUtil.extractDomainFromName(anyString())).thenCallRealMethod();
identityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(anyString())).thenReturn(SAMPLE_TENANT_ID);

addRole(roleNamesList.get(0), APPLICATION_AUD, SAMPLE_APP_ID, roleDAO);
addRole(roleNamesList.get(1), APPLICATION_AUD, SAMPLE_APP_ID, roleDAO);
addRole(roleNamesList.get(2), ORGANIZATION_AUD, SAMPLE_ORG_ID, roleDAO);

identityUtil.when(IdentityUtil::getDefaultItemsPerPage)
.thenReturn(IdentityCoreConstants.DEFAULT_ITEMS_PRE_PAGE);
identityUtil.when(IdentityUtil::getMaximumItemPerPage)
.thenReturn(IdentityCoreConstants.DEFAULT_MAXIMUM_ITEMS_PRE_PAGE);

List<String> requiredAttributes = new ArrayList<>();
requiredAttributes.add(ROLE_PROPERTIES);
List<Role> roles = roleDAO.getRoles(10, 1, null, null, SAMPLE_TENANT_DOMAIN, requiredAttributes);
assertEquals(roles.size(), 3);
for (Role role : roles) {
assertNotNull(role.getRoleProperties());
assertEquals(role.getRoleProperties().get(0).getName(), IS_SHARED_ROLE);
assertEquals(role.getRoleProperties().get(0).getValue(), Boolean.FALSE.toString());
}
}

@Test
public void testGetRoleById() throws Exception {

RoleDAOImpl roleDAO = spy(new RoleDAOImpl());
mockCacheClearing(roleDAO);
identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getUserDBConnection(anyBoolean()))
.thenAnswer(invocation -> getConnection());
identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getDBConnection(anyBoolean()))
.thenAnswer(invocation -> getConnection());
identityUtil.when(IdentityUtil::getPrimaryDomainName).thenReturn(USER_DOMAIN_PRIMARY);
identityUtil.when(() -> IdentityUtil.extractDomainFromName(anyString())).thenCallRealMethod();
identityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(anyString())).thenReturn(SAMPLE_TENANT_ID);

RoleBasicInfo roleBasicInfo = addRole(roleNamesList.get(0), APPLICATION_AUD, SAMPLE_APP_ID, roleDAO);

mockRealmConfiguration();
Role role = roleDAO.getRole(roleBasicInfo.getId(), SAMPLE_TENANT_DOMAIN);
assertEquals(roleBasicInfo.getId(), role.getId());
assertEquals(role.getRoleProperties().get(0).getName(), IS_SHARED_ROLE);
assertEquals(role.getRoleProperties().get(0).getValue(), Boolean.FALSE.toString());
}

@Test
public void testGetRoleByIdWithSharedRole() throws Exception {

RoleDAOImpl roleDAO = spy(new RoleDAOImpl());
mockCacheClearing(roleDAO);
identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getUserDBConnection(anyBoolean()))
.thenAnswer(invocation -> getConnection());
identityDatabaseUtil.when(() -> IdentityDatabaseUtil.getDBConnection(anyBoolean()))
.thenAnswer(invocation -> getConnection());
identityUtil.when(IdentityUtil::getPrimaryDomainName).thenReturn(USER_DOMAIN_PRIMARY);
identityUtil.when(() -> IdentityUtil.extractDomainFromName(anyString())).thenCallRealMethod();
identityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(anyString())).thenReturn(SAMPLE_TENANT_ID);
userCoreUtil.when(() -> UserCoreUtil.isEveryoneRole(anyString(), any(RealmConfiguration.class)))
.thenReturn(false);
userCoreUtil.when(() -> UserCoreUtil.removeDomainFromName(anyString())).thenCallRealMethod();

// Constructing a shared role scenario
RoleBasicInfo roleBasicInfo = addRole(SHARED_ORG_ROLE_NAME, ORGANIZATION_AUD, SAMPLE_ORG_ID, roleDAO);
identityTenantUtil.when(() -> IdentityTenantUtil.getTenantId(L1_ORG_TENANT_DOMAIN)).thenReturn(2);
identityTenantUtil.when(() -> IdentityTenantUtil.getTenantDomain(2)).thenReturn(L1_ORG_TENANT_DOMAIN);
OrganizationManager organizationManager = mock(OrganizationManager.class);
lenient().when(organizationManager.resolveOrganizationId(anyString())).thenReturn(SAMPLE_ORG_ID);
RoleBasicInfo sharedRoleBasicInfo = addRole(SHARED_ORG_ROLE_NAME, ORGANIZATION_AUD,
L1_ORG_TENANT_ORG_ID, roleDAO);
roleDAO.addMainRoleToSharedRoleRelationship(roleBasicInfo.getId(), sharedRoleBasicInfo.getId(),
SAMPLE_TENANT_DOMAIN, L1_ORG_TENANT_DOMAIN);

mockRealmConfiguration();
Role role = roleDAO.getRole(sharedRoleBasicInfo.getId(), L1_ORG_TENANT_DOMAIN);
assertEquals(sharedRoleBasicInfo.getId(), role.getId());
assertEquals(role.getRoleProperties().get(0).getName(), IS_SHARED_ROLE);
assertEquals(role.getRoleProperties().get(0).getValue(), Boolean.TRUE.toString());
}

@Test
public void testGetRolesWithFilter() throws Exception {

Expand Down
Loading