@@ -, +, @@
password overrides by category
---
Koha/AuthUtils.pm | 19 +++++-----
Koha/Patron.pm | 4 +-
Koha/Patron/Category.pm | 32 ++++++++++++++++
admin/categories.pl | 8 ++++
.../prog/en/includes/password_check.inc | 42 ++++++++++++++-------
.../prog/en/modules/admin/categories.tt | 37 ++++++++++++++++++
.../prog/en/modules/members/member-password.tt | 15 ++++----
.../prog/en/modules/members/memberentrygen.tt | 7 ++--
.../prog/en/modules/onboarding/onboardingstep3.tt | 5 +--
.../bootstrap/en/includes/password_check.inc | 44 +++++++++++++++-------
.../bootstrap/en/modules/opac-memberentry.tt | 18 ++++-----
.../opac-tmpl/bootstrap/en/modules/opac-passwd.tt | 9 ++---
.../bootstrap/en/modules/opac-password-recovery.tt | 6 +--
members/memberentry.pl | 6 ++-
misc/admin/set_password.pl | 13 ++++---
opac/opac-memberentry.pl | 8 ++--
opac/opac-password-recovery.pl | 15 +++++++-
opac/opac-registration-verify.pl | 3 +-
18 files changed, 207 insertions(+), 84 deletions(-)
--- a/Koha/AuthUtils.pm
+++ a/Koha/AuthUtils.pm
@@ -139,21 +139,21 @@ sub generate_salt {
=head2 is_password_valid
-my ( $is_valid, $error ) = is_password_valid( $password );
+my ( $is_valid, $error ) = is_password_valid( $password, $category );
-return $is_valid == 1 if the password match minPasswordLength and RequireStrongPassword conditions
+return $is_valid == 1 if the password match category's minimum password length and strength if provided, or general minPasswordLength and RequireStrongPassword conditions
otherwise return $is_valid == 0 and $error will contain the error ('too_short' or 'too_weak')
=cut
sub is_password_valid {
- my ($password) = @_;
- my $minPasswordLength = C4::Context->preference('minPasswordLength');
+ my ($password, $category) = @_;
+ my $minPasswordLength = $category?$category->effective_min_password_length:C4::Context->preference('minPasswordLength');
$minPasswordLength = 3 if not $minPasswordLength or $minPasswordLength < 3;
if ( length($password) < $minPasswordLength ) {
return ( 0, 'too_short' );
}
- elsif ( C4::Context->preference('RequireStrongPassword') ) {
+ elsif ( $category?$category->effective_require_strong_password:C4::Context->preference('RequireStrongPassword') ) {
return ( 0, 'too_weak' )
if $password !~ m|(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{$minPasswordLength,}|;
}
@@ -163,20 +163,21 @@ sub is_password_valid {
=head2 generate_password
-my password = generate_password();
+my password = generate_password($category);
-Generate a password according to the minPasswordLength and RequireStrongPassword.
+Generate a password according to category's minimum password length and strength if provided, or to the minPasswordLength and RequireStrongPassword system preferences.
=cut
sub generate_password {
- my $minPasswordLength = C4::Context->preference('minPasswordLength');
+ my ($category) = @_;
+ my $minPasswordLength = $category?$category->effective_min_password_length:C4::Context->preference('minPasswordLength');
$minPasswordLength = 8 if not $minPasswordLength or $minPasswordLength < 8;
my ( $password, $is_valid );
do {
$password = random_string('.' x $minPasswordLength );
- ( $is_valid, undef ) = is_password_valid( $password );
+ ( $is_valid, undef ) = is_password_valid( $password, $category );
} while not $is_valid;
return $password;
}
--- a/Koha/Patron.pm
+++ a/Koha/Patron.pm
@@ -731,11 +731,11 @@ sub set_password {
my $password = $args->{password};
unless ( $args->{skip_validation} ) {
- my ( $is_valid, $error ) = Koha::AuthUtils::is_password_valid( $password );
+ my ( $is_valid, $error ) = Koha::AuthUtils::is_password_valid( $password, $self->category );
if ( !$is_valid ) {
if ( $error eq 'too_short' ) {
- my $min_length = C4::Context->preference('minPasswordLength');
+ my $min_length = $self->category->effective_min_password_length;
$min_length = 3 if not $min_length or $min_length < 3;
my $password_length = length($password);
--- a/Koha/Patron/Category.pm
+++ a/Koha/Patron/Category.pm
@@ -255,6 +255,38 @@ sub effective_change_password {
: C4::Context->preference('OpacPasswordChange');
}
+=head3 effective_min_password_length
+
+ $category->effective_min_password_length()
+
+Retrieve category's password length if setted, or minPasswordLength otherwise
+
+=cut
+
+sub effective_min_password_length {
+ my ($self) = @_;
+
+ return C4::Context->preference('minPasswordLength') unless defined $self->min_password_length;
+
+ return $self->min_password_length;
+}
+
+=head3 effective_require_strong_password
+
+ $category->effective_require_strong_password()
+
+Retrieve category's password strength if setted, or RequireStrongPassword otherwise
+
+=cut
+
+sub effective_require_strong_password {
+ my ($self) = @_;
+
+ return C4::Context->preference('RequireStrongPassword') unless defined $self->require_strong_password;
+
+ return $self->require_strong_password;
+}
+
=head3 override_hidden_items
if ( $patron->category->override_hidden_items ) {
--- a/admin/categories.pl
+++ a/admin/categories.pl
@@ -94,10 +94,14 @@ elsif ( $op eq 'add_validate' ) {
my $default_privacy = $input->param('default_privacy');
my $reset_password = $input->param('reset_password');
my $change_password = $input->param('change_password');
+ my $min_password_length = $input->param('min_password_length');
+ my $require_strong_password = $input->param('require_strong_password');
my @branches = grep { $_ ne q{} } $input->multi_param('branches');
$reset_password = undef if $reset_password eq -1;
$change_password = undef if $change_password eq -1;
+ $min_password_length = undef unless length($min_password_length);
+ $require_strong_password = undef if $require_strong_password eq -1;
my $is_a_modif = $input->param("is_a_modif");
@@ -129,6 +133,8 @@ elsif ( $op eq 'add_validate' ) {
$category->default_privacy($default_privacy);
$category->reset_password($reset_password);
$category->change_password($change_password);
+ $category->min_password_length($min_password_length);
+ $category->require_strong_password($require_strong_password);
eval {
$category->store;
$category->replace_branch_limitations( \@branches );
@@ -157,6 +163,8 @@ elsif ( $op eq 'add_validate' ) {
default_privacy => $default_privacy,
reset_password => $reset_password,
change_password => $change_password,
+ min_password_length => $min_password_length,
+ require_strong_password => $require_strong_password,
});
eval {
$category->store;
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/password_check.inc
+++ a/koha-tmpl/intranet-tmpl/prog/en/includes/password_check.inc
@@ -1,19 +1,36 @@
[% USE Koha %]
-[% BLOCK add_password_check %]
-[% END %]
+
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt
+++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt
@@ -229,6 +229,43 @@
[% END %]
+
+
+
+ Leave blank to use system default ([% Koha.Preference('minPasswordLength') | html %])
+
+
+
+
+