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

(-)a/t/db_dependent/api/v1/patrons_password.t (-1 / +224 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License along
15
# with Koha; if not, write to the Free Software Foundation, Inc.,
16
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
use Modern::Perl;
19
20
use Test::More tests => 2;
21
22
use Test::Mojo;
23
use Test::Warn;
24
25
use t::lib::TestBuilder;
26
use t::lib::Mocks;
27
28
use Koha::Patrons;
29
30
my $schema  = Koha::Database->new->schema;
31
my $builder = t::lib::TestBuilder->new;
32
33
# FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
34
# this affects the other REST api tests
35
t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
36
37
my $remote_address = '127.0.0.1';
38
my $t              = Test::Mojo->new('Koha::REST::V1');
39
40
subtest 'set_password() (authorized user tests)' => sub {
41
42
    plan tests => 18;
43
44
    $schema->storage->txn_begin;
45
46
    my ( $patron, $session ) = create_user_and_session({ authorized => 1 });
47
48
    t::lib::Mocks::mock_preference( 'OpacPasswordChange',    0 );
49
    t::lib::Mocks::mock_preference( 'minPasswordLength',     3 );
50
    t::lib::Mocks::mock_preference( 'RequireStrongPassword', 0 );
51
52
    my $new_password = 'abc';
53
54
    my $tx
55
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
56
            . $patron->id
57
            . "/password" => json => { password => $new_password } );
58
59
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
60
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
61
    $t->request_ok($tx)->status_is(200)->json_is( '' );
62
63
    t::lib::Mocks::mock_preference( 'minPasswordLength', 5 );
64
    $tx
65
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
66
            . $patron->id
67
            . "/password" => json => { password => $new_password } );
68
69
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
70
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
71
    $t->request_ok($tx)->status_is(400)->json_is({ error => 'Password length (3) is shorter than required (5)' });
72
73
    $new_password = 'abc   ';
74
    $tx
75
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
76
            . $patron->id
77
            . "/password" => json => { password => $new_password } );
78
79
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
80
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
81
    $t->request_ok($tx)->status_is(400)->json_is({ error => 'Password contains trailing spaces, which is forbidden.' });
82
83
    $new_password = 'abcdefg';
84
    $tx
85
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
86
            . $patron->id
87
            . "/password" => json => { password => $new_password } );
88
89
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
90
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
91
    $t->request_ok($tx)->status_is(200)->json_is('');
92
93
    t::lib::Mocks::mock_preference( 'RequireStrongPassword', 1);
94
    $tx
95
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
96
            . $patron->id
97
            . "/password" => json => { password => $new_password } );
98
99
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
100
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
101
    $t->request_ok($tx)->status_is(400)->json_is({ error => 'Password is too weak' });
102
103
    $new_password = 'ABcde123%&';
104
    $tx
105
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
106
            . $patron->id
107
            . "/password" => json => { password => $new_password } );
108
109
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
110
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
111
    $t->request_ok($tx)->status_is(200)->json_is('');
112
113
    $schema->storage->txn_rollback;
114
};
115
116
subtest 'set_password() (unauthorized user tests)' => sub {
117
118
    plan tests => 15;
119
120
    $schema->storage->txn_begin;
121
122
    my ( $patron, $session ) = create_user_and_session({ authorized => 0 });
123
    my $other_patron = $builder->build_object({ class => 'Koha::Patrons' });
124
125
    t::lib::Mocks::mock_preference( 'OpacPasswordChange',    0 );
126
    t::lib::Mocks::mock_preference( 'minPasswordLength',     3 );
127
    t::lib::Mocks::mock_preference( 'RequireStrongPassword', 0 );
128
129
    my $new_password = 'abc';
130
131
    my $tx
132
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
133
            . $other_patron->id
134
            . "/password" => json => { password => $new_password } );
135
136
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
137
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
138
    $t->request_ok($tx)
139
      ->status_is(403)
140
      ->json_is({
141
          error => 'Authorization failure. Missing required permission(s).',
142
          required_permissions => { borrowers => 1 }
143
        });
144
145
    my $password = 'holapassword';
146
    $patron->update_password( $patron->userid, $password );
147
    $tx
148
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
149
            . $other_patron->id
150
            . "/password" => json => { password => $new_password, old_password => $password } );
151
152
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
153
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
154
    $t->request_ok($tx)
155
      ->status_is(403)
156
      ->json_is({
157
          error => 'Authorization failure. Missing required permission(s).',
158
          required_permissions => { borrowers => 1 }
159
        });
160
161
    $tx
162
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
163
            . $patron->id
164
            . "/password" => json => { password => $new_password, old_password => 'badpassword' } );
165
166
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
167
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
168
    $t->request_ok($tx)
169
      ->status_is(400)
170
      ->json_is({
171
          error => 'Configuration prevents password changes by unauthorized users'
172
        });
173
174
    t::lib::Mocks::mock_preference( 'OpacPasswordChange', 1 );
175
176
    $tx
177
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
178
            . $patron->id
179
            . "/password" => json => { password => $new_password, old_password => 'badpassword' } );
180
181
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
182
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
183
    $t->request_ok($tx)
184
      ->status_is(400)
185
      ->json_is({
186
          error => 'Invalid password'
187
        });
188
189
    $tx
190
        = $t->ua->build_tx( POST => "/api/v1/patrons/"
191
            . $patron->id
192
            . "/password" => json => { password => $new_password, old_password => $password } );
193
194
    $tx->req->cookies( { name => 'CGISESSID', value => $session->id } );
195
    $tx->req->env( { REMOTE_ADDR => '127.0.0.1' } );
196
    $t->request_ok($tx)
197
      ->status_is(200)
198
      ->json_is('');
199
200
    $schema->storage->txn_rollback;
201
};
202
203
sub create_user_and_session {
204
205
    my ( $args ) = @_;
206
    my $flags = ( $args->{authorized} ) ? 16 : 0;
207
208
    my $user = $builder->build_object(
209
        {
210
            class => 'Koha::Patrons',
211
            value => { flags => $flags }
212
        }
213
    );
214
215
    # Create a session for the authorized user
216
    my $session = C4::Auth::get_session('');
217
    $session->param( 'number',   $user->borrowernumber );
218
    $session->param( 'id',       $user->userid );
219
    $session->param( 'ip',       '127.0.0.1' );
220
    $session->param( 'lasttime', time() );
221
    $session->flush;
222
223
    return ( $user, $session );
224
}

Return to bug 17006