diff --git a/awx/sso/conf.py b/awx/sso/conf.py index 15db4f2cd8..e2c15c96fa 100644 --- a/awx/sso/conf.py +++ b/awx/sso/conf.py @@ -1185,7 +1185,7 @@ register( field_class=fields.SAMLTeamAttrField, allow_null=True, default=None, - label=_('SAML Team Map'), + label=_('SAML Team Attribute Mapping'), help_text=_('Used to translate user team membership into Tower.'), category=_('SAML'), category_slug='saml', diff --git a/awx/ui/client/src/configuration/auth-form/configuration-auth.controller.js b/awx/ui/client/src/configuration/auth-form/configuration-auth.controller.js index 5cd9e72a11..5b80e40ddb 100644 --- a/awx/ui/client/src/configuration/auth-form/configuration-auth.controller.js +++ b/awx/ui/client/src/configuration/auth-form/configuration-auth.controller.js @@ -17,6 +17,11 @@ export default [ 'configurationGithubTeamForm', 'configurationGoogleForm', 'configurationLdapForm', + 'configurationLdap1Form', + 'configurationLdap2Form', + 'configurationLdap3Form', + 'configurationLdap4Form', + 'configurationLdap5Form', 'configurationRadiusForm', 'configurationTacacsForm', 'configurationSamlForm', @@ -39,6 +44,11 @@ export default [ configurationGithubTeamForm, configurationGoogleForm, configurationLdapForm, + configurationLdap1Form, + configurationLdap2Form, + configurationLdap3Form, + configurationLdap4Form, + configurationLdap5Form, configurationRadiusForm, configurationTacacsForm, configurationSamlForm, @@ -55,6 +65,8 @@ export default [ var formTracker = $scope.$parent.vm.formTracker; var dropdownValue = 'azure'; var activeAuthForm = 'azure'; + var ldapDropdownValue = ''; + let codeInputInitialized = false; // Default active form @@ -62,10 +74,16 @@ export default [ formTracker.setCurrentAuth(activeAuthForm); } - var activeForm = function() { + const getActiveAuthForm = () => { + if (authVm.dropdownValue === 'ldap') { + return `ldap${authVm.ldapDropdownValue}`; + } + return authVm.dropdownValue; + }; + var activeForm = function() { if(!$scope.$parent[formTracker.currentFormName()].$dirty) { - authVm.activeAuthForm = authVm.dropdownValue; + authVm.activeAuthForm = getActiveAuthForm(); formTracker.setCurrentAuth(authVm.activeAuthForm); startCodeMirrors(); } else { @@ -78,7 +96,7 @@ export default [ onClick: function() { $scope.$parent.vm.populateFromApi(); $scope.$parent[formTracker.currentFormName()].$setPristine(); - authVm.activeAuthForm = authVm.dropdownValue; + authVm.activeAuthForm = getActiveAuthForm(); formTracker.setCurrentAuth(authVm.activeAuthForm); $('#FormModal-dialog').dialog('close'); } @@ -89,7 +107,7 @@ export default [ .then(function() { $scope.$parent[formTracker.currentFormName()].$setPristine(); $scope.$parent.vm.populateFromApi(); - authVm.activeAuthForm = authVm.dropdownValue; + authVm.activeAuthForm = getActiveAuthForm(); formTracker.setCurrentAuth(authVm.activeAuthForm); $('#FormModal-dialog').dialog('close'); }); @@ -100,11 +118,12 @@ export default [ $scope.$parent.vm.triggerModal(msg, title, buttons); } formTracker.setCurrentAuth(authVm.activeAuthForm); + authVm.ldapSelected = (authVm.activeAuthForm.indexOf('ldap') !== -1); }; var dropdownOptions = [ {label: i18n._('Azure AD'), value: 'azure'}, - {label: i18n._('GitHub'), value: 'github'}, + {label: i18n._('GitHub'), value: 'github'}, {label: i18n._('GitHub Org'), value: 'github_org'}, {label: i18n._('GitHub Team'), value: 'github_team'}, {label: i18n._('Google OAuth2'), value: 'google_oauth'}, @@ -114,48 +133,97 @@ export default [ {label: i18n._('TACACS+'), value: 'tacacs'} ]; + var ldapDropdownOptions = [ + {label: i18n._('Default'), value: ''}, + {label: i18n._('LDAP 1 (Optional)'), value: '1'}, + {label: i18n._('LDAP 2 (Optional)'), value: '2'}, + {label: i18n._('LDAP 3 (Optional)'), value: '3'}, + {label: i18n._('LDAP 4 (Optional)'), value: '4'}, + {label: i18n._('LDAP 5 (Optional)'), value: '5'}, + ]; + CreateSelect2({ element: '#configure-dropdown-nav', multiple: false, }); - var authForms = [{ + CreateSelect2({ + element: '#configure-ldap-dropdown', + multiple: false, + }); + + var authForms = [ + { formDef: configurationAzureForm, id: 'auth-azure-form', name: 'azure' - }, { + }, + { formDef: configurationGithubForm, id: 'auth-github-form', name: 'github' - }, { + }, + { formDef: configurationGithubOrgForm, id: 'auth-github-org-form', name: 'github_org' - }, { + }, + { formDef: configurationGithubTeamForm, id: 'auth-github-team-form', name: 'github_team' - }, { + }, + { formDef: configurationGoogleForm, id: 'auth-google-form', name: 'google_oauth' - }, { - formDef: configurationLdapForm, - id: 'auth-ldap-form', - name: 'ldap' - }, { + }, + { formDef: configurationRadiusForm, id: 'auth-radius-form', name: 'radius' - }, { + }, + { formDef: configurationTacacsForm, id: 'auth-tacacs-form', name: 'tacacs' - }, { + }, + { formDef: configurationSamlForm, id: 'auth-saml-form', name: 'saml' - }, ]; + }, + { + formDef: configurationLdapForm, + id: 'auth-ldap-form', + name: 'ldap' + }, + { + formDef: configurationLdap1Form, + id: 'auth-ldap1-form', + name: 'ldap1' + }, + { + formDef: configurationLdap2Form, + id: 'auth-ldap2-form', + name: 'ldap2' + }, + { + formDef: configurationLdap3Form, + id: 'auth-ldap3-form', + name: 'ldap3' + }, + { + formDef: configurationLdap4Form, + id: 'auth-ldap4-form', + name: 'ldap4' + }, + { + formDef: configurationLdap5Form, + id: 'auth-ldap5-form', + name: 'ldap5' + }, + ]; var forms = _.pluck(authForms, 'formDef'); _.each(forms, function(form) { @@ -179,10 +247,8 @@ export default [ form.buttons.save.disabled = $rootScope.user_is_system_auditor; }); - function startCodeMirrors(key){ - var form = _.find(authForms, function(f){ - return f.name === $scope.authVm.activeAuthForm; - }); + function startCodeMirrors(key) { + var form = _.find(authForms, f => f.name === $scope.authVm.activeAuthForm); if(!key){ // Attach codemirror to fields that need it @@ -246,9 +312,23 @@ export default [ // Flag to avoid re-rendering and breaking Select2 dropdowns on tab switching var dropdownRendered = false; - function populateLDAPGroupType(flag){ - if($scope.$parent.AUTH_LDAP_GROUP_TYPE !== null) { - $scope.$parent.AUTH_LDAP_GROUP_TYPE = _.find($scope.$parent.AUTH_LDAP_GROUP_TYPE_options, { value: $scope.$parent.AUTH_LDAP_GROUP_TYPE }); + function populateLDAPGroupType(flag, index = null){ + let groupPropName; + let groupOptionsPropName; + let selectElementId; + + if (index) { + groupPropName = `AUTH_LDAP_${index}_GROUP_TYPE`; + groupOptionsPropName = `${groupPropName}_options`; + selectElementId = `#configuration_ldap${index}_template_${groupPropName}`; + } else { + groupPropName = 'AUTH_LDAP_GROUP_TYPE'; + groupOptionsPropName = `${groupPropName}_options`; + selectElementId = `#configuration_ldap_template_${groupPropName}`; + } + + if($scope.$parent[groupPropName] !== null) { + $scope.$parent[groupPropName] = _.find($scope[groupOptionsPropName], { value: $scope.$parent[groupPropName] }); } if(flag !== undefined){ @@ -258,7 +338,7 @@ export default [ if(!dropdownRendered) { dropdownRendered = true; CreateSelect2({ - element: '#configuration_ldap_template_AUTH_LDAP_GROUP_TYPE', + element: selectElementId, multiple: false, placeholder: i18n._('Select group types'), }); @@ -284,13 +364,12 @@ export default [ } } - $scope.$on('AUTH_LDAP_GROUP_TYPE_populated', function(e, data, flag) { - populateLDAPGroupType(flag); - }); - - $scope.$on('TACACSPLUS_AUTH_PROTOCOL_populated', function(e, data, flag) { - populateTacacsProtocol(flag); - }); + $scope.$on('AUTH_LDAP_GROUP_TYPE_populated', (e, data, flag) => populateLDAPGroupType(flag)); + $scope.$on('AUTH_LDAP_1_GROUP_TYPE_populated', (e, data, flag) => populateLDAPGroupType(flag, 1)); + $scope.$on('AUTH_LDAP_2_GROUP_TYPE_populated', (e, data, flag) => populateLDAPGroupType(flag, 2)); + $scope.$on('AUTH_LDAP_3_GROUP_TYPE_populated', (e, data, flag) => populateLDAPGroupType(flag, 3)); + $scope.$on('AUTH_LDAP_4_GROUP_TYPE_populated', (e, data, flag) => populateLDAPGroupType(flag, 4)); + $scope.$on('AUTH_LDAP_5_GROUP_TYPE_populated', (e, data, flag) => populateLDAPGroupType(flag, 5)); $scope.$on('$locationChangeStart', (event, url) => { let parts = url.split('/'); @@ -311,6 +390,12 @@ export default [ } populateLDAPGroupType(false); + populateLDAPGroupType(false, 1); + populateLDAPGroupType(false, 2); + populateLDAPGroupType(false, 3); + populateLDAPGroupType(false, 4); + populateLDAPGroupType(false, 5); + populateTacacsProtocol(false); }); @@ -328,7 +413,9 @@ export default [ activeAuthForm: activeAuthForm, authForms: authForms, dropdownOptions: dropdownOptions, - dropdownValue: dropdownValue + dropdownValue: dropdownValue, + ldapDropdownValue: ldapDropdownValue, + ldapDropdownOptions: ldapDropdownOptions, }); } ]; diff --git a/awx/ui/client/src/configuration/auth-form/configuration-auth.partial.html b/awx/ui/client/src/configuration/auth-form/configuration-auth.partial.html index e1ffb3d9f4..2bfa19b401 100644 --- a/awx/ui/client/src/configuration/auth-form/configuration-auth.partial.html +++ b/awx/ui/client/src/configuration/auth-form/configuration-auth.partial.html @@ -1,63 +1,89 @@
+
Sub Category
- + +
+ +
+
LDAP Server
+
+ +
-
-
-
-
-
-
-
-
+
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
-
-
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap1.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap1.form.js new file mode 100644 index 0000000000..8430fecee3 --- /dev/null +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap1.form.js @@ -0,0 +1,108 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +export default ['i18n', function(i18n) { + return { + // editTitle: 'Authorization Configuration', + name: 'configuration_ldap1_template', + showActions: true, + showHeader: false, + + fields: { + AUTH_LDAP_1_SERVER_URI: { + type: 'text', + reset: 'AUTH_LDAP_1_SERVER_URI' + }, + AUTH_LDAP_1_BIND_DN: { + type: 'text', + reset: 'AUTH_LDAP_1_BIND_DN' + }, + AUTH_LDAP_1_BIND_PASSWORD: { + type: 'sensitive', + hasShowInputButton: true, + }, + AUTH_LDAP_1_USER_SEARCH: { + type: 'textarea', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + reset: 'AUTH_LDAP_1_USER_SEARCH' + }, + AUTH_LDAP_1_GROUP_SEARCH: { + type: 'textarea', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + reset: 'AUTH_LDAP_1_GROUP_SEARCH' + }, + AUTH_LDAP_1_USER_DN_TEMPLATE: { + type: 'text', + reset: 'AUTH_LDAP_1_USER_DN_TEMPLATE' + }, + AUTH_LDAP_1_USER_ATTR_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_1_USER_ATTR_MAP', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_1_GROUP_TYPE: { + type: 'select', + reset: 'AUTH_LDAP_1_GROUP_TYPE', + ngOptions: 'group.label for group in AUTH_LDAP_1_GROUP_TYPE_options track by group.value', + }, + AUTH_LDAP_1_REQUIRE_GROUP: { + type: 'text', + reset: 'AUTH_LDAP_1_REQUIRE_GROUP' + }, + AUTH_LDAP_1_DENY_GROUP: { + type: 'text', + reset: 'AUTH_LDAP_1_DENY_GROUP' + }, + AUTH_LDAP_1_START_TLS: { + type: 'toggleSwitch' + }, + AUTH_LDAP_1_USER_FLAGS_BY_GROUP: { + type: 'textarea', + reset: 'AUTH_LDAP_1_USER_FLAGS_BY_GROUP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_1_ORGANIZATION_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_1_ORGANIZATION_MAP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_1_TEAM_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_1_TEAM_MAP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + } + }, + + buttons: { + reset: { + ngShow: '!user_is_system_auditor', + ngClick: 'vm.resetAllConfirm()', + label: i18n._('Revert all to default'), + class: 'Form-resetAll' + }, + cancel: { + ngClick: 'vm.formCancel()', + }, + save: { + ngClick: 'vm.formSave()', + ngDisabled: "!ldap_auth || configuration_ldap1_template_form.$invalid || configuration_ldap1_template_form.$pending" + } + } + }; +} +]; diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap2.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap2.form.js new file mode 100644 index 0000000000..09230cb802 --- /dev/null +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap2.form.js @@ -0,0 +1,108 @@ +/************************************************* + * Copyright (c) 2018 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +export default ['i18n', function(i18n) { + return { + // editTitle: 'Authorization Configuration', + name: 'configuration_ldap2_template', + showActions: true, + showHeader: false, + + fields: { + AUTH_LDAP_2_SERVER_URI: { + type: 'text', + reset: 'AUTH_LDAP_2_SERVER_URI' + }, + AUTH_LDAP_2_BIND_DN: { + type: 'text', + reset: 'AUTH_LDAP_2_BIND_DN' + }, + AUTH_LDAP_2_BIND_PASSWORD: { + type: 'sensitive', + hasShowInputButton: true, + }, + AUTH_LDAP_2_USER_SEARCH: { + type: 'textarea', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + reset: 'AUTH_LDAP_2_USER_SEARCH' + }, + AUTH_LDAP_2_GROUP_SEARCH: { + type: 'textarea', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + reset: 'AUTH_LDAP_2_GROUP_SEARCH' + }, + AUTH_LDAP_2_USER_DN_TEMPLATE: { + type: 'text', + reset: 'AUTH_LDAP_2_USER_DN_TEMPLATE' + }, + AUTH_LDAP_2_USER_ATTR_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_2_USER_ATTR_MAP', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_2_GROUP_TYPE: { + type: 'select', + reset: 'AUTH_LDAP_2_GROUP_TYPE', + ngOptions: 'group.label for group in AUTH_LDAP_2_GROUP_TYPE_options track by group.value', + }, + AUTH_LDAP_2_REQUIRE_GROUP: { + type: 'text', + reset: 'AUTH_LDAP_2_REQUIRE_GROUP' + }, + AUTH_LDAP_2_DENY_GROUP: { + type: 'text', + reset: 'AUTH_LDAP_2_DENY_GROUP' + }, + AUTH_LDAP_2_START_TLS: { + type: 'toggleSwitch' + }, + AUTH_LDAP_2_USER_FLAGS_BY_GROUP: { + type: 'textarea', + reset: 'AUTH_LDAP_2_USER_FLAGS_BY_GROUP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_2_ORGANIZATION_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_2_ORGANIZATION_MAP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_2_TEAM_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_2_TEAM_MAP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + } + }, + + buttons: { + reset: { + ngShow: '!user_is_system_auditor', + ngClick: 'vm.resetAllConfirm()', + label: i18n._('Revert all to default'), + class: 'Form-resetAll' + }, + cancel: { + ngClick: 'vm.formCancel()', + }, + save: { + ngClick: 'vm.formSave()', + ngDisabled: "!ldap_auth || configuration_ldap2_template_form.$invalid || configuration_ldap2_template_form.$pending" + } + } + }; +} +]; diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap3.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap3.form.js new file mode 100644 index 0000000000..9c26c22829 --- /dev/null +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap3.form.js @@ -0,0 +1,108 @@ +/************************************************* + * Copyright (c) 2018 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +export default ['i18n', function(i18n) { + return { + // editTitle: 'Authorization Configuration', + name: 'configuration_ldap3_template', + showActions: true, + showHeader: false, + + fields: { + AUTH_LDAP_3_SERVER_URI: { + type: 'text', + reset: 'AUTH_LDAP_3_SERVER_URI' + }, + AUTH_LDAP_3_BIND_DN: { + type: 'text', + reset: 'AUTH_LDAP_3_BIND_DN' + }, + AUTH_LDAP_3_BIND_PASSWORD: { + type: 'sensitive', + hasShowInputButton: true, + }, + AUTH_LDAP_3_USER_SEARCH: { + type: 'textarea', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + reset: 'AUTH_LDAP_3_USER_SEARCH' + }, + AUTH_LDAP_3_GROUP_SEARCH: { + type: 'textarea', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + reset: 'AUTH_LDAP_3_GROUP_SEARCH' + }, + AUTH_LDAP_3_USER_DN_TEMPLATE: { + type: 'text', + reset: 'AUTH_LDAP_3_USER_DN_TEMPLATE' + }, + AUTH_LDAP_3_USER_ATTR_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_3_USER_ATTR_MAP', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_3_GROUP_TYPE: { + type: 'select', + reset: 'AUTH_LDAP_3_GROUP_TYPE', + ngOptions: 'group.label for group in AUTH_LDAP_3_GROUP_TYPE_options track by group.value', + }, + AUTH_LDAP_3_REQUIRE_GROUP: { + type: 'text', + reset: 'AUTH_LDAP_3_REQUIRE_GROUP' + }, + AUTH_LDAP_3_DENY_GROUP: { + type: 'text', + reset: 'AUTH_LDAP_3_DENY_GROUP' + }, + AUTH_LDAP_3_START_TLS: { + type: 'toggleSwitch' + }, + AUTH_LDAP_3_USER_FLAGS_BY_GROUP: { + type: 'textarea', + reset: 'AUTH_LDAP_3_USER_FLAGS_BY_GROUP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_3_ORGANIZATION_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_3_ORGANIZATION_MAP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_3_TEAM_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_3_TEAM_MAP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + } + }, + + buttons: { + reset: { + ngShow: '!user_is_system_auditor', + ngClick: 'vm.resetAllConfirm()', + label: i18n._('Revert all to default'), + class: 'Form-resetAll' + }, + cancel: { + ngClick: 'vm.formCancel()', + }, + save: { + ngClick: 'vm.formSave()', + ngDisabled: "!ldap_auth || configuration_ldap3_template_form.$invalid || configuration_ldap3_template_form.$pending" + } + } + }; +} +]; diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap4.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap4.form.js new file mode 100644 index 0000000000..95c9f6d175 --- /dev/null +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap4.form.js @@ -0,0 +1,108 @@ +/************************************************* + * Copyright (c) 2018 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +export default ['i18n', function(i18n) { + return { + // editTitle: 'Authorization Configuration', + name: 'configuration_ldap4_template', + showActions: true, + showHeader: false, + + fields: { + AUTH_LDAP_4_SERVER_URI: { + type: 'text', + reset: 'AUTH_LDAP_4_SERVER_URI' + }, + AUTH_LDAP_4_BIND_DN: { + type: 'text', + reset: 'AUTH_LDAP_4_BIND_DN' + }, + AUTH_LDAP_4_BIND_PASSWORD: { + type: 'sensitive', + hasShowInputButton: true, + }, + AUTH_LDAP_4_USER_SEARCH: { + type: 'textarea', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + reset: 'AUTH_LDAP_4_USER_SEARCH' + }, + AUTH_LDAP_4_GROUP_SEARCH: { + type: 'textarea', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + reset: 'AUTH_LDAP_4_GROUP_SEARCH' + }, + AUTH_LDAP_4_USER_DN_TEMPLATE: { + type: 'text', + reset: 'AUTH_LDAP_4_USER_DN_TEMPLATE' + }, + AUTH_LDAP_4_USER_ATTR_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_4_USER_ATTR_MAP', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_4_GROUP_TYPE: { + type: 'select', + reset: 'AUTH_LDAP_4_GROUP_TYPE', + ngOptions: 'group.label for group in AUTH_LDAP_4_GROUP_TYPE_options track by group.value', + }, + AUTH_LDAP_4_REQUIRE_GROUP: { + type: 'text', + reset: 'AUTH_LDAP_4_REQUIRE_GROUP' + }, + AUTH_LDAP_4_DENY_GROUP: { + type: 'text', + reset: 'AUTH_LDAP_4_DENY_GROUP' + }, + AUTH_LDAP_4_START_TLS: { + type: 'toggleSwitch' + }, + AUTH_LDAP_4_USER_FLAGS_BY_GROUP: { + type: 'textarea', + reset: 'AUTH_LDAP_4_USER_FLAGS_BY_GROUP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_4_ORGANIZATION_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_4_ORGANIZATION_MAP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_4_TEAM_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_4_TEAM_MAP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + } + }, + + buttons: { + reset: { + ngShow: '!user_is_system_auditor', + ngClick: 'vm.resetAllConfirm()', + label: i18n._('Revert all to default'), + class: 'Form-resetAll' + }, + cancel: { + ngClick: 'vm.formCancel()', + }, + save: { + ngClick: 'vm.formSave()', + ngDisabled: "!ldap_auth || configuration_ldap4_template_form.$invalid || configuration_ldap4_template_form.$pending" + } + } + }; +} +]; diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap5.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap5.form.js new file mode 100644 index 0000000000..fa93437367 --- /dev/null +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-ldap5.form.js @@ -0,0 +1,108 @@ +/************************************************* + * Copyright (c) 2018 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +export default ['i18n', function(i18n) { + return { + // editTitle: 'Authorization Configuration', + name: 'configuration_ldap5_template', + showActions: true, + showHeader: false, + + fields: { + AUTH_LDAP_5_SERVER_URI: { + type: 'text', + reset: 'AUTH_LDAP_5_SERVER_URI' + }, + AUTH_LDAP_5_BIND_DN: { + type: 'text', + reset: 'AUTH_LDAP_5_BIND_DN' + }, + AUTH_LDAP_5_BIND_PASSWORD: { + type: 'sensitive', + hasShowInputButton: true, + }, + AUTH_LDAP_5_USER_SEARCH: { + type: 'textarea', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + reset: 'AUTH_LDAP_5_USER_SEARCH' + }, + AUTH_LDAP_5_GROUP_SEARCH: { + type: 'textarea', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + reset: 'AUTH_LDAP_5_GROUP_SEARCH' + }, + AUTH_LDAP_5_USER_DN_TEMPLATE: { + type: 'text', + reset: 'AUTH_LDAP_5_USER_DN_TEMPLATE' + }, + AUTH_LDAP_5_USER_ATTR_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_5_USER_ATTR_MAP', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_5_GROUP_TYPE: { + type: 'select', + reset: 'AUTH_LDAP_5_GROUP_TYPE', + ngOptions: 'group.label for group in AUTH_LDAP_5_GROUP_TYPE_options track by group.value', + }, + AUTH_LDAP_5_REQUIRE_GROUP: { + type: 'text', + reset: 'AUTH_LDAP_5_REQUIRE_GROUP' + }, + AUTH_LDAP_5_DENY_GROUP: { + type: 'text', + reset: 'AUTH_LDAP_5_DENY_GROUP' + }, + AUTH_LDAP_5_START_TLS: { + type: 'toggleSwitch' + }, + AUTH_LDAP_5_USER_FLAGS_BY_GROUP: { + type: 'textarea', + reset: 'AUTH_LDAP_5_USER_FLAGS_BY_GROUP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_5_ORGANIZATION_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_5_ORGANIZATION_MAP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + AUTH_LDAP_5_TEAM_MAP: { + type: 'textarea', + reset: 'AUTH_LDAP_5_TEAM_MAP', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + } + }, + + buttons: { + reset: { + ngShow: '!user_is_system_auditor', + ngClick: 'vm.resetAllConfirm()', + label: i18n._('Revert all to default'), + class: 'Form-resetAll' + }, + cancel: { + ngClick: 'vm.formCancel()', + }, + save: { + ngClick: 'vm.formSave()', + ngDisabled: "!ldap_auth || configuration_ldap5_template_form.$invalid || configuration_ldap5_template_form.$pending" + } + } + }; +} +]; diff --git a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-saml.form.js b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-saml.form.js index c7c8cc289d..ad103461f9 100644 --- a/awx/ui/client/src/configuration/auth-form/sub-forms/auth-saml.form.js +++ b/awx/ui/client/src/configuration/auth-form/sub-forms/auth-saml.form.js @@ -71,15 +71,49 @@ export default ['i18n', function(i18n) { codeMirror: true, class: 'Form-textAreaLabel Form-formGroup--fullWidth' }, + SOCIAL_AUTH_SAML_ORGANIZATION_ATTR: { + type: 'textarea', + reset: 'SOCIAL_AUTH_SAML_ORGANIZATION_ATTR', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth' + }, SOCIAL_AUTH_SAML_TEAM_MAP: { type: 'textarea', reset: 'SOCIAL_AUTH_SAML_TEAM_MAP', rows: 6, codeMirror: true, class: 'Form-textAreaLabel Form-formGroup--fullWidth' - } + }, + SOCIAL_AUTH_SAML_TEAM_ATTR: { + type: 'textarea', + reset: 'SOCIAL_AUTH_SAML_TEAM_ATTR', + rows: 6, + codeMirror: true, + class: 'Form-textAreaLabel Form-formGroup--fullWidth' + }, + SOCIAL_AUTH_SAML_SECURITY_CONFIG: { + type: 'textarea', + reset: 'SOCIAL_AUTH_SAML_SECURITY_CONFIG', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + SOCIAL_AUTH_SAML_SP_EXTRA: { + type: 'textarea', + reset: 'SOCIAL_AUTH_SAML_SP_EXTRA', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, + SOCIAL_AUTH_SAML_EXTRA_DATA: { + type: 'textarea', + reset: 'SOCIAL_AUTH_SAML_EXTRA_DATA', + codeMirror: true, + rows: 6, + class: 'Form-textAreaLabel Form-formGroup--fullWidth', + }, }, - buttons: { reset: { ngShow: '!user_is_system_auditor', diff --git a/awx/ui/client/src/configuration/configuration.block.less b/awx/ui/client/src/configuration/configuration.block.less index bc6f4faa38..7cba028ef9 100644 --- a/awx/ui/client/src/configuration/configuration.block.less +++ b/awx/ui/client/src/configuration/configuration.block.less @@ -38,6 +38,13 @@ justify-content: flex-end; } +.Form-nav--ldapDropdownContainer { + align-items: center; + width: 100%; + margin: 0 0 auto auto; + display: flex; +} + .Form-nav--dropdown { width: 285px; } @@ -166,3 +173,7 @@ input#filePickerText { .LogAggregator-failedNotification{ max-width: 300px; } + +hr { + height: 1px; +} diff --git a/awx/ui/client/src/configuration/configuration.controller.js b/awx/ui/client/src/configuration/configuration.controller.js index 8fbf100eaa..fec8c23227 100644 --- a/awx/ui/client/src/configuration/configuration.controller.js +++ b/awx/ui/client/src/configuration/configuration.controller.js @@ -15,6 +15,11 @@ export default [ 'configurationGithubTeamForm', 'configurationGoogleForm', 'configurationLdapForm', + 'configurationLdap1Form', + 'configurationLdap2Form', + 'configurationLdap3Form', + 'configurationLdap4Form', + 'configurationLdap5Form', 'configurationRadiusForm', 'configurationTacacsForm', 'configurationSamlForm', @@ -34,6 +39,11 @@ export default [ configurationGithubTeamForm, configurationGoogleForm, configurationLdapForm, + configurationLdap1Form, + configurationLdap2Form, + configurationLdap3Form, + configurationLdap4Form, + configurationLdap5Form, configurationRadiusForm, configurationTacacsForm, configurationSamlForm, @@ -52,6 +62,11 @@ export default [ 'github_team': configurationGithubTeamForm, 'google_oauth': configurationGoogleForm, 'ldap': configurationLdapForm, + 'ldap1': configurationLdap1Form, + 'ldap2': configurationLdap2Form, + 'ldap3': configurationLdap3Form, + 'ldap4': configurationLdap4Form, + 'ldap5': configurationLdap5Form, 'radius': configurationRadiusForm, 'tacacs': configurationTacacsForm, 'saml': configurationSamlForm, @@ -85,9 +100,14 @@ export default [ // the ConfigurationUtils.arrayToList() // does a string.split(', ') w/ an extra space // behind the comma. + + const isLdap = (key.indexOf("AUTH_LDAP") !== -1); + const isLdapUserSearch = isLdap && (key.indexOf("USER_SEARCH") !== -1); + const isLdapGroupSearch = isLdap && (key.indexOf("GROUP_SEARCH") !== -1); + if(key === "AD_HOC_COMMANDS"){ $scope[key] = data[key]; - } else if (key === "AUTH_LDAP_USER_SEARCH" || key === "AUTH_LDAP_GROUP_SEARCH") { + } else if (isLdapUserSearch || isLdapGroupSearch) { $scope[key] = JSON.stringify(data[key]); } else { $scope[key] = ConfigurationUtils.arrayToList(data[key], key); @@ -339,7 +359,12 @@ export default [ $scope.$broadcast(key+'_reverted'); } else if($scope[key + '_field'].hasOwnProperty('codeMirror')){ - if (key === "AUTH_LDAP_USER_SEARCH" || key === "AUTH_LDAP_GROUP_SEARCH") { + const isLdap = (key.indexOf("AUTH_LDAP") !== -1); + + const isLdapUserSearch = isLdap && (key.indexOf("USER_SEARCH") !== -1); + const isLdapGroupSearch = isLdap && (key.indexOf("GROUP_SEARCH") !== -1); + + if (isLdapUserSearch || isLdapGroupSearch) { $scope[key] = '[]'; } else { $scope[key] = '{}'; diff --git a/awx/ui/client/src/configuration/main.js b/awx/ui/client/src/configuration/main.js index 40715249b1..3846354546 100644 --- a/awx/ui/client/src/configuration/main.js +++ b/awx/ui/client/src/configuration/main.js @@ -17,6 +17,11 @@ import configurationGithubOrgForm from './auth-form/sub-forms/auth-github-org.fo import configurationGithubTeamForm from './auth-form/sub-forms/auth-github-team.form'; import configurationGoogleForm from './auth-form/sub-forms/auth-google-oauth2.form'; import configurationLdapForm from './auth-form/sub-forms/auth-ldap.form.js'; +import configurationLdap1Form from './auth-form/sub-forms/auth-ldap1.form.js'; +import configurationLdap2Form from './auth-form/sub-forms/auth-ldap2.form.js'; +import configurationLdap3Form from './auth-form/sub-forms/auth-ldap3.form.js'; +import configurationLdap4Form from './auth-form/sub-forms/auth-ldap4.form.js'; +import configurationLdap5Form from './auth-form/sub-forms/auth-ldap5.form.js'; import configurationRadiusForm from './auth-form/sub-forms/auth-radius.form.js'; import configurationTacacsForm from './auth-form/sub-forms/auth-tacacs.form.js'; import configurationSamlForm from './auth-form/sub-forms/auth-saml.form'; @@ -39,6 +44,11 @@ angular.module('configuration', []) .factory('configurationGithubTeamForm', configurationGithubTeamForm) .factory('configurationGoogleForm', configurationGoogleForm) .factory('configurationLdapForm', configurationLdapForm) + .factory('configurationLdap1Form', configurationLdap1Form) + .factory('configurationLdap2Form', configurationLdap2Form) + .factory('configurationLdap3Form', configurationLdap3Form) + .factory('configurationLdap4Form', configurationLdap4Form) + .factory('configurationLdap5Form', configurationLdap5Form) .factory('configurationRadiusForm', configurationRadiusForm) .factory('configurationTacacsForm', configurationTacacsForm) .factory('configurationSamlForm', configurationSamlForm)