diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManager.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManager.java index fc9a6db4d81..c65f8b3ad1f 100644 --- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManager.java +++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManager.java @@ -64,6 +64,9 @@ public interface SAML2AuthManager extends PluggableAPIAuthenticator, PluggableSe public static final ConfigKey SAMLSignatureAlgorithm = new ConfigKey("Advanced", String.class, "saml2.sigalg", "SHA1", "The algorithm to use to when signing a SAML request. Default is SHA1, allowed algorithms: SHA1, SHA256, SHA384, SHA512", true); + public static final ConfigKey SAMLAppendDomainSuffix = new ConfigKey("Advanced", Boolean.class, "saml2.append.idpdomain", "false", + "If enabled, create account/user dialog with SAML SSO enabled will append the IdP domain to the user or account name in the UI dialog", true); + public static final ConfigKey SAMLTimeout = new ConfigKey("Advanced", Integer.class, "saml2.timeout", "1800", "SAML2 IDP Metadata refresh interval in seconds, minimum value is set to 300", true); diff --git a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java index 185955c3384..7232ac9e074 100644 --- a/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java +++ b/plugins/user-authenticators/saml2/src/org/apache/cloudstack/saml/SAML2AuthManagerImpl.java @@ -514,6 +514,6 @@ public class SAML2AuthManagerImpl extends AdapterBase implements SAML2AuthManage SAMLServiceProviderSingleSignOnURL, SAMLServiceProviderSingleLogOutURL, SAMLCloudStackRedirectionUrl, SAMLUserAttributeName, SAMLIdentityProviderMetadataURL, SAMLDefaultIdentityProviderId, - SAMLSignatureAlgorithm, SAMLTimeout}; + SAMLSignatureAlgorithm, SAMLAppendDomainSuffix, SAMLTimeout}; } } diff --git a/ui/scripts/accounts.js b/ui/scripts/accounts.js index b63d184b0e8..07cc6f772ae 100644 --- a/ui/scripts/accounts.js +++ b/ui/scripts/accounts.js @@ -148,6 +148,23 @@ }); } }); + + // SAML: Check Append Domain Setting + if (g_idpList) { + $.ajax({ + type: 'GET', + url: createURL('listConfigurations&name=saml2.append.idpdomain'), + dataType: 'json', + async: false, + success: function(data, textStatus, xhr) { + if (data && data.listconfigurationsresponse && data.listconfigurationsresponse.configuration) { + g_appendIdpDomain = (data.listconfigurationsresponse.configuration[0].value === 'true'); + } + }, + error: function(xhr) { + }, + }); + } }, detailView: { @@ -1061,6 +1078,68 @@ data: items }); } + }, + samlEnable: { + label: 'label.saml.enable', + docID: 'helpSamlEnable', + isBoolean: true, + validation: { + required: false + }, + isHidden: function (args) { + if (g_idpList) return false; + return true; + } + }, + samlEntity: { + label: 'label.saml.entity', + docID: 'helpSamlEntity', + validation: { + required: false + }, + select: function(args) { + var samlChecked = false; + var idpUrl = ""; + var appendDomainToUsername = function() { + if (!g_appendIdpDomain) { + return; + } + var username = $('input[name=username]').val(); + if (username) { + username = username.split('@')[0]; + } + if (samlChecked) { + var link = document.createElement('a'); + link.setAttribute('href', idpUrl); + $('input[name=username]').val(username + "@" + link.host.split('.').splice(-2).join('.')); + } else { + $('input[name=username]').val(username); + } + }; + args.$form.find('select[name=samlEntity]').change(function() { + idpUrl = $(this).children(':selected').val(); + appendDomainToUsername(); + }); + args.$form.find('input[name=samlEnable]').change(function() { + samlChecked = $(this).context.checked; + appendDomainToUsername(); + }); + + var items = []; + $(g_idpList).each(function() { + items.push({ + id: this.id, + description: this.orgName + }); + }); + args.response.success({ + data: items + }); + }, + isHidden: function (args) { + if (g_idpList) return false; + return true; + } } } }, @@ -1098,12 +1177,30 @@ accounttype: accountObj.accounttype }); + + var authorizeUsersForSamlSSO = function (users, entity) { + for (var i = 0; i < users.length; i++) { + $.ajax({ + url: createURL('authorizeSamlSso&enable=true&userid=' + users[i].id + "&entityid=" + entity), + error: function(XMLHttpResponse) { + args.response.error(parseXMLHttpResponse(XMLHttpResponse)); + } + }); + } + return; + }; + $.ajax({ url: createURL('createUser'), type: "POST", data: data, success: function(json) { var item = json.createuserresponse.user; + if (args.data.samlEnable && args.data.samlEnable === 'on') { + var entity = args.data.samlEntity; + if (item && entity) + authorizeUsersForSamlSSO([item], entity); + } args.response.success({ data: item }); diff --git a/ui/scripts/accountsWizard.js b/ui/scripts/accountsWizard.js index 7ea5eaa28b8..3efe6f91f18 100644 --- a/ui/scripts/accountsWizard.js +++ b/ui/scripts/accountsWizard.js @@ -16,8 +16,9 @@ // under the License. (function(cloudStack, $) { - var rootDomainId; - + var rootDomainId; + + cloudStack.accountsWizard = { informationWithinLdap: { @@ -178,6 +179,33 @@ required: false }, select: function(args) { + var samlChecked = false; + var idpUrl = ""; + var appendDomainToUsername = function() { + if (!g_appendIdpDomain) { + return; + } + var username = $('input[name=username]').val(); + if (username) { + username = username.split('@')[0]; + } + if (samlChecked) { + var link = document.createElement('a'); + link.setAttribute('href', idpUrl); + $('input[name=username]').val(username + "@" + link.host.split('.').splice(-2).join('.')); + } else { + $('input[name=username]').val(username); + } + }; + args.$form.find('select[name=samlEntity]').change(function() { + idpUrl = $(this).children(':selected').val(); + appendDomainToUsername(); + }); + args.$form.find('input[name=samlEnable]').change(function() { + samlChecked = $(this).context.checked; + appendDomainToUsername(); + }); + var items = []; $(g_idpList).each(function() { items.push({ diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index 14cd0f35b30..2dc19d94dcc 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -33,6 +33,7 @@ var g_userPublicTemplateEnabled = "true"; var g_cloudstackversion = null; var g_queryAsyncJobResultInterval = 3000; var g_idpList = null; +var g_appendIdpDomain = false; //keyboard keycode var keycode_Enter = 13;