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

(-)a/Koha/Patron/Password/Recovery.pm (-4 / +4 lines)
Lines 156-165 sub SendPasswordRecoveryEmail { Link Here
156
    if (defined $params->{url}) {
156
    if (defined $params->{url}) {
157
        # Make sure host name exists in whitelist
157
        # Make sure host name exists in whitelist
158
        my $url = $params->{url};
158
        my $url = $params->{url};
159
        my $whitelist = C4::Context->preference(
159
        my $allowed_list = C4::Context->preference(
160
            'OpacResetPasswordHostWhitelist'
160
            'OpacResetPasswordAllowedHosts'
161
        );
161
        );
162
        my @allowed_hosts = split /[,\s\|]/, $whitelist if defined $whitelist;
162
        my @allowed_hosts = split /[,\s\|]/, $allowed_list if defined $allowed_list;
163
        foreach my $allowed_host (@allowed_hosts) {
163
        foreach my $allowed_host (@allowed_hosts) {
164
           if ($url =~ /^https?:\/\/$allowed_host/) {
164
           if ($url =~ /^https?:\/\/$allowed_host/) {
165
                $url =~ s/{uuid}/$uuid_str/gi;
165
                $url =~ s/{uuid}/$uuid_str/gi;
Lines 168-174 sub SendPasswordRecoveryEmail { Link Here
168
            }
168
            }
169
        }
169
        }
170
        Koha::Exceptions::WrongParameter->throw( error => 'System preference'
170
        Koha::Exceptions::WrongParameter->throw( error => 'System preference'
171
              . ' OpacResetPasswordHostWhitelist does'
171
              . ' OpacResetPasswordAllowedHosts does'
172
              . " not contain the requested host of '$url'"
172
              . " not contain the requested host of '$url'"
173
        ) if $uuidLink ne $params->{url};
173
        ) if $uuidLink ne $params->{url};
174
    }
174
    }
(-)a/api/v1/swagger/paths/patrons.json (-1 / +1 lines)
Lines 731-737 Link Here
731
              "type": "string"
731
              "type": "string"
732
            },
732
            },
733
            "complete_url": {
733
            "complete_url": {
734
              "description": "The location where patron will complete their password recovery. This location will be added into the password recovery email. To avoid malicious use, whitelist certain hosts in OpacResetPasswordHostWhitelist system preference and forbid all other custom links. Use {uuid} for adding the password recovery uuid into your custom link. It will be replaced by the actual uuid in the email.",
734
              "description": "The location where patron will complete their password recovery. This location will be added into the password recovery email. To avoid malicious use, allow certain hosts in OpacResetPasswordAllowedHosts system preference and forbid all other custom links. Use {uuid} for adding the password recovery uuid into your custom link. It will be replaced by the actual uuid in the email.",
735
              "type": "string"
735
              "type": "string"
736
            },
736
            },
737
            "skip_email": {
737
            "skip_email": {
(-)a/installer/data/mysql/atomicupdate/Bug-19133-2_Add_permission_get_password_reset_uuid.perl (-3 / +7 lines)
Lines 1-8 Link Here
1
$DBversion = 'XXX';  # will be replaced by the RM
1
$DBversion = 'XXX';  # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
2
if( CheckVersion( $DBversion ) ) {
3
3
4
    $dbh->do( "INSERT INTO permissions (module_bit, code, description) VALUES ( 4, 'get_password_reset_uuid', 'Allow the user to get password reset uuid when recovering passwords. Useful for third party service integrations that wish to do something with the uuid, such as handle emails themselves instead of Koha.')" );
4
    $dbh->do(q{
5
        INSERT INTO permissions
6
            (module_bit, code, description)
7
        VALUES
8
            ( 4, 'get_password_reset_uuid', 'Allow the user to get password reset uuid when recovering passwords. Useful for third party service integrations that wish to do something with the uuid, such as handle emails themselves instead of Koha.');
9
        });
5
10
6
    SetVersion( $DBversion );
11
    NewVersion( $DBversion, 19133, "Password recovery via REST API - Add permission get_password_reset_uuid");
7
    print "Upgrade to $DBversion done (Bug 19133 - Add permission get_password_reset_uuid.)\n";
8
}
12
}
(-)a/installer/data/mysql/atomicupdate/Bug-19133-Password-recovery-custom-link-allowed-hosts.perl (+12 lines)
Line 0 Link Here
1
$DBversion = 'XXX';  # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
3
4
    $dbh->do(q{
5
        INSERT INTO systempreferences
6
            (variable, value, options, explanation, type)
7
        VALUES
8
            ('OpacResetPasswordAllowedHosts', '', '', 'Allowed external host names for password reset in third party service. Separate list by whitespace, comma or |', 'free');
9
    });
10
11
    NewVersion( $DBversion, 19133, "Password recovery via REST API - Allowed hosts for custom links");
12
}
(-)a/installer/data/mysql/atomicupdate/Bug-19133-Password-recovery-custom-link-whitelist.perl (-11 lines)
Lines 1-11 Link Here
1
$DBversion = 'XXX';  # will be replaced by the RM
2
if( CheckVersion( $DBversion ) ) {
3
4
    $dbh->do(
5
        "INSERT INTO systempreferences (variable, value, options, explanation, type) VALUES ('OpacResetPasswordHostWhitelist', '', '', 'Whitelist external host names for password reset in third party service. Separate list by whitespace, comma or |', 'free')"
6
    );
7
8
    # Always end with this (adjust the bug info)
9
    SetVersion( $DBversion );
10
    print "Upgrade to $DBversion done (Bug 19133 - Password recovery via REST API - whitelist custom links)\n";
11
}
(-)a/installer/data/mysql/mandatory/sysprefs.sql (-1 / +1 lines)
Lines 439-445 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
439
('OpacRenewalBranch','checkoutbranch','itemhomebranch|patronhomebranch|checkoutbranch|none','Choose how the branch for an OPAC renewal is recorded in statistics','Choice'),
439
('OpacRenewalBranch','checkoutbranch','itemhomebranch|patronhomebranch|checkoutbranch|none','Choose how the branch for an OPAC renewal is recorded in statistics','Choice'),
440
('OPACReportProblem', 0, NULL, 'Allow patrons to submit problem reports for OPAC pages to the library or Koha Administrator', 'YesNo'),
440
('OPACReportProblem', 0, NULL, 'Allow patrons to submit problem reports for OPAC pages to the library or Koha Administrator', 'YesNo'),
441
('OpacResetPassword','0','','Shows the ''Forgot your password?'' link in the OPAC','YesNo'),
441
('OpacResetPassword','0','','Shows the ''Forgot your password?'' link in the OPAC','YesNo'),
442
('OpacResetPasswordHostWhitelist','','','Whitelist external host names for password reset in third party service. Separate list by whitespace, comma or |','free'),
442
('OpacResetPasswordAllowedHosts','','','Allowed external host names for password reset in third party service. Separate list by whitespace, comma or |','free'),
443
('OPACResultsLibrary', 'homebranch', 'homebranch|holdingbranch', 'Defines whether the OPAC displays the holding or home branch in search results when using XSLT', 'Choice'),
443
('OPACResultsLibrary', 'homebranch', 'homebranch|holdingbranch', 'Defines whether the OPAC displays the holding or home branch in search results when using XSLT', 'Choice'),
444
('OPACResultsSidebar','','70|10','Define HTML to be included on the search results page, underneath the facets sidebar','Textarea'),
444
('OPACResultsSidebar','','70|10','Define HTML to be included on the search results page, underneath the facets sidebar','Textarea'),
445
('OPACSearchForTitleIn','<a href=\"https://worldcat.org/search?q={TITLE}\" target=\"_blank\">Other Libraries (WorldCat)</a>\n<a href=\"https://scholar.google.com/scholar?q={TITLE}\" target=\"_blank\">Other Databases (Google Scholar)</a>\n<a href=\"https://www.bookfinder.com/search/?author={AUTHOR}&amp;title={TITLE}&amp;st=xl&amp;ac=qr\" target=\"_blank\">Online Stores (Bookfinder.com)</a>\n<a href=\"https://openlibrary.org/search?author=({AUTHOR})&title=({TITLE})\" target=\"_blank\">Open Library (openlibrary.org)</a>','70|10','Enter the HTML that will appear in the \'Search for this title in\' box on the detail page in the OPAC.  Enter {TITLE}, {AUTHOR}, or {ISBN} in place of their respective variables in the URL. Leave blank to disable \'More Searches\' menu.','Textarea'),
445
('OPACSearchForTitleIn','<a href=\"https://worldcat.org/search?q={TITLE}\" target=\"_blank\">Other Libraries (WorldCat)</a>\n<a href=\"https://scholar.google.com/scholar?q={TITLE}\" target=\"_blank\">Other Databases (Google Scholar)</a>\n<a href=\"https://www.bookfinder.com/search/?author={AUTHOR}&amp;title={TITLE}&amp;st=xl&amp;ac=qr\" target=\"_blank\">Online Stores (Bookfinder.com)</a>\n<a href=\"https://openlibrary.org/search?author=({AUTHOR})&title=({TITLE})\" target=\"_blank\">Open Library (openlibrary.org)</a>','70|10','Enter the HTML that will appear in the \'Search for this title in\' box on the detail page in the OPAC.  Enter {TITLE}, {AUTHOR}, or {ISBN} in place of their respective variables in the URL. Leave blank to disable \'More Searches\' menu.','Textarea'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref (-1 / +1 lines)
Lines 390-396 OPAC: Link Here
390
            - " to recover their password via e-mail in the OPAC."
390
            - " to recover their password via e-mail in the OPAC."
391
        -
391
        -
392
            - "Allow the following "
392
            - "Allow the following "
393
            - pref: OpacResetPasswordHostWhitelist
393
            - pref: OpacResetPasswordAllowedHosts
394
              type: textarea
394
              type: textarea
395
            - " host names of third party services to be used as external password reset locations. Separate list elements by new line, whitespace, comma or |."
395
            - " host names of third party services to be used as external password reset locations. Separate list elements by new line, whitespace, comma or |."
396
        -
396
        -
(-)a/t/db_dependent/api/v1/patrons_password_recovery.t (-4 / +3 lines)
Lines 197-203 subtest 'recovery() tests' => sub { Link Here
197
        plan tests => 5;
197
        plan tests => 5;
198
198
199
        t::lib::Mocks::mock_preference(
199
        t::lib::Mocks::mock_preference(
200
            'OpacResetPasswordHostWhitelist', ''
200
            'OpacResetPasswordAllowedHosts', ''
201
        );
201
        );
202
202
203
        $tx = $t->ua->build_tx(POST => $url => json => {
203
        $tx = $t->ua->build_tx(POST => $url => json => {
Lines 211-217 subtest 'recovery() tests' => sub { Link Here
211
          ->status_is(400);
211
          ->status_is(400);
212
212
213
        t::lib::Mocks::mock_preference(
213
        t::lib::Mocks::mock_preference(
214
            'OpacResetPasswordHostWhitelist', 'allowed'
214
            'OpacResetPasswordAllowedHosts', 'allowed'
215
        );
215
        );
216
216
217
        $tx = $t->ua->build_tx(POST => $url => json => {
217
        $tx = $t->ua->build_tx(POST => $url => json => {
Lines 249-255 subtest 'recovery() tests' => sub { Link Here
249
        plan tests => 10;
249
        plan tests => 10;
250
250
251
        t::lib::Mocks::mock_preference(
251
        t::lib::Mocks::mock_preference(
252
            'OpacResetPasswordHostWhitelist', 'anotherallowed'
252
            'OpacResetPasswordAllowedHosts', 'anotherallowed'
253
        );
253
        );
254
        my ($service_borrowernumber, $service_session) = create_user_and_session({
254
        my ($service_borrowernumber, $service_session) = create_user_and_session({
255
            authorized => 1
255
            authorized => 1
256
- 

Return to bug 19133