View | Details | Raw Unified | Return to bug 29924
Collapse All | Expand All

(-)a/C4/Auth.pm (-3 / +9 lines)
Lines 930-935 sub checkauth { Link Here
930
                $info{oldip}        = $more_info->{old_ip};
930
                $info{oldip}        = $more_info->{old_ip};
931
                $info{newip}        = $more_info->{new_ip};
931
                $info{newip}        = $more_info->{new_ip};
932
                $info{different_ip} = 1;
932
                $info{different_ip} = 1;
933
            } elsif ( $return eq 'password_expired' ) {
934
                $info{password_has_expired} = 1;
933
            }
935
            }
934
        }
936
        }
935
    }
937
    }
Lines 1314-1320 sub checkauth { Link Here
1314
        PatronSelfRegistration                => C4::Context->preference("PatronSelfRegistration"),
1316
        PatronSelfRegistration                => C4::Context->preference("PatronSelfRegistration"),
1315
        PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"),
1317
        PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"),
1316
        opac_css_override                     => $ENV{'OPAC_CSS_OVERRIDE'},
1318
        opac_css_override                     => $ENV{'OPAC_CSS_OVERRIDE'},
1317
        too_many_login_attempts               => ( $patron and $patron->account_locked )
1319
        too_many_login_attempts               => ( $patron and $patron->account_locked ),
1320
        password_has_expired                  => ( $patron and $patron->password_expired )
1318
    );
1321
    );
1319
1322
1320
    $template->param( SCO_login => 1 ) if ( $query->param('sco_user_login') );
1323
    $template->param( SCO_login => 1 ) if ( $query->param('sco_user_login') );
Lines 1702-1707 sub check_cookie_auth { Link Here
1702
            return ( "restricted", undef, { old_ip => $ip, new_ip => $remote_addr});
1705
            return ( "restricted", undef, { old_ip => $ip, new_ip => $remote_addr});
1703
        } else {
1706
        } else {
1704
            $session->param( 'lasttime', time() );
1707
            $session->param( 'lasttime', time() );
1708
            my $patron = Koha::Patrons->find({ userid => $userid });
1709
            $patron = Koha::Patron->find({ cardnumber => $userid }) unless $patron;
1710
            return ("password_expired", undef ) if $patron->password_expired;
1705
            my $flags = defined($flagsrequired) ? haspermission( $userid, $flagsrequired ) : 1;
1711
            my $flags = defined($flagsrequired) ? haspermission( $userid, $flagsrequired ) : 1;
1706
            if ($flags) {
1712
            if ($flags) {
1707
                return ( "ok", $session );
1713
                return ( "ok", $session );
Lines 1790-1797 sub checkpw { Link Here
1790
    # 0 if auth is nok
1796
    # 0 if auth is nok
1791
    # -1 if user bind failed (LDAP only)
1797
    # -1 if user bind failed (LDAP only)
1792
1798
1793
    if ( $patron and $patron->account_locked ) {
1799
    if ( $patron and ( $patron->account_locked || $patron->password_expired )  ) {
1794
        # Nothing to check, account is locked
1800
        # Nothing to check, account is locked or password expired
1795
    } elsif ($ldap && defined($password)) {
1801
    } elsif ($ldap && defined($password)) {
1796
        my ( $retval, $retcard, $retuserid ) = checkpw_ldap(@_);    # EXTERNAL AUTH
1802
        my ( $retval, $retcard, $retuserid ) = checkpw_ldap(@_);    # EXTERNAL AUTH
1797
        if ( $retval == 1 ) {
1803
        if ( $retval == 1 ) {
(-)a/Koha/Patron.pm (+20 lines)
Lines 264-269 sub store { Link Here
264
                # Make a copy of the plain text password for later use
264
                # Make a copy of the plain text password for later use
265
                $self->plain_text_password( $self->password );
265
                $self->plain_text_password( $self->password );
266
266
267
                $self->password_expiration_date( $self->password
268
                    ? $self->category->get_password_expiry_date
269
                    : undef );
267
                # Create a disabled account if no password provided
270
                # Create a disabled account if no password provided
268
                $self->password( $self->password
271
                $self->password( $self->password
269
                    ? Koha::AuthUtils::hash_password( $self->password )
272
                    ? Koha::AuthUtils::hash_password( $self->password )
Lines 777-782 sub is_expired { Link Here
777
    return 0;
780
    return 0;
778
}
781
}
779
782
783
=head3 password_expired
784
785
my $password_expired = $patron->password_expired;
786
787
Returns 1 if the patron's password is expired or 0;
788
789
=cut
790
791
sub password_expired {
792
    my ($self) = @_;
793
    return 0 unless $self->password_expiration_date;
794
    return 1 if dt_from_string( $self->password_expiration_date ) < dt_from_string->truncate( to => 'day' );
795
    return 0;
796
}
797
780
=head3 is_going_to_expire
798
=head3 is_going_to_expire
781
799
782
my $is_going_to_expire = $patron->is_going_to_expire;
800
my $is_going_to_expire = $patron->is_going_to_expire;
Lines 876-881 sub set_password { Link Here
876
894
877
    my $digest = Koha::AuthUtils::hash_password($password);
895
    my $digest = Koha::AuthUtils::hash_password($password);
878
896
897
    $self->password_expiration_date( $self->category->get_password_expiry_date );
898
879
    # We do not want to call $self->store and retrieve password from DB
899
    # We do not want to call $self->store and retrieve password from DB
880
    $self->password($digest);
900
    $self->password($digest);
881
    $self->login_attempts(0);
901
    $self->login_attempts(0);
(-)a/Koha/Patron/Category.pm (+20 lines)
Lines 113-118 sub get_expiry_date { Link Here
113
    }
113
    }
114
}
114
}
115
115
116
=head3 get_password_expiry_date
117
118
Returns date based on password expiry days set for the category. If the value is not set
119
we return undef, password does not expire
120
121
my $expiry_date = $category->get_password_expiry_date();
122
123
=cut
124
125
sub get_password_expiry_date {
126
    my ($self, $date ) = @_;
127
    if ( $self->password_expiry_days ) {
128
        $date ||= dt_from_string;
129
        $date = dt_from_string( $date ) unless ref $date;
130
        return $date->add( days => $self->password_expiry_days )->ymd;
131
    } else {
132
        return;
133
    }
134
}
135
116
=head3 effective_reset_password
136
=head3 effective_reset_password
117
137
118
Returns if patrons in this category can reset their password. If set in $self->reset_password
138
Returns if patrons in this category can reset their password. If set in $self->reset_password
(-)a/Koha/REST/V1/Auth.pm (-1 / +6 lines)
Lines 490-496 sub _basic_auth { Link Here
490
        Koha::Exceptions::Authorization::Unauthorized->throw( error => 'Invalid password' );
490
        Koha::Exceptions::Authorization::Unauthorized->throw( error => 'Invalid password' );
491
    }
491
    }
492
492
493
    return Koha::Patrons->find({ userid => $user_id });
493
    my $patron = Koha::Patrons->find({ userid => $user_id });
494
    if ( $patron->password_expired ) {
495
        Koha::Exceptions::Authorization::Unauthorized->throw( error => 'Password has expired' );
496
    }
497
498
    return $patron;
494
}
499
}
495
500
496
=head3 _set_userenv
501
=head3 _set_userenv
(-)a/admin/categories.pl (+3 lines)
Lines 63-68 elsif ( $op eq 'add_validate' ) { Link Here
63
    my $description = $input->param('description');
63
    my $description = $input->param('description');
64
    my $enrolmentperiod = $input->param('enrolmentperiod');
64
    my $enrolmentperiod = $input->param('enrolmentperiod');
65
    my $enrolmentperioddate = $input->param('enrolmentperioddate') || undef;
65
    my $enrolmentperioddate = $input->param('enrolmentperioddate') || undef;
66
    my $password_expiry_days = $input->param('password_expiry_days') || undef;
66
    my $upperagelimit = $input->param('upperagelimit');
67
    my $upperagelimit = $input->param('upperagelimit');
67
    my $dateofbirthrequired = $input->param('dateofbirthrequired');
68
    my $dateofbirthrequired = $input->param('dateofbirthrequired');
68
    my $enrolmentfee = $input->param('enrolmentfee');
69
    my $enrolmentfee = $input->param('enrolmentfee');
Lines 103-108 elsif ( $op eq 'add_validate' ) { Link Here
103
        $category->description($description);
104
        $category->description($description);
104
        $category->enrolmentperiod($enrolmentperiod);
105
        $category->enrolmentperiod($enrolmentperiod);
105
        $category->enrolmentperioddate($enrolmentperioddate);
106
        $category->enrolmentperioddate($enrolmentperioddate);
107
        $category->password_expiry_days($password_expiry_days);
106
        $category->upperagelimit($upperagelimit);
108
        $category->upperagelimit($upperagelimit);
107
        $category->dateofbirthrequired($dateofbirthrequired);
109
        $category->dateofbirthrequired($dateofbirthrequired);
108
        $category->enrolmentfee($enrolmentfee);
110
        $category->enrolmentfee($enrolmentfee);
Lines 134-139 elsif ( $op eq 'add_validate' ) { Link Here
134
            description => $description,
136
            description => $description,
135
            enrolmentperiod => $enrolmentperiod,
137
            enrolmentperiod => $enrolmentperiod,
136
            enrolmentperioddate => $enrolmentperioddate,
138
            enrolmentperioddate => $enrolmentperioddate,
139
            password_expiry_days => $password_expiry_days,
137
            upperagelimit => $upperagelimit,
140
            upperagelimit => $upperagelimit,
138
            dateofbirthrequired => $dateofbirthrequired,
141
            dateofbirthrequired => $dateofbirthrequired,
139
            enrolmentfee => $enrolmentfee,
142
            enrolmentfee => $enrolmentfee,
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/categories.tt (+11 lines)
Lines 162-167 Link Here
162
                        </ol>
162
                        </ol>
163
                    </fieldset>
163
                    </fieldset>
164
                </li>
164
                </li>
165
                <li>
166
                    <label for="password_expiry_days">Password expiration: </label>
167
                    <input type="text" name="password_expiry_days" id="password_expiry_days" value="[% category.password_expiry_days | html %]" size="3" maxlength="5" /> days
168
                </li>
165
                <li>
169
                <li>
166
                    <label for="dateofbirthrequired">Age required: </label>
170
                    <label for="dateofbirthrequired">Age required: </label>
167
                    <input type="text" name="dateofbirthrequired" id="dateofbirthrequired" value="[% category.dateofbirthrequired | html %]" size="3" maxlength="3" /> years
171
                    <input type="text" name="dateofbirthrequired" id="dateofbirthrequired" value="[% category.dateofbirthrequired | html %]" size="3" maxlength="3" /> years
Lines 449-454 Link Here
449
                        [% END %]
453
                        [% END %]
450
                    </td>
454
                    </td>
451
                </tr>
455
                </tr>
456
                <tr><th scope="row">Password expiration: </th><td>[% category.password_expiry_days | html %] days</td></tr>
452
                <tr><th scope="row">Age required: </th><td>[% category.dateofbirthrequired | html %] years</td></tr>
457
                <tr><th scope="row">Age required: </th><td>[% category.dateofbirthrequired | html %] years</td></tr>
453
                <tr><th scope="row">Upperage limit: </th><td>[% category.upperagelimit | html %] years</td></tr>
458
                <tr><th scope="row">Upperage limit: </th><td>[% category.upperagelimit | html %] years</td></tr>
454
                <tr><th scope="row">Enrollment fee: </th><td>[% category.enrolmentfee | $Price %]</td></tr>
459
                <tr><th scope="row">Enrollment fee: </th><td>[% category.enrolmentfee | $Price %]</td></tr>
Lines 517-522 Link Here
517
                    <th scope="col">Category name</th>
522
                    <th scope="col">Category name</th>
518
                    <th scope="col">Type</th>
523
                    <th scope="col">Type</th>
519
                    <th scope="col">Enrollment period</th>
524
                    <th scope="col">Enrollment period</th>
525
                    <th scope="col">Password expiration</th>
520
                    <th scope="col">Age required</th>
526
                    <th scope="col">Age required</th>
521
                    <th scope="col">Upper age limit</th>
527
                    <th scope="col">Upper age limit</th>
522
                    <th scope="col">Enrollment fee</th>
528
                    <th scope="col">Enrollment fee</th>
Lines 559-564 Link Here
559
                                until [% category.enrolmentperioddate | $KohaDates %]
565
                                until [% category.enrolmentperioddate | $KohaDates %]
560
                            [% END %]
566
                            [% END %]
561
                        </td>
567
                        </td>
568
                        [% IF (category.password_expiry_days) %]
569
                            <td>[% category.password_expiry_days | html %] days</td>
570
                        [% ELSE %]
571
                            <td>-</td>
572
                        [% END %]
562
                        [% IF (category.dateofbirthrequired) %]
573
                        [% IF (category.dateofbirthrequired) %]
563
                            <td>[% category.dateofbirthrequired | html %] years</td>
574
                            <td>[% category.dateofbirthrequired | html %] years</td>
564
                        [% ELSE %]
575
                        [% ELSE %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/auth.tt (+7 lines)
Lines 49-54 Link Here
49
    [% IF Categories.can_any_reset_password && Koha.Preference('OpacBaseURL') %]
49
    [% IF Categories.can_any_reset_password && Koha.Preference('OpacBaseURL') %]
50
        <a href="[% Koha.Preference('OpacBaseURL') | url %]/cgi-bin/koha/opac-password-recovery.pl">You must reset your password</a>.
50
        <a href="[% Koha.Preference('OpacBaseURL') | url %]/cgi-bin/koha/opac-password-recovery.pl">You must reset your password</a>.
51
    [% END %]
51
    [% END %]
52
[% ELSIF password_has_expired %]
53
    <div id="login_error"><strong>Error: </strong>Your password has expired!</div>
54
    [% IF Categories.can_any_reset_password && Koha.Preference('OpacBaseURL') %]
55
        <a href="[% Koha.Preference('OpacBaseURL') | url %]/cgi-bin/koha/opac-password-recovery.pl">You must reset your password</a>.
56
    [% ELSE %]
57
        <p>You must contact the library to have your password reset</p>
58
    [% END %]
52
[% ELSIF invalid_username_or_password %]
59
[% ELSIF invalid_username_or_password %]
53
<div id="login_error"><strong>Error: </strong>Invalid username or password</div>
60
<div id="login_error"><strong>Error: </strong>Invalid username or password</div>
54
[% END %]
61
[% END %]
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt (-3 / +11 lines)
Lines 167-173 Link Here
167
                            [% END # /IF GoogleOpenIDConnect %]
167
                            [% END # /IF GoogleOpenIDConnect %]
168
                        [% END # /UNLESS OPACShibOnly %]
168
                        [% END # /UNLESS OPACShibOnly %]
169
169
170
                        [% IF !Koha.Preference('OPACShibOnly') or SCO_login or SCI_login %]
170
                        [% IF password_has_expired %]
171
                            <p class="error"><strong>Error: </strong>Your password has expired!</p>
172
                            [% IF Koha.Preference('OpacPasswordChange') && Categories.can_any_reset_password %]
173
                                <div id="resetpassword">
174
                                    <a href="/cgi-bin/koha/opac-password-recovery.pl">Reset your password?</a>
175
                                </div>
176
                            [% ELSE %]
177
                                <p>You must contact the library to reset your password</p>
178
                            [% END %]
179
                        [% ELSIF !Koha.Preference('OPACShibOnly') or SCO_login or SCI_login %]
171
                            [% IF SCO_login %]
180
                            [% IF SCO_login %]
172
                                <form action="/cgi-bin/koha/sco/sco-main.pl" name="auth" id="auth" method="post" autocomplete="off">
181
                                <form action="/cgi-bin/koha/sco/sco-main.pl" name="auth" id="auth" method="post" autocomplete="off">
173
                            [% ELSIF SCI_login %]
182
                            [% ELSIF SCI_login %]
Lines 218-224 Link Here
218
                                    </div>
227
                                    </div>
219
                                [% END %]
228
                                [% END %]
220
                            </form>
229
                            </form>
221
                        [% END # / IF !OPACShibOnly or SCO_login or SCI_login %]
230
                        [% END # / IF password_has_expired / ELSIF !OPACShibOnly or SCO_login or SCI_login %]
222
                    [% END # / IF loginprompt %]
231
                    [% END # / IF loginprompt %]
223
232
224
                    [% ELSE %]
233
                    [% ELSE %]
225
- 

Return to bug 29924