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

Add support for federated IDP groups to role assignments #5143

Merged
merged 3 commits into from
Nov 15, 2023
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 @@ -48,6 +48,10 @@ public class IdPGroup implements Serializable {
@XmlTransient
@JsonIgnore
private String idpGroupId = null;
@IgnoreNullElement
@XmlTransient
@JsonIgnore
private String idpId = null;
SujanSanjula96 marked this conversation as resolved.
Show resolved Hide resolved

public static IdPGroup build(OMElement idpGroupOM) {

Expand Down Expand Up @@ -101,4 +105,24 @@ public void setIdpGroupId(String idpGroupId) {

this.idpGroupId = idpGroupId;
}

/**
* Get idp id.
*
* @return idp Id.
*/
public String getIdpId() {

return idpId;
}

/**
* Set idp id.
*
* @param idpId idp id.
*/
public void setIdpId(String idpId) {

this.idpId = idpId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.wso2.carbon.identity.application.common.model.ClaimConfig;
import org.wso2.carbon.identity.application.common.model.ClaimMapping;
import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.IdPGroup;
import org.wso2.carbon.identity.application.common.model.IdentityProvider;
import org.wso2.carbon.identity.application.common.model.IdentityProviderProperty;
import org.wso2.carbon.identity.application.common.model.LocalRole;
Expand Down Expand Up @@ -81,6 +82,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -2959,6 +2961,22 @@ public IdentityProvider getIdPByMetadataProperty(String property, String value,
return getIdPByName(idPName, tenantDomain, ignoreFileBasedIdps);
}

@Override
public List<IdPGroup> getValidIdPGroupsByIdPGroupIds(List<String> idpGroupIds, String tenantDomain)
throws IdentityProviderManagementException {

if (CollectionUtils.isEmpty(idpGroupIds)) {
return Collections.emptyList();
}
try {
int tenantId = IdentityTenantUtil.getTenantId(tenantDomain);
return dao.getIdPGroupsByIds(idpGroupIds, tenantId);
} catch (IdentityProviderManagementException e) {
throw IdPManagementUtil.handleServerException(
IdPManagementConstants.ErrorMessage.ERROR_CODE_RETRIEVING_IDP_GROUPS, null, e);
}
}

/**
* Method to validate the uniqueness of the IDP Issuer Name.
* Ideally used when adding a IDP.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.wso2.carbon.identity.application.common.model.ClaimMapping;
import org.wso2.carbon.identity.application.common.model.FederatedAuthenticatorConfig;
import org.wso2.carbon.identity.application.common.model.IdPGroup;
import org.wso2.carbon.identity.application.common.model.IdentityProvider;
import org.wso2.carbon.identity.application.common.model.LocalRole;
import org.wso2.carbon.identity.application.common.model.ProvisioningConnectorConfig;
Expand Down Expand Up @@ -531,4 +532,18 @@ default IdentityProvider getIdPByMetadataProperty(String property, String value,

return null;
}

/**
* Get valid IDP groups by IDP group IDs.
*
* @param idpGroupIds List of IDP group IDs.
* @param tenantDomain Tenant domain.
* @return List of valid IDP groups.
* @throws IdentityProviderManagementException If an error occurred while getting IDP Group data.
*/
default List<IdPGroup> getValidIdPGroupsByIdPGroupIds(List<String> idpGroupIds, String tenantDomain)
throws IdentityProviderManagementException {

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.context.CarbonContext;
import org.wso2.carbon.identity.application.common.model.IdPGroup;
import org.wso2.carbon.identity.application.common.model.IdentityProvider;
import org.wso2.carbon.identity.application.common.model.IdentityProviderProperty;
import org.wso2.carbon.identity.application.common.util.IdentityApplicationConstants;
Expand Down Expand Up @@ -1062,4 +1063,18 @@ public Map<String, String> getIdPNamesById(int tenantId, Set<String> idpIds)

return idPMgtDAO.getIdPNamesById(tenantId, idpIds);
}

/**
* Get IDP group data by IDP group IDs.
*
* @param idpGroupIds List of IDP group IDs.
* @param tenantId Tenant ID.
* @return List of IDP groups.
* @throws IdentityProviderManagementException If an error occurred while retrieving IDP groups.
*/
public List<IdPGroup> getIdPGroupsByIds(List<String> idpGroupIds, int tenantId)
throws IdentityProviderManagementException {

return idPMgtDAO.getIdPGroupsByIds(idpGroupIds, tenantId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -5022,4 +5023,44 @@ public Map<String, String> getIdPNamesById(int tenantId, Set<String> idpIds)
IdentityDatabaseUtil.closeAllConnections(dbConnection, rs, prepStmt);
}
}

/**
* Get IDP group data by IDP group IDs.
*
* @param idpGroupIds List of IDP group IDs.
* @param tenantId Tenant ID.
* @return List of IDP groups.
* @throws IdentityProviderManagementException If an error occurred while retrieving IDP groups.
*/
public List<IdPGroup> getIdPGroupsByIds(List<String> idpGroupIds, int tenantId)
throws IdentityProviderManagementException {

if (CollectionUtils.isEmpty(idpGroupIds)) {
return Collections.emptyList();
}
String query = IdPManagementConstants.SQLQueries.GET_IDP_GROUPS_BY_IDP_GROUP_IDS;
String placeholders = String.join(",", Collections.nCopies(idpGroupIds.size(), "?"));
SujanSanjula96 marked this conversation as resolved.
Show resolved Hide resolved
query = query.replace(IdPManagementConstants.IDP_GROUP_LIST_PLACEHOLDER, placeholders);
try (Connection connection = IdentityDatabaseUtil.getDBConnection(false);
PreparedStatement prepStmt = connection.prepareStatement(query)) {
prepStmt.setInt(1, tenantId);
for (int i = 0; i < idpGroupIds.size(); i++) {
prepStmt.setString(i + 2, idpGroupIds.get(i));
}
try (ResultSet resultSet = prepStmt.executeQuery()) {
List<IdPGroup> idpGroups = new ArrayList<>();
while (resultSet.next()) {
IdPGroup idpGroup = new IdPGroup();
idpGroup.setIdpGroupId(resultSet.getString("UUID"));
idpGroup.setIdpGroupName(resultSet.getString("GROUP_NAME"));
idpGroup.setIdpId(resultSet.getString("IDP_ID"));
idpGroups.add(idpGroup);
}
return idpGroups;
}
} catch (SQLException e) {
throw new IdentityProviderManagementException("Error occurred while retrieving IDP groups for IDP group " +
"IDs: " + idpGroupIds, e);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ public class IdPManagementConstants {

public static final String SHARED_IDP_PREFIX = "SHARED_";
public static final String SCOPE_LIST_PLACEHOLDER = "_SCOPE_LIST_";
public static final String IDP_GROUP_LIST_PLACEHOLDER = "_IDP_GROUP_LIST_";
public static final String MULTI_VALUED_PROPERTY_CHARACTER = ".";
public static final String IS_TRUE_VALUE = "1";
public static final String IS_FALSE_VALUE = "0";
Expand Down Expand Up @@ -553,6 +554,9 @@ public static class SQLQueries {
"IDP_METADATA.TENANT_ID = ?";
public static final String GET_TOTAL_IDP_CLAIM_USAGES = "SELECT COUNT(*) FROM IDP_CLAIM_MAPPING WHERE " +
"TENANT_ID = ? AND LOCAL_CLAIM = ?";
public static final String GET_IDP_GROUPS_BY_IDP_GROUP_IDS = "SELECT IDP_GROUP.UUID, IDP_GROUP.GROUP_NAME, " +
"IDP.UUID AS IDP_ID FROM IDP_GROUP LEFT JOIN IDP ON IDP.ID = IDP_GROUP.IDP_ID WHERE " +
"IDP_GROUP.TENANT_ID = ? AND IDP_GROUP.UUID IN (" + IDP_GROUP_LIST_PLACEHOLDER + ")";
}

public enum ErrorMessage {
Expand Down Expand Up @@ -585,7 +589,8 @@ public enum ErrorMessage {
ERROR_CODE_RETRIEVE_IDP_CONNECTED_APPS("IDP-65007", "Error while retrieving connected " +
"applications of Identity Provider with resource ID: %s."),
ERROR_CODE_VALIDATING_OUTBOUND_PROVISIONING_ROLES("IDP-65008", "Error while validating " +
"the outbound provisioning roles");
"the outbound provisioning roles"),
ERROR_CODE_RETRIEVING_IDP_GROUPS("IDP-65009", "Error while retrieving IDP groups");

private final String code;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1253,25 +1253,14 @@ private void resolveIdpGroups(List<IdpGroup> groups, String tenantDomain) throws
if (groups == null || groups.isEmpty()) {
return;
}
for (IdpGroup group : groups) {

IdentityProvider identityProvider = getIdpById(group.getIdpId(), tenantDomain);
if (identityProvider == null) {
throw new IdentityRoleManagementException("Idp not found.",
"Idp not found for id : " + group.getIdpId());
}
IdPGroup[] idpGroups = identityProvider.getIdPGroupConfig();
Map<String, String> idpGroupIdList = new HashMap<>();
for (IdPGroup idpGroup : idpGroups) {
idpGroupIdList.put(idpGroup.getIdpGroupId(), idpGroup.getIdpGroupName());
}
if (idpGroupIdList.containsKey(group.getGroupId())) {
group.setGroupName(idpGroupIdList.get(group.getGroupId()));
} else {
throw new IdentityRoleManagementException("Idp group not found.",
"Idp group not found for id : " + group.getGroupId());
}
}
List<String> idpGroupIds = groups.stream()
.map(IdpGroup::getGroupId)
.collect(Collectors.toList());
List<IdPGroup> idpGroups = getIdpGroupsByIds(idpGroupIds, tenantDomain);

groups.clear();
idpGroups.stream().map(this::convertToIdpGroup).forEach(groups::add);
}

/**
Expand Down Expand Up @@ -2958,6 +2947,27 @@ private IdentityProvider getIdpById(String idpId, String tenantDomain)
return identityProvider;
}

/**
* Get idp groups by id.
*
* @param idpGroupIds Idp group ids.
* @param tenantDomain Tenant domain.
* @throws IdentityRoleManagementException Error occurred while retrieving idp groups by id.
*/
private List<IdPGroup> getIdpGroupsByIds(List<String> idpGroupIds, String tenantDomain)
throws IdentityRoleManagementException {

List<IdPGroup> idpGroups;
try {
idpGroups = RoleManagementServiceComponentHolder.getInstance()
.getIdentityProviderManager().getValidIdPGroupsByIdPGroupIds(idpGroupIds, tenantDomain);
} catch (IdentityProviderManagementException e) {
throw new IdentityRoleManagementException("Error while retrieving idp groups", "Error while retrieving idp "
+ "groups for idp Ids: " + idpGroupIds, e);
}
return idpGroups;
}

/**
* Delete SCIM role.
*
Expand Down Expand Up @@ -3245,4 +3255,11 @@ private void lessThanFilterBuilder(String value, String attributeName, StringBui
filter.append(attributeName).append(filterString);
filterQueryBuilder.setFilterAttributeValue(attributeName, value);
}

private IdpGroup convertToIdpGroup(IdPGroup idpGroup) {

IdpGroup convertedGroup = new IdpGroup(idpGroup.getIdpGroupId(), idpGroup.getIdpId());
convertedGroup.setGroupName(idpGroup.getIdpGroupName());
return convertedGroup;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
<xs:sequence>
<xs:element minOccurs="0" name="idpGroupId" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="idpGroupName" nillable="true" type="xs:string"/>
<xs:element minOccurs="0" name="idpId" nillable="true" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="IdentityProviderProperty">
Expand Down
Loading