diff options
-rw-r--r-- | Bugzilla/Config/Auth.pm | 9 | ||||
-rw-r--r-- | Bugzilla/User.pm | 13 | ||||
-rw-r--r-- | template/en/default/admin/params/auth.html.tmpl | 14 | ||||
-rw-r--r-- | template/en/default/global/user-error.html.tmpl | 17 |
4 files changed, 52 insertions, 1 deletions
diff --git a/Bugzilla/Config/Auth.pm b/Bugzilla/Config/Auth.pm index c7d921ed5..a61cab5a2 100644 --- a/Bugzilla/Config/Auth.pm +++ b/Bugzilla/Config/Auth.pm @@ -121,6 +121,15 @@ sub get_param_list { type => 't', default => q:.*:, checker => \&check_regexp + }, + + { + name => 'password_complexity', + type => 's', + choices => [ 'no_constraints', 'mixed_letters', 'letters_numbers', + 'letters_numbers_specialchars' ], + default => 'no_constraints', + checker => \&check_multi } ); return @param_list; } diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index d15113959..eafda6563 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -1946,6 +1946,19 @@ sub validate_password { } elsif ((defined $matchpassword) && ($password ne $matchpassword)) { ThrowUserError('passwords_dont_match'); } + + my $complexity_level = Bugzilla->params->{password_complexity}; + if ($complexity_level eq 'letters_numbers_specialchars') { + ThrowUserError('password_not_complex') + if ($password !~ /\w/ || $password !~ /\d/ || $password !~ /[[:punct:]]/); + } elsif ($complexity_level eq 'letters_numbers') { + ThrowUserError('password_not_complex') + if ($password !~ /[[:lower:]]/ || $password !~ /[[:upper:]]/ || $password !~ /\d/); + } elsif ($complexity_level eq 'mixed_letters') { + ThrowUserError('password_not_complex') + if ($password !~ /[[:lower:]]/ || $password !~ /[[:upper:]]/); + } + # Having done these checks makes us consider the password untainted. trick_taint($_[0]); return 1; diff --git a/template/en/default/admin/params/auth.html.tmpl b/template/en/default/admin/params/auth.html.tmpl index 35bddf1af..8e91e54c0 100644 --- a/template/en/default/admin/params/auth.html.tmpl +++ b/template/en/default/admin/params/auth.html.tmpl @@ -125,5 +125,17 @@ "default (.*) permits any account matching the emailregexp " _ "to be created. If this parameter is left blank, no users " _ "will be permitted to create their own accounts and all accounts " _ - "will have to be created by an administrator." } + "will have to be created by an administrator.", + + password_complexity => + "Set the complexity required for passwords. In all cases must the passwords " _ + "be at least ${constants.USER_PASSWORD_MIN_LENGTH} characters long." _ + "<ul><li>no_constraints - No complexity required.</li>" _ + "<li>mixed_letters - Passwords must contain at least one UPPER and one lower " _ + "case letter.</li>" _ + "<li>letters_numbers - Passwords must contain at least one UPPER and one " _ + "lower case letter and a number.</li>" _ + "<li>letters_numbers_specialchars - Passwords must contain at least one " _ + "UPPER or one lower case letter, a number and a special character.</li></ul>" + } %] diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl index b76106f24..67012b555 100644 --- a/template/en/default/global/user-error.html.tmpl +++ b/template/en/default/global/user-error.html.tmpl @@ -1325,6 +1325,23 @@ The password must be at least [%+ constants.USER_PASSWORD_MIN_LENGTH FILTER html %] characters long. + [% ELSIF error == "password_not_complex" %] + [% title = "Password Fails Requirements" %] + [% passregex = Param('password_complexity') %] + The password must contain at least one: + <ul> + [% IF passregex.search('letters') %] + <li>UPPERCASE letter</li> + <li>lowercase letter</li> + [% END %] + [% IF passregex.search('numbers') %] + <li>digit</li> + [% END %] + [% IF passregex.search('specialchars') %] + <li>special character</li> + [% END %] + </ul> + [% ELSIF error == "product_access_denied" %] [% title = "Product Access Denied" %] Either the product |