diff --git a/awx/ui/static/js/config.js b/awx/ui/static/js/config.js index 3531acafc0..192f436dfc 100644 --- a/awx/ui/static/js/config.js +++ b/awx/ui/static/js/config.js @@ -21,12 +21,12 @@ debug_mode: false, // Enable console logging messages - password_strength: 45, // User password strength. Integer between 0 and 100, 100 being impossibly strong. - // This value controls progress bar colors: - // 0 to password_strength - 15 = red; - // password_strength - 15 to password_strength = yellow - // > password_strength = green - // It also controls password validation. Passwords are rejected if the score is not > password_strength. + password_length: 8, // Minimum user password length. Set to 0 to not set a limit + password_hasLowercase: true, // require a lowercase letter in the password + password_hasUppercase: true, // require an uppercase letter in the password + password_hasNumber: true, // require a number in the password + password_hasSymbol: true, // require one of these symbols to be + // in the password: -!$%^&*()_+|~=`{}[]:";'<>?,./ session_timeout: 1800, // Number of seconds before an inactive session is automatically timed out and forced to log in again. // Separate from time out value set in API. diff --git a/awx/ui/static/js/shared/directives.js b/awx/ui/static/js/shared/directives.js index c55c117813..5f1321457c 100644 --- a/awx/ui/static/js/shared/directives.js +++ b/awx/ui/static/js/shared/directives.js @@ -60,6 +60,64 @@ angular.module('AWDirectives', ['RestServices', 'Utilities', 'AuthService', 'Job }; }) + // chkPass + // + // Enables use of js/shared/pwdmeter.js to check strengh of passwords. + // See controllers/Users.js for example. + // + .directive('chkPass', [ function() { + return { + require: 'ngModel', + link: function(scope, elm, attrs, ctrl) { + $(elm).keyup(function() { + var validity = true; + if (elm.val()) { + if ($AnsibleConfig.password_length) { + validity = (ctrl.$modelValue.length >= $AnsibleConfig.password_length); + ctrl.$setValidity('password_length', validity); + } + if ($AnsibleConfig.password_hasLowercase) { + validity = (/[a-z]/.test(ctrl.$modelValue)); + ctrl.$setValidity('hasLowercase', validity); + } + if ($AnsibleConfig.password_hasUppercase) { + validity = (/[A-Z]/.test(ctrl.$modelValue)); + ctrl.$setValidity('hasUppercase', validity); + } + if ($AnsibleConfig.password_hasNumber) { + validity = (/[0-9]/.test(ctrl.$modelValue)); + ctrl.$setValidity('hasNumber', validity); + } + if ($AnsibleConfig.password_hasSymbol) { + validity = (/[$-/:-?{-~!"^_`\[\]]/.test(ctrl.$modelValue)); + ctrl.$setValidity('hasSymbol', validity); + } + } else { + validity = true; + if ($AnsibleConfig.password_length) { + ctrl.$setValidity('password_length', validity); + } + if ($AnsibleConfig.password_hasLowercase) { + ctrl.$setValidity('hasLowercase', validity); + } + if ($AnsibleConfig.password_hasUppercase) { + ctrl.$setValidity('hasUppercase', validity); + } + if ($AnsibleConfig.password_hasNumber) { + ctrl.$setValidity('hasNumber', validity); + } + if ($AnsibleConfig.password_hasSymbol) { + ctrl.$setValidity('hasSymbol', validity); + } + } + if (!scope.$$phase) { + scope.$digest(); + } + }); + } + }; + }]) + .directive('surveyCheckboxes', function(){ return { diff --git a/awx/ui/static/js/shared/form-generator.js b/awx/ui/static/js/shared/form-generator.js index f49fe1764b..e8194cff8d 100644 --- a/awx/ui/static/js/shared/form-generator.js +++ b/awx/ui/static/js/shared/form-generator.js @@ -397,6 +397,23 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat scope[form.name + '_form'][fld].$setPristine(); scope[form.name + '_form'][fld].$setValidity('apiError', true); } + if (f.chkPass && scope[form.name + '_form'][fld]) { + if ($AnsibleConfig.password_length) { + scope[form.name + '_form'][fld].$setValidity('password_length', true); + } + if ($AnsibleConfig.password_hasLowercase) { + scope[form.name + '_form'][fld].$setValidity('hasLowercase', true); + } + if ($AnsibleConfig.password_hasUppercase) { + scope[form.name + '_form'][fld].$setValidity('hasUppercase', true); + } + if ($AnsibleConfig.password_hasNumber) { + scope[form.name + '_form'][fld].$setValidity('hasNumber', true); + } + if ($AnsibleConfig.password_hasSymbol) { + scope[form.name + '_form'][fld].$setValidity('hasSymbol', true); + } + } if (f.awPassMatch && scope[form.name + '_form'][fld]) { scope[form.name + '_form'][fld].$setValidity('awpassmatch', true); } @@ -899,6 +916,7 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat html += "class='form-control"; html += (field['class']) ? " " + this.attr(field, 'class') : ""; html += "' "; + html += (field.chkPass) ? "chk-pass " : ""; html += (field.placeholder) ? this.attr(field, 'placeholder') : ""; html += (options.mode === 'edit' && field.editRequired) ? "required " : ""; @@ -965,6 +983,29 @@ angular.module('FormGenerator', [GeneratorHelpers.name, 'Utilities', listGenerat html += "