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

(-)a/t/db_dependent/api/v1/patrons.t (-131 / +124 lines)
Lines 31-42 use Koha::Patron::Debarments qw/AddDebarment/; Link Here
31
my $schema  = Koha::Database->new->schema;
31
my $schema  = Koha::Database->new->schema;
32
my $builder = t::lib::TestBuilder->new;
32
my $builder = t::lib::TestBuilder->new;
33
33
34
# FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
34
my $t = Test::Mojo->new('Koha::REST::V1');
35
# this affects the other REST api tests
35
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
36
t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
37
38
my $remote_address = '127.0.0.1';
39
my $t              = Test::Mojo->new('Koha::REST::V1');
40
36
41
subtest 'list() tests' => sub {
37
subtest 'list() tests' => sub {
42
    plan tests => 2;
38
    plan tests => 2;
Lines 50-89 subtest 'list() tests' => sub { Link Here
50
46
51
        $schema->storage->txn_begin;
47
        $schema->storage->txn_begin;
52
48
53
        my ( $patron_id, $session_id ) = create_user_and_session({ authorized => 1 });
49
        my $librarian = $builder->build_object(
54
        my $patron = Koha::Patrons->find($patron_id);
50
            {
51
                class => 'Koha::Patrons',
52
                value => { flags => 2**4 }    # borrowers flag = 4
53
            }
54
        );
55
        my $password = 'thePassword123';
56
        $librarian->set_password( { password => $password, skip_validation => 1 } );
57
        my $userid = $librarian->userid;
55
58
56
        my $tx = $t->ua->build_tx(GET => '/api/v1/patrons');
59
        $t->get_ok("//$userid:$password@/api/v1/patrons")
57
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
58
        $tx->req->env({ REMOTE_ADDR => '127.0.0.1' });
59
        $t->request_ok($tx)
60
          ->status_is(200);
60
          ->status_is(200);
61
61
62
        $tx = $t->ua->build_tx(GET => '/api/v1/patrons?cardnumber=' . $patron->cardnumber);
62
        $t->get_ok("//$userid:$password@/api/v1/patrons?cardnumber=" . $librarian->cardnumber)
63
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
64
        $tx->req->env({ REMOTE_ADDR => '127.0.0.1' });
65
        $t->request_ok($tx)
66
          ->status_is(200)
63
          ->status_is(200)
67
          ->json_is('/0/cardnumber' => $patron->cardnumber);
64
          ->json_is('/0/cardnumber' => $librarian->cardnumber);
68
65
69
        $tx = $t->ua->build_tx(GET => '/api/v1/patrons?address2='.
66
        $t->get_ok("//$userid:$password@/api/v1/patrons?address2=" . $librarian->address2)
70
                                  $patron->address2);
71
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
72
        $tx->req->env({ REMOTE_ADDR => '127.0.0.1' });
73
        $t->request_ok($tx)
74
          ->status_is(200)
67
          ->status_is(200)
75
          ->json_is('/0/address2' => $patron->address2);
68
          ->json_is('/0/address2' => $librarian->address2);
76
69
77
        my $patron_2 = $builder->build_object({ class => 'Koha::Patrons' });
70
        my $patron = $builder->build_object({ class => 'Koha::Patrons' });
78
        AddDebarment({ borrowernumber => $patron_2->id });
71
        AddDebarment({ borrowernumber => $patron->borrowernumber });
79
        # re-read from DB
72
80
        $patron_2->discard_changes;
73
        $t->get_ok("//$userid:$password@/api/v1/patrons?restricted=" . Mojo::JSON->true . "&cardnumber=" . $patron->cardnumber )
81
        my $ub = $patron_2->unblessed;
82
83
        $tx = $t->ua->build_tx( GET => '/api/v1/patrons?restricted=' . Mojo::JSON->true );
84
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
85
        $tx->req->env({ REMOTE_ADDR => '127.0.0.1' });
86
        $t->request_ok($tx)
87
          ->status_is(200)
74
          ->status_is(200)
88
          ->json_has('/0/restricted')
75
          ->json_has('/0/restricted')
89
          ->json_is( '/0/restricted' => Mojo::JSON->true )
76
          ->json_is( '/0/restricted' => Mojo::JSON->true )
Lines 105-116 subtest 'get() tests' => sub { Link Here
105
92
106
        $schema->storage->txn_begin;
93
        $schema->storage->txn_begin;
107
94
95
        my $librarian = $builder->build_object(
96
            {
97
                class => 'Koha::Patrons',
98
                value => { flags => 2**4 }    # borrowers flag = 4
99
            }
100
        );
101
        my $password = 'thePassword123';
102
        $librarian->set_password( { password => $password, skip_validation => 1 } );
103
        my $userid = $librarian->userid;
104
108
        my $patron = $builder->build_object({ class => 'Koha::Patrons' });
105
        my $patron = $builder->build_object({ class => 'Koha::Patrons' });
109
        my ( undef, $session_id ) = create_user_and_session({ authorized => 1 });
110
106
111
        my $tx = $t->ua->build_tx(GET => "/api/v1/patrons/" . $patron->id);
107
        $t->get_ok("//$userid:$password@/api/v1/patrons/" . $patron->id)
112
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
113
        $t->request_ok($tx)
114
          ->status_is(200)
108
          ->status_is(200)
115
          ->json_is('/patron_id'        => $patron->id)
109
          ->json_is('/patron_id'        => $patron->id)
116
          ->json_is('/category_id'      => $patron->categorycode )
110
          ->json_is('/category_id'      => $patron->categorycode )
Lines 126-133 subtest 'add() tests' => sub { Link Here
126
120
127
    $schema->storage->txn_begin;
121
    $schema->storage->txn_begin;
128
122
129
    my $patron = Koha::REST::V1::Patrons::_to_api(
123
    my $patron = $builder->build_object( { class => 'Koha::Patrons' } )->to_api;
130
        $builder->build_object( { class => 'Koha::Patrons' } )->TO_JSON );
131
124
132
    unauthorized_access_tests('POST', undef, $patron);
125
    unauthorized_access_tests('POST', undef, $patron);
133
126
Lines 139-145 subtest 'add() tests' => sub { Link Here
139
        $schema->storage->txn_begin;
132
        $schema->storage->txn_begin;
140
133
141
        my $patron = $builder->build_object({ class => 'Koha::Patrons' });
134
        my $patron = $builder->build_object({ class => 'Koha::Patrons' });
142
        my $newpatron = Koha::REST::V1::Patrons::_to_api( $patron->TO_JSON );
135
        my $newpatron = $patron->to_api;
143
        # delete RO attributes
136
        # delete RO attributes
144
        delete $newpatron->{patron_id};
137
        delete $newpatron->{patron_id};
145
        delete $newpatron->{restricted};
138
        delete $newpatron->{restricted};
Lines 151-163 subtest 'add() tests' => sub { Link Here
151
        # Delete library
144
        # Delete library
152
        $library_to_delete->delete;
145
        $library_to_delete->delete;
153
146
154
        my ( undef, $session_id ) = create_user_and_session({ authorized => 1 });
147
        my $librarian = $builder->build_object(
148
            {
149
                class => 'Koha::Patrons',
150
                value => { flags => 2**4 }    # borrowers flag = 4
151
            }
152
        );
153
        my $password = 'thePassword123';
154
        $librarian->set_password( { password => $password, skip_validation => 1 } );
155
        my $userid = $librarian->userid;
155
156
156
        $newpatron->{library_id} = $deleted_library_id;
157
        $newpatron->{library_id} = $deleted_library_id;
157
        my $tx = $t->ua->build_tx(POST => "/api/v1/patrons" => json => $newpatron );
158
158
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
159
        warning_like {
159
        warning_like {
160
            $t->request_ok($tx)
160
            $t->post_ok("//$userid:$password@/api/v1/patrons" => json => $newpatron)
161
              ->status_is(409)
161
              ->status_is(409)
162
              ->json_is('/error' => "Duplicate ID"); }
162
              ->json_is('/error' => "Duplicate ID"); }
163
            qr/^DBD::mysql::st execute failed: Duplicate entry/;
163
            qr/^DBD::mysql::st execute failed: Duplicate entry/;
Lines 171-201 subtest 'add() tests' => sub { Link Here
171
        $category_to_delete->delete;
171
        $category_to_delete->delete;
172
172
173
        $newpatron->{category_id} = $deleted_category_id; # Test invalid patron category
173
        $newpatron->{category_id} = $deleted_category_id; # Test invalid patron category
174
        $tx = $t->ua->build_tx(POST => "/api/v1/patrons" => json => $newpatron);
174
175
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
175
        $t->post_ok("//$userid:$password@/api/v1/patrons" => json => $newpatron)
176
        $t->request_ok($tx)
177
          ->status_is(400)
176
          ->status_is(400)
178
          ->json_is('/error' => "Given category_id does not exist");
177
          ->json_is('/error' => "Given category_id does not exist");
179
        $newpatron->{category_id} = $patron->categorycode;
178
        $newpatron->{category_id} = $patron->categorycode;
180
179
181
        $newpatron->{falseproperty} = "Non existent property";
180
        $newpatron->{falseproperty} = "Non existent property";
182
        $tx = $t->ua->build_tx(POST => "/api/v1/patrons" => json => $newpatron);
181
183
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
182
        $t->post_ok("//$userid:$password@/api/v1/patrons" => json => $newpatron)
184
        $t->request_ok($tx)
185
          ->status_is(400);
183
          ->status_is(400);
184
186
        delete $newpatron->{falseproperty};
185
        delete $newpatron->{falseproperty};
187
186
188
        my $patron_to_delete = $builder->build_object({ class => 'Koha::Patrons' });
187
        my $patron_to_delete = $builder->build_object({ class => 'Koha::Patrons' });
189
        $newpatron = Koha::REST::V1::Patrons::_to_api($patron_to_delete->TO_JSON);
188
        $newpatron = $patron_to_delete->to_api;
190
        # delete RO attributes
189
        # delete RO attributes
191
        delete $newpatron->{patron_id};
190
        delete $newpatron->{patron_id};
192
        delete $newpatron->{restricted};
191
        delete $newpatron->{restricted};
193
        delete $newpatron->{anonymized};
192
        delete $newpatron->{anonymized};
194
        $patron_to_delete->delete;
193
        $patron_to_delete->delete;
195
194
196
        $tx = $t->ua->build_tx(POST => "/api/v1/patrons" => json => $newpatron);
195
        $t->post_ok("//$userid:$password@/api/v1/patrons" => json => $newpatron)
197
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
198
        $t->request_ok($tx)
199
          ->status_is(201, 'Patron created successfully')
196
          ->status_is(201, 'Patron created successfully')
200
          ->header_like(
197
          ->header_like(
201
            Location => qr|^\/api\/v1\/patrons/\d*|,
198
            Location => qr|^\/api\/v1\/patrons/\d*|,
Lines 206-215 subtest 'add() tests' => sub { Link Here
206
          ->json_is( '/surname'    => $newpatron->{ surname })
203
          ->json_is( '/surname'    => $newpatron->{ surname })
207
          ->json_is( '/firstname'  => $newpatron->{ firstname });
204
          ->json_is( '/firstname'  => $newpatron->{ firstname });
208
205
209
        $tx = $t->ua->build_tx(POST => "/api/v1/patrons" => json => $newpatron);
210
        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
211
        warning_like {
206
        warning_like {
212
            $t->request_ok($tx)
207
            $t->post_ok("//$userid:$password@/api/v1/patrons" => json => $newpatron)
213
              ->status_is(409)
208
              ->status_is(409)
214
              ->json_has( '/error', 'Fails when trying to POST duplicate cardnumber' )
209
              ->json_has( '/error', 'Fails when trying to POST duplicate cardnumber' )
215
              ->json_has( '/conflict', 'cardnumber' ); }
210
              ->json_has( '/conflict', 'cardnumber' ); }
Lines 231-251 subtest 'update() tests' => sub { Link Here
231
226
232
        $schema->storage->txn_begin;
227
        $schema->storage->txn_begin;
233
228
234
        t::lib::Mocks::mock_preference('minPasswordLength', 1);
229
        my $authorized_patron = $builder->build_object(
235
        my ( $patron_id_1, $session_id ) = create_user_and_session({ authorized => 1 });
230
            {
236
        my ( $patron_id_2, undef )       = create_user_and_session({ authorized => 0 });
231
                class => 'Koha::Patrons',
232
                value => { flags => 2**4 } # borrowers flag = 4
233
            }
234
        );
235
        my $password = 'thePassword123';
236
        $authorized_patron->set_password(
237
            { password => $password, skip_validation => 1 } );
238
        my $userid = $authorized_patron->userid;
239
240
        my $unauthorized_patron = $builder->build_object(
241
            {
242
                class => 'Koha::Patrons',
243
                value => { flags => 0 }
244
            }
245
        );
246
        $unauthorized_patron->set_password( { password => $password, skip_validation => 1 } );
247
        my $unauth_userid = $unauthorized_patron->userid;
237
248
238
        my $patron_1  = Koha::Patrons->find($patron_id_1);
249
        my $patron_1  = $authorized_patron;
239
        my $patron_2  = Koha::Patrons->find($patron_id_2);
250
        my $patron_2  = $unauthorized_patron;
240
        my $newpatron = Koha::REST::V1::Patrons::_to_api($patron_2->TO_JSON);
251
        my $newpatron = $unauthorized_patron->to_api;
241
        # delete RO attributes
252
        # delete RO attributes
242
        delete $newpatron->{patron_id};
253
        delete $newpatron->{patron_id};
243
        delete $newpatron->{restricted};
254
        delete $newpatron->{restricted};
244
        delete $newpatron->{anonymized};
255
        delete $newpatron->{anonymized};
245
256
246
        my $tx = $t->ua->build_tx(PUT => "/api/v1/patrons/-1" => json => $newpatron );
257
        $t->put_ok("//$userid:$password@/api/v1/patrons/-1" => json => $newpatron)
247
        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
248
        $t->request_ok($tx)
249
          ->status_is(404)
258
          ->status_is(404)
250
          ->json_has('/error', 'Fails when trying to PUT nonexistent patron');
259
          ->json_has('/error', 'Fails when trying to PUT nonexistent patron');
251
260
Lines 255-266 subtest 'update() tests' => sub { Link Here
255
        # Delete library
264
        # Delete library
256
        $category_to_delete->delete;
265
        $category_to_delete->delete;
257
266
267
        # Use an invalid category
258
        $newpatron->{category_id} = $deleted_category_id;
268
        $newpatron->{category_id} = $deleted_category_id;
259
        $tx = $t->ua->build_tx(PUT => "/api/v1/patrons/$patron_id_2" => json => $newpatron );
269
260
        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
270
        $t->put_ok("//$userid:$password@/api/v1/patrons/" . $patron_2->borrowernumber => json => $newpatron)
261
        $t->request_ok($tx)
262
          ->status_is(400)
271
          ->status_is(400)
263
          ->json_is('/error' => "Given category_id does not exist");
272
          ->json_is('/error' => "Given category_id does not exist");
273
274
        # Restore the valid category
264
        $newpatron->{category_id} = $patron_2->categorycode;
275
        $newpatron->{category_id} = $patron_2->categorycode;
265
276
266
        # Create a library just to make sure its ID doesn't exist on the DB
277
        # Create a library just to make sure its ID doesn't exist on the DB
Lines 269-313 subtest 'update() tests' => sub { Link Here
269
        # Delete library
280
        # Delete library
270
        $library_to_delete->delete;
281
        $library_to_delete->delete;
271
282
283
        # Use an invalid library_id
272
        $newpatron->{library_id} = $deleted_library_id;
284
        $newpatron->{library_id} = $deleted_library_id;
273
        $tx = $t->ua->build_tx(PUT => "/api/v1/patrons/" . $patron_2->id => json => $newpatron );
285
274
        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
275
        warning_like {
286
        warning_like {
276
            $t->request_ok($tx)
287
            $t->put_ok("//$userid:$password@/api/v1/patrons/" . $patron_2->borrowernumber => json => $newpatron)
277
              ->status_is(400)
288
              ->status_is(400)
278
              ->json_is('/error' => "Given library_id does not exist"); }
289
              ->json_is('/error' => "Given library_id does not exist"); }
279
            qr/^DBD::mysql::st execute failed: Cannot add or update a child row: a foreign key constraint fails/;
290
            qr/^DBD::mysql::st execute failed: Cannot add or update a child row: a foreign key constraint fails/;
291
292
        # Restore the valid library_id
280
        $newpatron->{library_id} = $patron_2->branchcode;
293
        $newpatron->{library_id} = $patron_2->branchcode;
281
294
295
        # Use an invalid attribute
282
        $newpatron->{falseproperty} = "Non existent property";
296
        $newpatron->{falseproperty} = "Non existent property";
283
        $tx = $t->ua->build_tx(PUT => "/api/v1/patrons/" . $patron_2->id => json => $newpatron );
297
284
        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
298
        $t->put_ok( "//$userid:$password@/api/v1/patrons/" . $patron_2->borrowernumber => json => $newpatron )
285
        $t->request_ok($tx)
286
          ->status_is(400)
299
          ->status_is(400)
287
          ->json_is('/errors/0/message' =>
300
          ->json_is('/errors/0/message' =>
288
                    'Properties not allowed: falseproperty.');
301
                    'Properties not allowed: falseproperty.');
302
303
        # Get rid of the invalid attribute
289
        delete $newpatron->{falseproperty};
304
        delete $newpatron->{falseproperty};
290
305
291
        # Set both cardnumber and userid to already existing values
306
        # Set both cardnumber and userid to already existing values
292
        $newpatron->{cardnumber} = $patron_1->cardnumber;
307
        $newpatron->{cardnumber} = $patron_1->cardnumber;
293
        $newpatron->{userid}     = $patron_1->userid;
308
        $newpatron->{userid}     = $patron_1->userid;
294
309
295
        $tx = $t->ua->build_tx( PUT => "/api/v1/patrons/" . $patron_2->id => json => $newpatron );
296
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
297
        warning_like {
310
        warning_like {
298
            $t->request_ok($tx)
311
            $t->put_ok( "//$userid:$password@/api/v1/patrons/" . $patron_2->borrowernumber => json => $newpatron )
299
              ->status_is(409)
312
              ->status_is(409)
300
              ->json_has( '/error' => "Fails when trying to update to an existing cardnumber or userid")
313
              ->json_has( '/error' => "Fails when trying to update to an existing cardnumber or userid")
301
              ->json_is(  '/conflict', 'cardnumber' ); }
314
              ->json_is(  '/conflict', 'cardnumber' ); }
302
            qr/^DBD::mysql::st execute failed: Duplicate entry '(.*?)' for key 'cardnumber'/;
315
            qr/^DBD::mysql::st execute failed: Duplicate entry '(.*?)' for key 'cardnumber'/;
303
316
304
        $newpatron->{ cardnumber } = $patron_id_1.$patron_id_2;
317
        $newpatron->{ cardnumber } = $patron_1->id . $patron_2->id;
305
        $newpatron->{ userid }     = "user".$patron_id_1.$patron_id_2;
318
        $newpatron->{ userid }     = "user" . $patron_1->id.$patron_2->id;
306
        $newpatron->{ surname }    = "user".$patron_id_1.$patron_id_2;
319
        $newpatron->{ surname }    = "user" . $patron_1->id.$patron_2->id;
307
320
308
        $tx = $t->ua->build_tx(PUT => "/api/v1/patrons/" . $patron_2->id => json => $newpatron);
321
        $t->put_ok( "//$userid:$password@/api/v1/patrons/" . $patron_2->borrowernumber => json => $newpatron )
309
        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
310
        $t->request_ok($tx)
311
          ->status_is(200, 'Patron updated successfully')
322
          ->status_is(200, 'Patron updated successfully')
312
          ->json_has($newpatron);
323
          ->json_has($newpatron);
313
        is(Koha::Patrons->find( $patron_2->id )->cardnumber,
324
        is(Koha::Patrons->find( $patron_2->id )->cardnumber,
Lines 329-345 subtest 'delete() tests' => sub { Link Here
329
340
330
        $schema->storage->txn_begin;
341
        $schema->storage->txn_begin;
331
342
332
        my ( undef, $session_id ) = create_user_and_session({ authorized => 1 });
343
        my $authorized_patron = $builder->build_object(
333
        my ( $patron_id, undef )  = create_user_and_session({ authorized => 0 });
344
            {
345
                class => 'Koha::Patrons',
346
                value => { flags => 2**4 }    # borrowers flag = 4
347
            }
348
        );
349
        my $password = 'thePassword123';
350
        $authorized_patron->set_password(
351
            { password => $password, skip_validation => 1 } );
352
        my $userid = $authorized_patron->userid;
334
353
335
        my $tx = $t->ua->build_tx(DELETE => "/api/v1/patrons/-1");
354
        $t->delete_ok("//$userid:$password@/api/v1/patrons/-1")
336
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
337
        $t->request_ok($tx)
338
          ->status_is(404, 'Patron not found');
355
          ->status_is(404, 'Patron not found');
339
356
340
        $tx = $t->ua->build_tx(DELETE => "/api/v1/patrons/$patron_id");
357
        my $patron = $builder->build_object({ class => 'Koha::Patrons' });
341
        $tx->req->cookies({ name => 'CGISESSID', value => $session_id });
358
342
        $t->request_ok($tx)
359
        $t->delete_ok("//$userid:$password@/api/v1/patrons/" . $patron->borrowernumber)
343
          ->status_is(200, 'Patron deleted successfully');
360
          ->status_is(200, 'Patron deleted successfully');
344
361
345
        $schema->storage->txn_rollback;
362
        $schema->storage->txn_rollback;
Lines 433-479 sub unauthorized_access_tests { Link Here
433
    subtest 'unauthorized access tests' => sub {
450
    subtest 'unauthorized access tests' => sub {
434
        plan tests => 5;
451
        plan tests => 5;
435
452
436
        my $tx = $t->ua->build_tx($verb => $endpoint => json => $json);
453
        my $verb_ok = lc($verb) . '_ok';
437
        $t->request_ok($tx)
454
455
        $t->$verb_ok($endpoint => json => $json)
438
          ->status_is(401);
456
          ->status_is(401);
439
457
440
        my ($borrowernumber, $session_id) = create_user_and_session({
458
        my $unauthorized_patron = $builder->build_object(
441
            authorized => 0 });
459
            {
460
                class => 'Koha::Patrons',
461
                value => { flags => 0 }
462
            }
463
        );
464
        my $password = "thePassword123!";
465
        $unauthorized_patron->set_password(
466
            { password => $password, skip_validation => 1 } );
467
        my $unauth_userid = $unauthorized_patron->userid;
442
468
443
        $tx = $t->ua->build_tx($verb => $endpoint => json => $json);
469
        $t->$verb_ok( "//$unauth_userid:$password\@$endpoint" => json => $json )
444
        $tx->req->cookies({name => 'CGISESSID', value => $session_id});
445
        $t->request_ok($tx)
446
          ->status_is(403)
470
          ->status_is(403)
447
          ->json_has('/required_permissions');
471
          ->json_has('/required_permissions');
448
    };
472
    };
449
}
473
}
450
451
sub create_user_and_session {
452
453
    my $args  = shift;
454
    my $flags = ( $args->{authorized} ) ? 16 : 0;
455
456
    my $user = $builder->build(
457
        {
458
            source => 'Borrower',
459
            value  => {
460
                flags => $flags,
461
                gonenoaddress => 0,
462
                lost => 0,
463
                email => 'nobody@example.com',
464
                emailpro => 'nobody@example.com',
465
                B_email => 'nobody@example.com'
466
            }
467
        }
468
    );
469
470
    # Create a session for the authorized user
471
    my $session = C4::Auth::get_session('');
472
    $session->param( 'number',   $user->{borrowernumber} );
473
    $session->param( 'id',       $user->{userid} );
474
    $session->param( 'ip',       '127.0.0.1' );
475
    $session->param( 'lasttime', time() );
476
    $session->flush;
477
478
    return ( $user->{borrowernumber}, $session->id );
479
}
480
- 

Return to bug 23860