aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Bugzilla/Config/Auth.pm9
-rw-r--r--Bugzilla/User.pm13
-rw-r--r--template/en/default/admin/params/auth.html.tmpl14
-rw-r--r--template/en/default/global/user-error.html.tmpl17
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