/* * Copyright (c) 2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * 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.scim.common.group; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil; import org.wso2.carbon.identity.core.util.IdentityUtil; import org.wso2.carbon.identity.scim.common.utils.IdentitySCIMException; import org.wso2.carbon.identity.scim.common.utils.SCIMCommonUtils; import org.wso2.carbon.identity.scim.common.utils.SQLQueries; import org.wso2.carbon.user.core.util.UserCoreUtil; import org.wso2.charon.core.schema.SCIMConstants; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * JDBC based Data Access layer for managing SCIM specific attributes that are not stored in * user store. */ public class GroupDAO { private static Log log = LogFactory.getLog(GroupDAO.class); /** * Lists the groups that are created from SCIM * * @return The set of groups that were created from SCIM * @throws IdentitySCIMException */ public Set<String> listSCIMGroups() throws IdentitySCIMException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet resultSet = null; Set<String> groups = new HashSet<>(); try { //retrieve groups from the DB prepStmt = connection.prepareStatement(SQLQueries.LIST_SCIM_GROUPS_SQL); prepStmt.setString(1, SCIMConstants.ID_URI); resultSet = prepStmt.executeQuery(); while (resultSet.next()) { String group = resultSet.getString(1); if (StringUtils.isNotEmpty(group)) { groups.add(group); } } } catch (SQLException e) { throw new IdentitySCIMException("Error when reading the SCIM Group information from persistence store.", e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, resultSet, prepStmt); } return groups; } public boolean isExistingGroup(String groupName, int tenantId) throws IdentitySCIMException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rSet = null; boolean isExistingGroup = false; try { prepStmt = connection.prepareStatement(SQLQueries.CHECK_EXISTING_GROUP_SQL); prepStmt.setInt(1, tenantId); prepStmt.setString(2, SCIMCommonUtils.getGroupNameWithDomain(groupName)); rSet = prepStmt.executeQuery(); if (rSet.next()) { isExistingGroup = true; } connection.commit(); } catch (SQLException e) { throw new IdentitySCIMException("Error when reading the group information from the persistence store.", e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rSet, prepStmt); } return isExistingGroup; } private boolean isExistingAttribute(String attributeName, String groupName, int tenantId) throws IdentitySCIMException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rSet = null; boolean isExistingAttribute = false; try { prepStmt = connection.prepareStatement(SQLQueries.CHECK_EXISTING_ATTRIBUTE_SQL); prepStmt.setInt(1, tenantId); prepStmt.setString(2, SCIMCommonUtils.getGroupNameWithDomain(groupName)); prepStmt.setString(3, attributeName); rSet = prepStmt.executeQuery(); if (rSet.next()) { isExistingAttribute = true; } connection.commit(); } catch (SQLException e) { throw new IdentitySCIMException("Error when reading the group attribute information from " + "the persistence store.", e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rSet, prepStmt); } return isExistingAttribute; } public void addSCIMGroupAttributes(int tenantId, String roleName, Map<String, String> attributes) throws IdentitySCIMException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; if (!isExistingGroup(SCIMCommonUtils.getGroupNameWithDomain(roleName), tenantId)) { try { prepStmt = connection.prepareStatement(SQLQueries.ADD_ATTRIBUTES_SQL); prepStmt.setInt(1, tenantId); prepStmt.setString(2, roleName); for (Map.Entry<String, String> entry : attributes.entrySet()) { if (!isExistingAttribute(entry.getKey(), SCIMCommonUtils.getGroupNameWithDomain(roleName), tenantId)) { prepStmt.setString(3, entry.getKey()); prepStmt.setString(4, entry.getValue()); prepStmt.execute(); connection.commit(); } else { throw new IdentitySCIMException("Error when adding SCIM Attribute: " + entry.getKey() + " An attribute with the same name already exists."); } } connection.commit(); } catch (SQLException e) { throw new IdentitySCIMException("Error when adding SCIM attributes for the group: " + roleName, e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, null, prepStmt); } } else { throw new IdentitySCIMException("Error when adding SCIM Attributes for the group: " + roleName + " A Group with the same name already exists."); } } public void updateSCIMGroupAttributes(int tenantId, String roleName, Map<String, String> attributes) throws IdentitySCIMException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; if (isExistingGroup(SCIMCommonUtils.getGroupNameWithDomain(roleName), tenantId)) { try { prepStmt = connection.prepareStatement(SQLQueries.UPDATE_ATTRIBUTES_SQL); prepStmt.setInt(2, tenantId); prepStmt.setString(3, roleName); for (Map.Entry<String, String> entry : attributes.entrySet()) { if (isExistingAttribute(entry.getKey(), SCIMCommonUtils.getGroupNameWithDomain(roleName), tenantId)) { prepStmt.setString(4, entry.getKey()); prepStmt.setString(1, entry.getValue()); int count = prepStmt.executeUpdate(); if (log.isDebugEnabled()) { log.debug("No. of records updated for updating SCIM Group : " + count); } connection.commit(); } else { throw new IdentitySCIMException("Error when adding SCIM Attribute: " + entry.getKey() + " An attribute with the same name doesn't exists."); } } } catch (SQLException e) { throw new IdentitySCIMException("Error updating the SCIM Group Attributes.", e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, null, prepStmt); } } else { throw new IdentitySCIMException("Error when updating SCIM Attributes for the group: " + roleName + " A Group with the same name doesn't exists."); } } public void removeSCIMGroup(int tenantId, String roleName) throws IdentitySCIMException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; try { prepStmt = connection.prepareStatement(SQLQueries.DELETE_GROUP_SQL); prepStmt.setInt(1, tenantId); prepStmt.setString(2, SCIMCommonUtils.getGroupNameWithDomain(roleName)); prepStmt.execute(); connection.commit(); } catch (SQLException e) { log.error("Error when executing the SQL : " + SQLQueries.DELETE_GROUP_SQL); throw new IdentitySCIMException("Error deleting the SCIM Group.", e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, null, prepStmt); } } public Map<String, String> getSCIMGroupAttributes(int tenantId, String roleName) throws IdentitySCIMException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rSet = null; Map<String, String> attributes = new HashMap<>(); try { prepStmt = connection.prepareStatement(SQLQueries.GET_ATTRIBUTES_SQL); prepStmt.setInt(1, tenantId); prepStmt.setString(2, SCIMCommonUtils.getGroupNameWithDomain(roleName)); rSet = prepStmt.executeQuery(); while (rSet.next()) { if (StringUtils.isNotEmpty(rSet.getString(1))) { attributes.put(rSet.getString(1), rSet.getString(2)); } } connection.commit(); } catch (SQLException e) { log.error("Error when executing the SQL : " + SQLQueries.GET_ATTRIBUTES_SQL); throw new IdentitySCIMException("Error when reading the SCIM Group information from the " + "persistence store.", e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rSet, prepStmt); } return attributes; } public String getGroupNameById(int tenantId, String id) throws IdentitySCIMException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; ResultSet rSet = null; String roleName = null; try { prepStmt = connection.prepareStatement(SQLQueries.GET_GROUP_NAME_BY_ID_SQL); prepStmt.setInt(1, tenantId); prepStmt.setString(2, id); prepStmt.setString(3, SCIMConstants.ID_URI); rSet = prepStmt.executeQuery(); while (rSet.next()) { //we assume only one result since group id and tenant id is unique. roleName = rSet.getString(1); } connection.commit(); } catch (SQLException e) { throw new IdentitySCIMException("Error when reading the SCIM Group information from the persistence store.", e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, rSet, prepStmt); } if (StringUtils.isNotEmpty(roleName)) { return SCIMCommonUtils.getPrimaryFreeGroupName(roleName); } return null; } public void updateRoleName(int tenantId, String oldRoleName, String newRoleName) throws IdentitySCIMException { Connection connection = IdentityDatabaseUtil.getDBConnection(); PreparedStatement prepStmt = null; if (isExistingGroup(SCIMCommonUtils.getGroupNameWithDomain(oldRoleName), tenantId)) { try { prepStmt = connection.prepareStatement(SQLQueries.UPDATE_GROUP_NAME_SQL); prepStmt.setString(1, SCIMCommonUtils.getGroupNameWithDomain(newRoleName)); prepStmt.setInt(2, tenantId); prepStmt.setString(3, SCIMCommonUtils.getGroupNameWithDomain(oldRoleName)); int count = prepStmt.executeUpdate(); if (log.isDebugEnabled()) { log.debug("No. of records updated for updating SCIM Group : " + count); } connection.commit(); } catch (SQLException e) { throw new IdentitySCIMException("Error updating the SCIM Group Attributes", e); } finally { IdentityDatabaseUtil.closeAllConnections(connection, null, prepStmt); } } else { throw new IdentitySCIMException("Error when updating role name of the role: " + oldRoleName); } } }