/*
* Copyright (c) 2014, 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.provisioning.dao;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.application.common.IdentityApplicationManagementException;
import org.wso2.carbon.identity.application.common.model.IdentityProvider;
import org.wso2.carbon.identity.application.common.util.IdentityApplicationManagementUtil;
import org.wso2.carbon.identity.core.persistence.JDBCPersistenceManager;
import org.wso2.carbon.identity.core.util.IdentityDatabaseUtil;
import org.wso2.carbon.identity.core.util.IdentityUtil;
import org.wso2.carbon.identity.provisioning.IdentityProvisioningConstants;
import org.wso2.carbon.identity.provisioning.ProvisionedIdentifier;
import org.wso2.carbon.identity.provisioning.ProvisioningEntity;
import org.wso2.carbon.identity.provisioning.ProvisioningUtil;
import org.wso2.carbon.idp.mgt.util.IdPManagementConstants;
import org.wso2.carbon.user.core.util.DatabaseUtil;
import org.wso2.carbon.user.core.util.UserCoreUtil;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ProvisioningManagementDAO {
private static final Log log = LogFactory.getLog(ProvisioningManagementDAO.class);
/**
* @param identityProviderName
* @param connectorType
* @param provisioningEntity
* @param tenantId
* @throws IdentityApplicationManagementException
*/
public void addProvisioningEntity(String identityProviderName, String connectorType,
ProvisioningEntity provisioningEntity, int tenantId)
throws IdentityApplicationManagementException {
Connection dbConnection = IdentityDatabaseUtil.getDBConnection();
try {
PreparedStatement prepStmt = null;
// id of the identity provider
int idpId = getIdentityProviderIdentifier(dbConnection, identityProviderName, tenantId);
// id of the provisioning configuration
int provisioningConfigId = getProvisioningConfigurationIdentifier(dbConnection, idpId,
connectorType);
String localId = getLocalIdFromProvisioningEntity(provisioningEntity);
// PROVISIONING_CONFIG_ID, ENTITY_TYPE,
// ENTITY_LOCAL_USERSTORE, ENTITY_NAME, ENTITY_VALUE,
// TENANT_ID
String sqlStmt = IdentityProvisioningConstants.SQLQueries.ADD_PROVISIONING_ENTITY_SQL;
prepStmt = dbConnection.prepareStatement(sqlStmt);
prepStmt.setInt(1, provisioningConfigId);
prepStmt.setString(2, provisioningEntity.getEntityType().toString());
prepStmt.setString(3, IdentityUtil.extractDomainFromName(provisioningEntity.getEntityName()));
prepStmt.setString(4, UserCoreUtil.removeDomainFromName(provisioningEntity.getEntityName()));
prepStmt.setString(5, provisioningEntity.getIdentifier().getIdentifier());
prepStmt.setInt(6, tenantId);
prepStmt.setString(7, localId);
prepStmt.execute();
dbConnection.commit();
} catch (SQLException e) {
IdentityApplicationManagementUtil.rollBack(dbConnection);
String msg = "Error occurred while adding Provisioning entity for tenant " + tenantId;
throw new IdentityApplicationManagementException(msg, e);
} finally {
IdentityApplicationManagementUtil.closeConnection(dbConnection);
}
}
/**
* @param identityProviderName
* @param connectorType
* @param provisioningEntity
* @param tenantId
* @throws IdentityApplicationManagementException
*/
public void deleteProvisioningEntity(String identityProviderName, String connectorType,
ProvisioningEntity provisioningEntity, int tenantId)
throws IdentityApplicationManagementException {
Connection dbConnection = IdentityDatabaseUtil.getDBConnection();
try {
PreparedStatement prepStmt = null;
// id of the identity provider
int idpId = getIdentityProviderIdentifier(dbConnection, identityProviderName, tenantId);
// id of the provisioning configuration
int provisioningConfigId = getProvisioningConfigurationIdentifier(dbConnection, idpId,
connectorType);
// PROVISIONING_CONFIG_ID, ENTITY_TYPE,
// ENTITY_LOCAL_USERSTORE, ENTITY_NAME, TENANT_ID
String sqlStmt = IdentityProvisioningConstants.SQLQueries.DELETE_PROVISIONING_ENTITY_SQL;
prepStmt = dbConnection.prepareStatement(sqlStmt);
prepStmt.setInt(1, provisioningConfigId);
prepStmt.setString(2, provisioningEntity.getEntityType().toString());
prepStmt.setString(3, IdentityUtil.extractDomainFromName(provisioningEntity.getEntityName()));
prepStmt.setString(4, UserCoreUtil.removeDomainFromName(provisioningEntity.getEntityName()));
prepStmt.setInt(5, tenantId);
prepStmt.execute();
dbConnection.commit();
} catch (SQLException e) {
IdentityApplicationManagementUtil.rollBack(dbConnection);
String msg = "Error occurred while deleting Provisioning entity for tenant " + tenantId;
throw new IdentityApplicationManagementException(msg, e);
} finally {
IdentityApplicationManagementUtil.closeConnection(dbConnection);
}
}
/**
* @param identityProviderName
* @param connectorType
* @param provisioningEntity
* @param tenantId
* @throws IdentityApplicationManagementException
*/
public ProvisionedIdentifier getProvisionedIdentifier(String identityProviderName, String connectorType,
ProvisioningEntity provisioningEntity, int tenantId)
throws IdentityApplicationManagementException {
Connection dbConnection = IdentityDatabaseUtil.getDBConnection();
try {
PreparedStatement prepStmt = null;
// id of the identity provider
int idpId = getIdentityProviderIdentifier(dbConnection, identityProviderName, tenantId);
// id of the provisioning configuration
int provisioningConfigId = getProvisioningConfigurationIdentifier(dbConnection, idpId,
connectorType);
// PROVISIONING_CONFIG_ID, ENTITY_TYPE,
// ENTITY_LOCAL_USERSTORE, ENTITY_NAME, ENTITY_VALUE,
// TENANT_ID
String sqlStmt = IdentityProvisioningConstants.SQLQueries.GET_PROVISIONING_ENTITY_SQL;
prepStmt = dbConnection.prepareStatement(sqlStmt);
prepStmt.setInt(1, provisioningConfigId);
prepStmt.setString(2, provisioningEntity.getEntityType().toString());
prepStmt.setString(3, IdentityUtil.extractDomainFromName(provisioningEntity.getEntityName()));
prepStmt.setString(4, UserCoreUtil.removeDomainFromName(provisioningEntity.getEntityName()));
prepStmt.setInt(5, tenantId);
ResultSet rs = prepStmt.executeQuery();
dbConnection.commit();
if (rs.next()) {
String entityId = rs.getString(1);
ProvisionedIdentifier provisionedIdentifier = new ProvisionedIdentifier();
provisionedIdentifier.setIdentifier(entityId);
return provisionedIdentifier;
} else {
return null;
}
} catch (SQLException e) {
IdentityApplicationManagementUtil.rollBack(dbConnection);
String msg = "Error occurred while adding Provisioning entity for tenant " + tenantId;
throw new IdentityApplicationManagementException(msg, e);
} finally {
IdentityApplicationManagementUtil.closeConnection(dbConnection);
}
}
/**
* @param newIdentityProvider
* @param currentIdentityProvider
* @param tenantId
* @throws IdentityApplicationManagementException
*/
public void updateProvisionedIdentifier(IdentityProvider newIdentityProvider,
IdentityProvider currentIdentityProvider, int tenantId)
throws IdentityApplicationManagementException {
Connection dbConnection = IdentityDatabaseUtil.getDBConnection();
try {
int idPId =
getIdentityProviderIdByName(dbConnection,
newIdentityProvider.getIdentityProviderName(),
tenantId);
if (idPId <= 0) {
String msg =
"Trying to update non-existent Identity Provider for tenant " +
tenantId;
throw new IdentityApplicationManagementException(msg);
}
PreparedStatement prepStmt = null;
// SP_IDP_NAME=?, SP_IDP_PRIMARY=?,SP_IDP_HOME_REALM_ID=?,
// SP_IDP_THUMBPRINT=?,
// SP_IDP_TOKEN_EP_ALIAS=?,
// SP_IDP_INBOUND_PROVISIONING_ENABLED=?,SP_IDP_INBOUND_PROVISIONING_USER_STORE_ID=?,SP_IDP_USER_CLAIM_URI=?,
// SP_IDP_ROLE_CLAIM_URI=?,SP_IDP_DEFAULT_AUTHENTICATOR_NAME=?,SP_IDP_DEFAULT_PRO_CONNECTOR_NAME=?
String sqlStmt = IdPManagementConstants.SQLQueries.UPDATE_IDP_SQL;
prepStmt = dbConnection.prepareStatement(sqlStmt);
prepStmt.setString(1, newIdentityProvider.getIdentityProviderName());
if (newIdentityProvider.isPrimary()) {
prepStmt.setString(2, "1");
} else {
prepStmt.setString(2, "0");
}
prepStmt.setString(3, newIdentityProvider.getHomeRealmId());
prepStmt.setBinaryStream(4, setBlobValue(newIdentityProvider.getCertificate()));
prepStmt.setString(5, newIdentityProvider.getAlias());
if (newIdentityProvider.getJustInTimeProvisioningConfig() != null &&
newIdentityProvider.getJustInTimeProvisioningConfig().isProvisioningEnabled()) {
prepStmt.setString(6, "1");
prepStmt.setString(7, newIdentityProvider.getJustInTimeProvisioningConfig()
.getProvisioningUserStore());
} else {
prepStmt.setString(6, "0");
prepStmt.setString(7, null);
}
if (newIdentityProvider.getClaimConfig() != null) {
prepStmt.setString(8, newIdentityProvider.getClaimConfig().getUserClaimURI());
prepStmt.setString(9, newIdentityProvider.getClaimConfig().getRoleClaimURI());
} else {
prepStmt.setString(8, null);
prepStmt.setString(9, null);
}
// update the default authenticator
if (newIdentityProvider.getDefaultAuthenticatorConfig() != null &&
newIdentityProvider.getDefaultAuthenticatorConfig().getName() != null) {
prepStmt.setString(10, newIdentityProvider.getDefaultAuthenticatorConfig()
.getName());
} else {
// its not a must to have a default authenticator.
prepStmt.setString(10, null);
}
// update the default provisioning connector.
if (newIdentityProvider.getDefaultProvisioningConnectorConfig() != null &&
newIdentityProvider.getDefaultProvisioningConnectorConfig().getName() != null) {
prepStmt.setString(11, newIdentityProvider.getDefaultProvisioningConnectorConfig()
.getName());
} else {
// its not a must to have a default provisioning connector..
prepStmt.setString(11, null);
}
prepStmt.setString(12, newIdentityProvider.getIdentityProviderDescription());
prepStmt.setInt(13, tenantId);
prepStmt.setString(14, currentIdentityProvider.getIdentityProviderName());
prepStmt.executeUpdate();
prepStmt.clearParameters();
IdentityApplicationManagementUtil.closeStatement(prepStmt);
dbConnection.commit();
} catch (SQLException e) {
IdentityApplicationManagementUtil.rollBack(dbConnection);
String msg = "Error occurred while updating Identity Provider information for tenant " + tenantId;
throw new IdentityApplicationManagementException(msg, e);
} finally {
IdentityApplicationManagementUtil.closeConnection(dbConnection);
}
}
/**
* @param idPName
* @param tenantId
* @param tenantDomain
* @throws IdentityApplicationManagementException
*/
public void deleteProvisionedIdentifier(String idPName, int tenantId, String tenantDomain)
throws IdentityApplicationManagementException {
}
/**
* @param conn
* @param tenantId
* @param idPName
* @throws SQLException
*/
private void deleteIdP(Connection conn, int tenantId, String idPName) throws SQLException {
PreparedStatement prepStmt = null;
String sqlStmt = IdPManagementConstants.SQLQueries.DELETE_IDP_SQL;
try {
prepStmt = conn.prepareStatement(sqlStmt);
prepStmt.setInt(1, tenantId);
prepStmt.setString(2, idPName);
prepStmt.executeUpdate();
} finally {
IdentityApplicationManagementUtil.closeStatement(prepStmt);
}
}
/**
* @param dbConnection
* @param idpName
* @param tenantId
* @return
* @throws SQLException
* @throws IdentityApplicationManagementException
*/
private int getIdentityProviderIdByName(Connection dbConnection, String idpName, int tenantId)
throws SQLException,
IdentityApplicationManagementException {
boolean dbConnInitialized = true;
PreparedStatement prepStmt = null;
ResultSet rs = null;
if (dbConnection == null) {
dbConnection = IdentityDatabaseUtil.getDBConnection();
} else {
dbConnInitialized = false;
}
try {
String sqlStmt = IdPManagementConstants.SQLQueries.GET_IDP_ROW_ID_SQL;
prepStmt = dbConnection.prepareStatement(sqlStmt);
prepStmt.setInt(1, tenantId);
prepStmt.setString(2, idpName);
rs = prepStmt.executeQuery();
dbConnection.commit();
if (rs.next()) {
return rs.getInt(1);
}
} finally {
IdentityApplicationManagementUtil.closeStatement(prepStmt);
IdentityApplicationManagementUtil.closeResultSet(rs);
if (dbConnInitialized) {
IdentityApplicationManagementUtil.closeConnection(dbConnection);
}
}
return 0;
}
/**
* @param dbConnection
* @param idPName
* @param tenantId
* @return
* @throws SQLException
* @throws IdentityApplicationManagementException
*/
private int getIdentityProviderIdentifier(Connection dbConnection, String idPName, int tenantId)
throws SQLException,
IdentityApplicationManagementException {
String sqlStmt = null;
PreparedStatement prepStmt = null;
ResultSet rs = null;
try {
sqlStmt = IdPManagementConstants.SQLQueries.GET_IDP_ID_BY_NAME_SQL;
prepStmt = dbConnection.prepareStatement(sqlStmt);
prepStmt.setInt(1, tenantId);
prepStmt.setString(2, idPName);
rs = prepStmt.executeQuery();
if (rs.next()) {
return rs.getInt(1);
} else {
throw new IdentityApplicationManagementException("Invalid Identity Provider Name " +
idPName);
}
} finally {
IdentityApplicationManagementUtil.closeResultSet(rs);
IdentityApplicationManagementUtil.closeStatement(prepStmt);
}
}
/**
* @param dbConnection
* @param idPId
* @param connectorType
* @return
* @throws SQLException
* @throws IdentityApplicationManagementException
*/
private int getProvisioningConfigurationIdentifier(Connection dbConnection, int idPId,
String connectorType) throws SQLException,
IdentityApplicationManagementException {
String sqlStmt = null;
PreparedStatement prepStmt = null;
ResultSet rs = null;
try {
sqlStmt = IdentityProvisioningConstants.SQLQueries.GET_IDP_PROVISIONING_CONFIG_ID_SQL;
prepStmt = dbConnection.prepareStatement(sqlStmt);
prepStmt.setInt(1, idPId);
prepStmt.setString(2, connectorType);
rs = prepStmt.executeQuery();
if (rs.next()) {
return rs.getInt(1);
} else {
throw new IdentityApplicationManagementException("Invalid connector type " +
connectorType);
}
} finally {
IdentityApplicationManagementUtil.closeResultSet(rs);
IdentityApplicationManagementUtil.closeStatement(prepStmt);
}
}
private InputStream setBlobValue(String value) throws SQLException {
if (value != null) {
return new ByteArrayInputStream(value.getBytes());
}
return null;
}
public List<String> getSPNamesOfProvisioningConnectorsByIDP(String idPName, int tenantId)
throws IdentityApplicationManagementException {
Connection dbConnection = IdentityDatabaseUtil.getDBConnection();
PreparedStatement prepStmt = null;
ResultSet rs = null;
List<String> spNames = new ArrayList<String>();
try {
String sqlStmt = IdentityProvisioningConstants.SQLQueries.GET_SP_NAMES_OF_PROVISIONING_CONNECTORS_BY_IDP;
prepStmt = dbConnection.prepareStatement(sqlStmt);
prepStmt.setString(1, idPName);
prepStmt.setInt(2, tenantId);
rs = prepStmt.executeQuery();
while (rs.next()) {
spNames.add(rs.getString(1));
}
} catch (SQLException e) {
String msg = "Error occurred while retrieving SP names of provisioning connectors by IDP name";
throw new IdentityApplicationManagementException(msg, e);
} finally {
if (prepStmt != null) {
IdentityApplicationManagementUtil.closeStatement(prepStmt);
}
if (rs != null) {
IdentityApplicationManagementUtil.closeResultSet(rs);
}
IdentityApplicationManagementUtil.closeConnection(dbConnection);
}
return spNames;
}
private String getLocalIdFromProvisioningEntity(ProvisioningEntity provisioningEntity) {
Map<org.wso2.carbon.identity.application.common.model.ClaimMapping, List<String>> attributeMap =
provisioningEntity.getAttributes();
if (!attributeMap.isEmpty()) {
List<String> attributeValues =
attributeMap.get(org.wso2.carbon.identity.application.common.model.ClaimMapping.build(
IdentityProvisioningConstants.ID_CLAIM_URI, null, null, false));
if (attributeValues != null && !attributeValues.isEmpty()) {
return attributeValues.get(0);
}
}
return null;
}
/**
* Get provisioned entity name by providing SCIM ID (ENTITY_LOCAL_ID)
* @param localId
* @return
* @throws IdentityApplicationManagementException
*/
public String getProvisionedEntityNameByLocalId(String localId) throws IdentityApplicationManagementException {
Connection dbConnection = null;
String sqlStmt = null;
PreparedStatement prepStmt = null;
ResultSet rs = null;
try {
dbConnection = JDBCPersistenceManager.getInstance().getDBConnection();
sqlStmt = IdentityProvisioningConstants.SQLQueries.GET_PROVISIONED_ENTITY_NAME_SQL;
prepStmt = dbConnection.prepareStatement(sqlStmt);
prepStmt.setString(1, localId);
rs = prepStmt.executeQuery();
if (rs.next()) {
return rs.getString(1);
} else {
throw new IdentityApplicationManagementException("Given Local ID :"+localId+" does not exist");
}
} catch (SQLException e) {
IdentityApplicationManagementUtil.rollBack(dbConnection);
throw new IdentityApplicationManagementException(
"Error occurred while loading Provisioned Entity Name from DB", e);
} finally {
IdentityDatabaseUtil.closeAllConnections(dbConnection, rs, prepStmt);
}
}
/**
* Applicable for only group name update
*
* @param provisioningEntity
* @throws IdentityApplicationManagementException
*/
public void updateProvisioningEntityName(ProvisioningEntity provisioningEntity) throws
IdentityApplicationManagementException {
Connection dbConnection = null;
String provisioningEntityName = null;
String entityLocalID = null;
PreparedStatement prepStmt = null;
try {
dbConnection = JDBCPersistenceManager.getInstance().getDBConnection();
String sqlStmt = IdentityProvisioningConstants.SQLQueries.UPDATE_PROVISIONED_ENTITY_NAME_SQL;
prepStmt = dbConnection.prepareStatement(sqlStmt);
provisioningEntityName = ProvisioningUtil.getAttributeValue(provisioningEntity,
IdentityProvisioningConstants.NEW_GROUP_NAME_CLAIM_URI);
entityLocalID = ProvisioningUtil.getAttributeValue(provisioningEntity,
IdentityProvisioningConstants.ID_CLAIM_URI);
prepStmt.setString(1, provisioningEntityName);
prepStmt.setString(2, entityLocalID);
prepStmt.execute();
dbConnection.commit();
} catch (SQLException e) {
IdentityApplicationManagementUtil.rollBack(dbConnection);
String msg = "Error occurred while Updating Provisioning entity name to " + provisioningEntityName +
" for Entity Local Id :" + entityLocalID;
throw new IdentityApplicationManagementException(msg, e);
} finally {
DatabaseUtil.closeAllConnections(dbConnection, prepStmt);
}
}
}