From 974306541e04ab6bc8c5a610abb350ba2dacff4c Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Mon, 14 Jan 2019 14:24:22 -0500 Subject: [PATCH 1/4] add isolated settings to ui --- .../forms/jobs-form/configuration-jobs.form.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/awx/ui/client/src/configuration/forms/jobs-form/configuration-jobs.form.js b/awx/ui/client/src/configuration/forms/jobs-form/configuration-jobs.form.js index e897a6ba4e..8822f531bd 100644 --- a/awx/ui/client/src/configuration/forms/jobs-form/configuration-jobs.form.js +++ b/awx/ui/client/src/configuration/forms/jobs-form/configuration-jobs.form.js @@ -67,6 +67,18 @@ export default ['i18n', function(i18n) { rows: 6, codeMirror: true, class: 'Form-textAreaLabel Form-formGroup--fullWidth' + }, + AWX_ISOLATED_CHECK_INTERVAL: { + type: 'text', + reset: 'AWX_ISOLATED_CHECK_INTERVAL' + }, + AWX_ISOLATED_LAUNCH_TIMEOUT: { + type: 'text', + reset: 'AWX_ISOLATED_LAUNCH_TIMEOUT' + }, + AWX_ISOLATED_CONNECTION_TIMEOUT: { + type: 'text', + reset: 'AWX_ISOLATED_CONNECTION_TIMEOUT' } }, buttons: { From 24de951f6ce2c24628ac8c4f1970a4e2e004b5f5 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Tue, 15 Jan 2019 14:05:48 -0500 Subject: [PATCH 2/4] add access token and authorization code expiration settings to ui --- .../configuration-auth.controller.js | 8 ++- .../auth-form/configuration-auth.partial.html | 4 ++ .../auth-form/sub-forms/auth-misc.form.js | 40 +++++++++++++++ .../forms/settings-form.controller.js | 49 +++++++++++++++++-- awx/ui/client/src/configuration/main.js | 2 + .../src/configuration/settings.service.js | 31 ++++++++++-- 6 files changed, 124 insertions(+), 10 deletions(-) create mode 100644 awx/ui/client/src/configuration/forms/auth-form/sub-forms/auth-misc.form.js diff --git a/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.controller.js b/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.controller.js index d3ef949ca6..966ecdc8e1 100644 --- a/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.controller.js +++ b/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.controller.js @@ -94,7 +94,8 @@ export default [ {label: i18n._('LDAP'), value: 'ldap'}, {label: i18n._('RADIUS'), value: 'radius'}, {label: i18n._('SAML'), value: 'saml'}, - {label: i18n._('TACACS+'), value: 'tacacs'} + {label: i18n._('TACACS+'), value: 'tacacs'}, + {label: i18n._('MISC'), value: 'authMisc'} ]; authVm.ldapDropdownOptions = [ @@ -198,6 +199,11 @@ export default [ id: 'auth-ldap5-form', name: 'ldap5' }, + { + formDef: formDefs.authMisc, + id: 'auth-misc-form', + name: 'authMisc' + }, ]; var forms = _.map(authForms, 'formDef'); _.each(forms, function(form) { diff --git a/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.partial.html b/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.partial.html index 5154285c80..04f0f2b542 100644 --- a/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.partial.html +++ b/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.partial.html @@ -97,6 +97,10 @@
+ +
+
+
diff --git a/awx/ui/client/src/configuration/forms/auth-form/sub-forms/auth-misc.form.js b/awx/ui/client/src/configuration/forms/auth-form/sub-forms/auth-misc.form.js new file mode 100644 index 0000000000..d55662c469 --- /dev/null +++ b/awx/ui/client/src/configuration/forms/auth-form/sub-forms/auth-misc.form.js @@ -0,0 +1,40 @@ +/************************************************* + * Copyright (c) 2016 Ansible, Inc. + * + * All Rights Reserved + *************************************************/ + +export default ['i18n', function(i18n) { + return { + name: 'configuration_authMisc_template', + showActions: true, + showHeader: false, + + fields: { + ACCESS_TOKEN_EXPIRE_SECONDS: { + type: 'text', + reset: 'ACCESS_TOKEN_EXPIRE_SECONDS' + }, + AUTHORIZATION_CODE_EXPIRE_SECONDS: { + type: 'text', + reset: 'AUTHORIZATION_CODE_EXPIRE_SECONDS' + } + }, + 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: "!enterprise_auth || configuration_authMisc_template_form.$invalid || configuration_authMisc_template_form.$pending" + } + } + }; +} +]; diff --git a/awx/ui/client/src/configuration/forms/settings-form.controller.js b/awx/ui/client/src/configuration/forms/settings-form.controller.js index 57216d9b85..828928f78b 100644 --- a/awx/ui/client/src/configuration/forms/settings-form.controller.js +++ b/awx/ui/client/src/configuration/forms/settings-form.controller.js @@ -19,6 +19,7 @@ export default [ 'configurationRadiusForm', 'configurationTacacsForm', 'configurationSamlForm', + 'configurationMiscForm', 'systemActivityStreamForm', 'systemLoggingForm', 'systemMiscForm', @@ -44,6 +45,7 @@ export default [ configurationRadiusForm, configurationTacacsForm, configurationSamlForm, + configurationMiscForm, systemActivityStreamForm, systemLoggingForm, systemMiscForm, @@ -71,6 +73,7 @@ export default [ 'radius': configurationRadiusForm, 'tacacs': configurationTacacsForm, 'saml': configurationSamlForm, + 'authMisc': configurationMiscForm, 'activity_stream': systemActivityStreamForm, 'logging': systemLoggingForm, 'misc': systemMiscForm, @@ -92,10 +95,15 @@ export default [ var populateFromApi = function() { SettingsService.getCurrentValues() .then(function(data) { + // these two values need to be unnested from the + // OAUTH2_PROVIDER key + data.ACCESS_TOKEN_EXPIRE_SECONDS = data + .OAUTH2_PROVIDER.ACCESS_TOKEN_EXPIRE_SECONDS; + data.AUTHORIZATION_CODE_EXPIRE_SECONDS = data + .OAUTH2_PROVIDER.AUTHORIZATION_CODE_EXPIRE_SECONDS; var currentKeys = _.keys(data); $scope.requiredLogValues = {}; _.each(currentKeys, function(key) { - if(key === "LOG_AGGREGATOR_HOST") { $scope.requiredLogValues.LOG_AGGREGATOR_HOST = data[key]; } @@ -232,7 +240,18 @@ export default [ $scope.resetValue = function(key) { Wait('start'); var payload = {}; - payload[key] = $scope.configDataResolve[key].default; + if (key === 'ACCESS_TOKEN_EXPIRE_SECONDS' || key === 'AUTHORIZATION_CODE_EXPIRE_SECONDS') { + // the reset for these two keys needs to be nested under OAUTH2_PROVIDER + if (payload.OAUTH2_PROVIDER === undefined) { + payload.OAUTH2_PROVIDER = { + ACCESS_TOKEN_EXPIRE_SECONDS: $scope.ACCESS_TOKEN_EXPIRE_SECONDS, + AUTHORIZATION_CODE_EXPIRE_SECONDS: $scope.AUTHORIZATION_CODE_EXPIRE_SECONDS + }; + } + payload.OAUTH2_PROVIDER[key] = $scope.configDataResolve[key].default; + } else { + payload[key] = $scope.configDataResolve[key].default; + } SettingsService.patchConfiguration(payload) .then(function() { $scope[key] = $scope.configDataResolve[key].default; @@ -310,7 +329,16 @@ export default [ var keys = _.keys(formDefs[formTracker.getCurrent()].fields); var payload = {}; _.each(keys, function(key) { - if($scope.configDataResolve[key].type === 'choice' || multiselectDropdowns.indexOf(key) !== -1) { + if (key === 'ACCESS_TOKEN_EXPIRE_SECONDS' || key === 'AUTHORIZATION_CODE_EXPIRE_SECONDS') { + // These two values need to be POSTed nested under the OAUTH2_PROVIDER key + if (payload.OAUTH2_PROVIDER === undefined) { + payload.OAUTH2_PROVIDER = { + ACCESS_TOKEN_EXPIRE_SECONDS: $scope.ACCESS_TOKEN_EXPIRE_SECONDS, + AUTHORIZATION_CODE_EXPIRE_SECONDS: $scope.AUTHORIZATION_CODE_EXPIRE_SECONDS + }; + } + payload.OAUTH2_PROVIDER[key] = $scope[key]; + } else if($scope.configDataResolve[key].type === 'choice' || multiselectDropdowns.indexOf(key) !== -1) { //Parse dropdowns and dropdowns labeled as lists if($scope[key] === null) { payload[key] = null; @@ -394,7 +422,7 @@ export default [ return saveDeferred.promise; }; - vm.formCancel = function() { + vm.formCancel = function() { if ($scope[formTracker.currentFormName()].$dirty === true) { var msg = i18n._('You have unsaved changes. Would you like to proceed without saving?'); var title = i18n._('Warning: Unsaved Changes'); @@ -518,7 +546,18 @@ export default [ var payload = {}; clearApiErrors(); _.each(keys, function(key) { - payload[key] = $scope.configDataResolve[key].default; + if (key === 'ACCESS_TOKEN_EXPIRE_SECONDS' || key === 'AUTHORIZATION_CODE_EXPIRE_SECONDS') { + // the reset for these two keys needs to be nested under OAUTH2_PROVIDER + if (payload.OAUTH2_PROVIDER === undefined) { + payload.OAUTH2_PROVIDER = { + ACCESS_TOKEN_EXPIRE_SECONDS: $scope.ACCESS_TOKEN_EXPIRE_SECONDS, + AUTHORIZATION_CODE_EXPIRE_SECONDS: $scope.AUTHORIZATION_CODE_EXPIRE_SECONDS + }; + } + payload.OAUTH2_PROVIDER[key] = $scope.configDataResolve[key].default; + } else { + payload[key] = $scope.configDataResolve[key].default; + } }); Wait('start'); diff --git a/awx/ui/client/src/configuration/main.js b/awx/ui/client/src/configuration/main.js index 809f3312fd..b034243652 100644 --- a/awx/ui/client/src/configuration/main.js +++ b/awx/ui/client/src/configuration/main.js @@ -23,6 +23,7 @@ import configurationLdap5Form from './forms/auth-form/sub-forms/auth-ldap5.form. import configurationRadiusForm from './forms/auth-form/sub-forms/auth-radius.form.js'; import configurationTacacsForm from './forms/auth-form/sub-forms/auth-tacacs.form.js'; import configurationSamlForm from './forms/auth-form/sub-forms/auth-saml.form'; +import configurationMiscForm from './forms/auth-form/sub-forms/auth-misc.form'; //system sub-forms import systemActivityStreamForm from './forms/system-form/sub-forms/system-activity-stream.form.js'; @@ -56,6 +57,7 @@ angular.module('configuration', []) .factory('configurationRadiusForm', configurationRadiusForm) .factory('configurationTacacsForm', configurationTacacsForm) .factory('configurationSamlForm', configurationSamlForm) + .factory('configurationMiscForm', configurationMiscForm) //system forms .factory('systemActivityStreamForm', systemActivityStreamForm) .factory('systemLoggingForm', systemLoggingForm) diff --git a/awx/ui/client/src/configuration/settings.service.js b/awx/ui/client/src/configuration/settings.service.js index 1d437dc2cd..a29f069869 100644 --- a/awx/ui/client/src/configuration/settings.service.js +++ b/awx/ui/client/src/configuration/settings.service.js @@ -4,8 +4,8 @@ * All Rights Reserved *************************************************/ -export default ['$rootScope', 'GetBasePath', 'ProcessErrors', '$q', '$http', 'Rest', - function($rootScope, GetBasePath, ProcessErrors, $q, $http, Rest) { +export default ['GetBasePath', '$q', 'Rest', 'i18n', + function(GetBasePath, $q, Rest, i18n) { var url = GetBasePath('settings') + 'all'; return { @@ -18,9 +18,32 @@ export default ['$rootScope', 'GetBasePath', 'ProcessErrors', '$q', '$http', 'Re .then(({data}) => { // Compare GET actions with PUT actions and flag discrepancies // for disabling in the UI - var getActions = data.actions.GET; + // + // since OAUTH2_PROVIDER returns two of the keys in a nested format, + // we need to split those out into the root of the options payload + // in order for them to be consumed + var appendOauth2ProviderKeys = (optsFromAPI) => { + var unnestOauth2ProviderKey = (key, label, parentKey) => { + optsFromAPI[key] = _.cloneDeep(optsFromAPI[parentKey]); + optsFromAPI[key].label = i18n._(label); + optsFromAPI[key].type = optsFromAPI[parentKey].child.type; + optsFromAPI[key].min_value = optsFromAPI[parentKey].child.min_value; + if (optsFromAPI[parentKey].default) { + optsFromAPI[key].default = optsFromAPI[parentKey].default[key]; + } + delete optsFromAPI[key].child; + }; + unnestOauth2ProviderKey('ACCESS_TOKEN_EXPIRE_SECONDS', + 'Access Token Expiration', + 'OAUTH2_PROVIDER'); + unnestOauth2ProviderKey('AUTHORIZATION_CODE_EXPIRE_SECONDS', + 'Authorization Code Expiration', + 'OAUTH2_PROVIDER'); + return optsFromAPI; + }; + var getActions = appendOauth2ProviderKeys(data.actions.GET); var getKeys = _.keys(getActions); - var putActions = data.actions.PUT; + var putActions = appendOauth2ProviderKeys(data.actions.PUT); _.each(getKeys, function(key) { if(putActions && putActions[key]) { From b75ba7ebeadb87c729bab3a811a442d5aa15de76 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Thu, 17 Jan 2019 13:50:53 -0500 Subject: [PATCH 3/4] remove auth misc form and move fields under system misc form --- .../configuration-auth.controller.js | 10 +---- .../auth-form/configuration-auth.partial.html | 4 -- .../auth-form/sub-forms/auth-misc.form.js | 40 ------------------- .../forms/settings-form.controller.js | 5 +-- .../system-form/sub-forms/system-misc.form.js | 8 ++++ awx/ui/client/src/configuration/main.js | 2 - 6 files changed, 11 insertions(+), 58 deletions(-) delete mode 100644 awx/ui/client/src/configuration/forms/auth-form/sub-forms/auth-misc.form.js diff --git a/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.controller.js b/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.controller.js index 966ecdc8e1..d916e3a53a 100644 --- a/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.controller.js +++ b/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.controller.js @@ -94,8 +94,7 @@ export default [ {label: i18n._('LDAP'), value: 'ldap'}, {label: i18n._('RADIUS'), value: 'radius'}, {label: i18n._('SAML'), value: 'saml'}, - {label: i18n._('TACACS+'), value: 'tacacs'}, - {label: i18n._('MISC'), value: 'authMisc'} + {label: i18n._('TACACS+'), value: 'tacacs'} ]; authVm.ldapDropdownOptions = [ @@ -198,12 +197,7 @@ export default [ formDef: formDefs.ldap5, id: 'auth-ldap5-form', name: 'ldap5' - }, - { - formDef: formDefs.authMisc, - id: 'auth-misc-form', - name: 'authMisc' - }, + } ]; var forms = _.map(authForms, 'formDef'); _.each(forms, function(form) { diff --git a/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.partial.html b/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.partial.html index 04f0f2b542..5154285c80 100644 --- a/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.partial.html +++ b/awx/ui/client/src/configuration/forms/auth-form/configuration-auth.partial.html @@ -97,10 +97,6 @@
- -
-
-
diff --git a/awx/ui/client/src/configuration/forms/auth-form/sub-forms/auth-misc.form.js b/awx/ui/client/src/configuration/forms/auth-form/sub-forms/auth-misc.form.js deleted file mode 100644 index d55662c469..0000000000 --- a/awx/ui/client/src/configuration/forms/auth-form/sub-forms/auth-misc.form.js +++ /dev/null @@ -1,40 +0,0 @@ -/************************************************* - * Copyright (c) 2016 Ansible, Inc. - * - * All Rights Reserved - *************************************************/ - -export default ['i18n', function(i18n) { - return { - name: 'configuration_authMisc_template', - showActions: true, - showHeader: false, - - fields: { - ACCESS_TOKEN_EXPIRE_SECONDS: { - type: 'text', - reset: 'ACCESS_TOKEN_EXPIRE_SECONDS' - }, - AUTHORIZATION_CODE_EXPIRE_SECONDS: { - type: 'text', - reset: 'AUTHORIZATION_CODE_EXPIRE_SECONDS' - } - }, - 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: "!enterprise_auth || configuration_authMisc_template_form.$invalid || configuration_authMisc_template_form.$pending" - } - } - }; -} -]; diff --git a/awx/ui/client/src/configuration/forms/settings-form.controller.js b/awx/ui/client/src/configuration/forms/settings-form.controller.js index 828928f78b..57bb59e68f 100644 --- a/awx/ui/client/src/configuration/forms/settings-form.controller.js +++ b/awx/ui/client/src/configuration/forms/settings-form.controller.js @@ -19,7 +19,6 @@ export default [ 'configurationRadiusForm', 'configurationTacacsForm', 'configurationSamlForm', - 'configurationMiscForm', 'systemActivityStreamForm', 'systemLoggingForm', 'systemMiscForm', @@ -45,7 +44,6 @@ export default [ configurationRadiusForm, configurationTacacsForm, configurationSamlForm, - configurationMiscForm, systemActivityStreamForm, systemLoggingForm, systemMiscForm, @@ -73,7 +71,6 @@ export default [ 'radius': configurationRadiusForm, 'tacacs': configurationTacacsForm, 'saml': configurationSamlForm, - 'authMisc': configurationMiscForm, 'activity_stream': systemActivityStreamForm, 'logging': systemLoggingForm, 'misc': systemMiscForm, @@ -422,7 +419,7 @@ export default [ return saveDeferred.promise; }; - vm.formCancel = function() { + vm.formCancel = function() { if ($scope[formTracker.currentFormName()].$dirty === true) { var msg = i18n._('You have unsaved changes. Would you like to proceed without saving?'); var title = i18n._('Warning: Unsaved Changes'); diff --git a/awx/ui/client/src/configuration/forms/system-form/sub-forms/system-misc.form.js b/awx/ui/client/src/configuration/forms/system-form/sub-forms/system-misc.form.js index 2d5853f8e4..f9dddd237b 100644 --- a/awx/ui/client/src/configuration/forms/system-form/sub-forms/system-misc.form.js +++ b/awx/ui/client/src/configuration/forms/system-form/sub-forms/system-misc.form.js @@ -43,6 +43,14 @@ export default ['i18n', function(i18n) { ALLOW_OAUTH2_FOR_EXTERNAL_USERS: { type: 'toggleSwitch', }, + ACCESS_TOKEN_EXPIRE_SECONDS: { + type: 'text', + reset: 'ACCESS_TOKEN_EXPIRE_SECONDS' + }, + AUTHORIZATION_CODE_EXPIRE_SECONDS: { + type: 'text', + reset: 'AUTHORIZATION_CODE_EXPIRE_SECONDS' + }, REMOTE_HOST_HEADERS: { type: 'textarea', reset: 'REMOTE_HOST_HEADERS' diff --git a/awx/ui/client/src/configuration/main.js b/awx/ui/client/src/configuration/main.js index b034243652..809f3312fd 100644 --- a/awx/ui/client/src/configuration/main.js +++ b/awx/ui/client/src/configuration/main.js @@ -23,7 +23,6 @@ import configurationLdap5Form from './forms/auth-form/sub-forms/auth-ldap5.form. import configurationRadiusForm from './forms/auth-form/sub-forms/auth-radius.form.js'; import configurationTacacsForm from './forms/auth-form/sub-forms/auth-tacacs.form.js'; import configurationSamlForm from './forms/auth-form/sub-forms/auth-saml.form'; -import configurationMiscForm from './forms/auth-form/sub-forms/auth-misc.form'; //system sub-forms import systemActivityStreamForm from './forms/system-form/sub-forms/system-activity-stream.form.js'; @@ -57,7 +56,6 @@ angular.module('configuration', []) .factory('configurationRadiusForm', configurationRadiusForm) .factory('configurationTacacsForm', configurationTacacsForm) .factory('configurationSamlForm', configurationSamlForm) - .factory('configurationMiscForm', configurationMiscForm) //system forms .factory('systemActivityStreamForm', systemActivityStreamForm) .factory('systemLoggingForm', systemLoggingForm) From 2df51a923dd81ca619aea2f19f86f66ae9b29509 Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Fri, 18 Jan 2019 13:13:15 -0500 Subject: [PATCH 4/4] change grant reference to code in ui help text --- awx/ui/client/src/configuration/settings.service.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/awx/ui/client/src/configuration/settings.service.js b/awx/ui/client/src/configuration/settings.service.js index a29f069869..62dedab140 100644 --- a/awx/ui/client/src/configuration/settings.service.js +++ b/awx/ui/client/src/configuration/settings.service.js @@ -23,9 +23,10 @@ export default ['GetBasePath', '$q', 'Rest', 'i18n', // we need to split those out into the root of the options payload // in order for them to be consumed var appendOauth2ProviderKeys = (optsFromAPI) => { - var unnestOauth2ProviderKey = (key, label, parentKey) => { + var unnestOauth2ProviderKey = (key, help_text, label, parentKey) => { optsFromAPI[key] = _.cloneDeep(optsFromAPI[parentKey]); - optsFromAPI[key].label = i18n._(label); + optsFromAPI[key].label = label; + optsFromAPI[key].help_text = help_text; optsFromAPI[key].type = optsFromAPI[parentKey].child.type; optsFromAPI[key].min_value = optsFromAPI[parentKey].child.min_value; if (optsFromAPI[parentKey].default) { @@ -34,10 +35,12 @@ export default ['GetBasePath', '$q', 'Rest', 'i18n', delete optsFromAPI[key].child; }; unnestOauth2ProviderKey('ACCESS_TOKEN_EXPIRE_SECONDS', - 'Access Token Expiration', + i18n._('The duration (in seconds) access tokens remain valid since their creation.'), + i18n._('Access Token Expiration'), 'OAUTH2_PROVIDER'); unnestOauth2ProviderKey('AUTHORIZATION_CODE_EXPIRE_SECONDS', - 'Authorization Code Expiration', + i18n._('The duration (in seconds) authorization codes remain valid since their creation.'), + i18n._('Authorization Code Expiration'), 'OAUTH2_PROVIDER'); return optsFromAPI; };