Skip to content

Commit

Permalink
Move SAML SP validation to SAMLSSOServiceProviderManager layer
Browse files Browse the repository at this point in the history
  • Loading branch information
Osara-B committed Jan 6, 2025
1 parent e78b593 commit b1c6b77
Show file tree
Hide file tree
Showing 4 changed files with 297 additions and 118 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@

package org.wso2.carbon.identity.core;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.identity.base.IdentityException;
import org.wso2.carbon.identity.core.dao.SAMLServiceProviderPersistenceManagerFactory;
import org.wso2.carbon.identity.core.dao.SAMLSSOServiceProviderDAO;
Expand All @@ -33,6 +36,7 @@ public class SAMLSSOServiceProviderManager {
new SAMLServiceProviderPersistenceManagerFactory();
SAMLSSOServiceProviderDAO serviceProviderDAO =
samlSSOPersistenceManagerFactory.getSAMLServiceProviderPersistenceManager();
private static Log LOG = LogFactory.getLog(SAMLSSOServiceProviderManager.class);

/**
* Add a saml service provider.
Expand All @@ -45,6 +49,13 @@ public class SAMLSSOServiceProviderManager {
public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int tenantId)
throws IdentityException {

validateServiceProvider(serviceProviderDO);
if (isServiceProviderExists(serviceProviderDO.getIssuer(), tenantId)) {
if (LOG.isDebugEnabled()){
LOG.debug(serviceProviderInfo(serviceProviderDO) + " already exists.");
}
return false;
}
return serviceProviderDAO.addServiceProvider(serviceProviderDO, tenantId);
}

Expand All @@ -60,6 +71,15 @@ public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, in
public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, String currentIssuer, int tenantId)
throws IdentityException {

validateServiceProvider(serviceProviderDO);
String newIssuer = serviceProviderDO.getIssuer();
boolean isIssuerUpdated = !StringUtils.equals(currentIssuer, newIssuer);
if (isIssuerUpdated && isServiceProviderExists(newIssuer, tenantId)) {
if (LOG.isDebugEnabled()) {
LOG.debug(serviceProviderInfo(serviceProviderDO) + " already exists.");
}
return false;
}
return serviceProviderDAO.updateServiceProvider(serviceProviderDO, currentIssuer, tenantId);
}

Expand Down Expand Up @@ -110,20 +130,89 @@ public boolean isServiceProviderExists(String issuer, int tenantId) throws Ident
*/
public boolean removeServiceProvider(String issuer, int tenantId) throws IdentityException {

if (issuer == null || StringUtils.isEmpty(issuer.trim())) {
throw new IllegalArgumentException("Trying to delete issuer \'" + issuer + "\'");
}
if (!isServiceProviderExists(issuer, tenantId)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Service Provider with issuer: " + issuer + " does not exist.");
}
return false;
}
return serviceProviderDAO.removeServiceProvider(issuer, tenantId);
}

/**
* Upload the SAML configuration related to the application, using metadata.
*
* @param samlssoServiceProviderDO SAML service provider information object.
* @param serviceProviderDO SAML service provider information object.
* @param tenantId Tenant ID.
* @return SAML service provider information object.
* @throws IdentityException Error when uploading the SAML configuration.
*/
public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO samlssoServiceProviderDO,
public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO,
int tenantId) throws IdentityException {

return serviceProviderDAO.uploadServiceProvider(samlssoServiceProviderDO, tenantId);
validateServiceProvider(serviceProviderDO);
if (serviceProviderDO.getDefaultAssertionConsumerUrl() == null) {
throw new IdentityException("No default assertion consumer URL provided for service provider :" +
serviceProviderDO.getIssuer());
}
if (isServiceProviderExists(serviceProviderDO.getIssuer(), tenantId)) {
if (LOG.isDebugEnabled()){
LOG.debug(serviceProviderInfo(serviceProviderDO) + " already exists.");
}
throw new IdentityException("A Service Provider already exists.");
}

return serviceProviderDAO.uploadServiceProvider(serviceProviderDO, tenantId);
}

private void validateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO) throws IdentityException {

if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null ||
StringUtils.isBlank(serviceProviderDO.getIssuer())) {
throw new IdentityException("Issuer cannot be found in the provided arguments.");
}

if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier()) &&
!serviceProviderDO.getIssuer().contains(IdentityRegistryResources.QUALIFIER_ID)) {
serviceProviderDO.setIssuer(
getIssuerWithQualifier(serviceProviderDO.getIssuer(), serviceProviderDO.getIssuerQualifier()));
}
}

private String serviceProviderInfo(SAMLSSOServiceProviderDO serviceProviderDO) {

if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) {
return "SAML2 Service Provider with issuer: " + getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) +
" and qualifier name " + serviceProviderDO.getIssuerQualifier();
} else {
return "SAML2 Service Provider with issuer: " + serviceProviderDO.getIssuer();
}
}

/**
* Get the issuer value to be added to registry by appending the qualifier.
*
* @param issuer value given as 'issuer' when configuring SAML SP.
* @return issuer value with qualifier appended.
*/
private String getIssuerWithQualifier(String issuer, String qualifier) {

return issuer + IdentityRegistryResources.QUALIFIER_ID + qualifier;
}

/**
* Get the issuer value by removing the qualifier.
*
* @param issuerWithQualifier issuer value saved in the registry.
* @return issuer value given as 'issuer' when configuring SAML SP.
*/
private String getIssuerWithoutQualifier(String issuerWithQualifier) {

String issuerWithoutQualifier = StringUtils.substringBeforeLast(issuerWithQualifier,
IdentityRegistryResources.QUALIFIER_ID);
return issuerWithoutQualifier;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -256,36 +256,11 @@ SAMLSSOServiceProviderDO buildSAMLSSOServiceProviderDAO (Resource resource) {
public boolean addServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO, int tenantId) throws IdentityException {

Registry registry = getRegistry(tenantId);
if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null ||
StringUtils.isBlank(serviceProviderDO.getIssuer())) {
throw new IdentityException("Issuer cannot be found in the provided arguments.");
}

// If an issuer qualifier value is specified, it is appended to the end of the issuer value.
if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) {
serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(),
serviceProviderDO.getIssuerQualifier()));
}

String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(serviceProviderDO.getIssuer());

boolean isTransactionStarted = Transaction.isStarted();
boolean isErrorOccurred = false;
try {
if (registry.resourceExists(path)) {
if (LOG.isDebugEnabled()) {
if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) {
LOG.debug("SAML2 Service Provider already exists with the same issuer name "
+ getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name "
+ serviceProviderDO.getIssuerQualifier());
} else {
LOG.debug("SAML2 Service Provider already exists with the same issuer name "
+ serviceProviderDO.getIssuer());
}
}
return false;
}

Resource resource = createResource(serviceProviderDO, registry);
if (!isTransactionStarted) {
registry.beginTransaction();
Expand Down Expand Up @@ -480,39 +455,13 @@ public boolean updateServiceProvider(SAMLSSOServiceProviderDO serviceProviderDO,
throws IdentityException {

Registry registry = getRegistry(tenantId);
if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null ||
StringUtils.isBlank(serviceProviderDO.getIssuer())) {
throw new IdentityException("Issuer cannot be found in the provided arguments.");
}

// If an issuer qualifier value is specified, it is appended to the end of the issuer value.
if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) {
serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(),
serviceProviderDO.getIssuerQualifier()));
}

String currentPath = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(currentIssuer);
String newPath = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(serviceProviderDO.getIssuer());

boolean isIssuerUpdated = !StringUtils.equals(currentPath, newPath);
boolean isTransactionStarted = Transaction.isStarted();
boolean isErrorOccurred = false;
try {
// Check if the updated issuer value already exists.
if (isIssuerUpdated && registry.resourceExists(newPath)) {
if (LOG.isDebugEnabled()) {
if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) {
LOG.debug("SAML2 Service Provider already exists with the same issuer name "
+ getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name "
+ serviceProviderDO.getIssuerQualifier());
} else {
LOG.debug("SAML2 Service Provider already exists with the same issuer name "
+ serviceProviderDO.getIssuer());
}
}
return false;
}

Resource resource = createResource(serviceProviderDO, registry);
if (!isTransactionStarted) {
registry.beginTransaction();
Expand Down Expand Up @@ -578,21 +527,11 @@ public SAMLSSOServiceProviderDO[] getServiceProviders(int tenantId) throws Ident
public boolean removeServiceProvider(String issuer, int tenantId) throws IdentityException {

Registry registry = getRegistry(tenantId);
if (issuer == null || StringUtils.isEmpty(issuer.trim())) {
throw new IllegalArgumentException("Trying to delete issuer \'" + issuer + "\'");
}

String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(issuer);
boolean isTransactionStarted = Transaction.isStarted();
boolean isErrorOccurred = false;
try {
if (!registry.resourceExists(path)) {
if (LOG.isDebugEnabled()) {
LOG.debug("Registry resource does not exist for the path: " + path);
}
return false;
}

// Since we are getting a global registry object, better to check whether this is a task inside already
// started transaction.
if (!isTransactionStarted) {
Expand Down Expand Up @@ -738,39 +677,11 @@ public SAMLSSOServiceProviderDO uploadServiceProvider(SAMLSSOServiceProviderDO s
throws IdentityException {

Registry registry = getRegistry(tenantId);
if (serviceProviderDO == null || serviceProviderDO.getIssuer() == null) {
throw new IdentityException("Issuer cannot be found in the provided arguments.");
}

if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) {
serviceProviderDO.setIssuer(getIssuerWithQualifier(serviceProviderDO.getIssuer(),
serviceProviderDO.getIssuerQualifier()));
}

if (serviceProviderDO.getDefaultAssertionConsumerUrl() == null) {
throw new IdentityException("No default assertion consumer URL provided for service provider :" +
serviceProviderDO.getIssuer());
}

String path = IdentityRegistryResources.SAML_SSO_SERVICE_PROVIDERS + encodePath(serviceProviderDO.getIssuer());

boolean isTransactionStarted = Transaction.isStarted();
boolean isErrorOccurred = false;
try {
if (registry.resourceExists(path)) {
if (LOG.isDebugEnabled()) {
if (StringUtils.isNotBlank(serviceProviderDO.getIssuerQualifier())) {
LOG.debug("SAML2 Service Provider already exists with the same issuer name "
+ getIssuerWithoutQualifier(serviceProviderDO.getIssuer()) + " and qualifier name "
+ serviceProviderDO.getIssuerQualifier());
} else {
LOG.debug("SAML2 Service Provider already exists with the same issuer name "
+ serviceProviderDO.getIssuer());
}
}
throw IdentityException.error("A Service Provider already exists.");
}

if (!isTransactionStarted) {
registry.beginTransaction();
}
Expand Down
Loading

0 comments on commit b1c6b77

Please sign in to comment.