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

(-)a/Koha/REST/V1/Auth.pm (+73 lines)
Line 0 Link Here
1
package Koha::REST::V1::Auth;
2
3
# Copyright 2016 Koha-Suomi
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use Mojo::Base 'Mojolicious::Controller';
23
24
use Koha::Patrons;
25
use C4::Auth;
26
27
use CGI;
28
29
sub login {
30
    my ($c, $args, $cb) = @_;
31
32
    my $userid = $args->{userid} || $args->{cardnumber};
33
    my $password = $args->{password};
34
    my $patron;
35
36
    return $c->$cb({ error => "Either userid or cardnumber is required "
37
                             ."- neither given." }, 403) unless ($userid);
38
39
    my $cgi = CGI->new;
40
    $cgi->param(userid => $userid);
41
    $cgi->param(password => $password);
42
    my ($status, $cookie, $sessionid) = C4::Auth::check_api_auth($cgi);
43
44
    return $c->$cb({ error => "Login failed." }, 401) if $status eq "failed";
45
    return $c->$cb({ error => "Session expired." }, 401) if $status eq "expired";
46
    return $c->$cb({ error => "Database is under maintenance." }, 401) if $status eq "maintenance";
47
    return $c->$cb({ error => "Login failed." }, 401) unless $status eq "ok";
48
49
    $patron = Koha::Patrons->find({ userid => $userid }) unless $patron;
50
    $patron = Koha::Patrons->find({ cardnumber => $userid }) unless $patron;
51
52
    my $session = _swaggerize_session($sessionid, $patron);
53
54
    $c->cookie(CGISESSID => $sessionid, { path => "/" });
55
56
    return $c->$cb($session, 201);
57
}
58
59
sub _swaggerize_session {
60
    my ($sessionid, $patron) = @_;
61
62
    return unless ref($patron) eq 'Koha::Patron';
63
64
    return {
65
        borrowernumber => $patron->borrowernumber,
66
        firstname => $patron->firstname,
67
        surname  => $patron->surname,
68
        email     => $patron->email,
69
        sessionid => $sessionid,
70
    };
71
}
72
73
1;
(-)a/api/v1/definitions/index.json (+1 lines)
Lines 1-4 Link Here
1
{
1
{
2
    "session": { "$ref": "session.json" },
2
    "patron": { "$ref": "patron.json" },
3
    "patron": { "$ref": "patron.json" },
3
    "holds": { "$ref": "holds.json" },
4
    "holds": { "$ref": "holds.json" },
4
    "hold": { "$ref": "hold.json" },
5
    "hold": { "$ref": "hold.json" },
(-)a/api/v1/definitions/session.json (+25 lines)
Line 0 Link Here
1
{
2
  "type": "object",
3
  "properties": {
4
    "borrowernumber": {
5
      "type": "string",
6
      "description": "internally assigned user identifier"
7
    },
8
    "email": {
9
      "type": ["string", "null"],
10
      "description": "primary email address for patron's primary address"
11
    },
12
    "surname": {
13
      "type": "string",
14
      "description": "patron's last name"
15
    },
16
    "firstname": {
17
      "type": ["string", "null"],
18
      "description": "patron's first name"
19
    },
20
    "sessionid": {
21
      "description": "Koha Session identifier",
22
      "type": "string"
23
    }
24
  }
25
}
(-)a/api/v1/swagger.json (+50 lines)
Lines 14-19 Link Here
14
  },
14
  },
15
  "basePath": "/api/v1",
15
  "basePath": "/api/v1",
16
  "paths": {
16
  "paths": {
17
    "/auth/session": {
18
      "post": {
19
        "operationId": "loginAuth",
20
        "tags": ["auth"],
21
        "summary": "Login to Koha and get a session cookie",
22
        "description": "Makes a 'normal' username + password login to Koha, and returns the sessionid you need put to the CGISESSID-cookie. Koha uses this cookie to track a session.\nBe aware that the authenticated session most probably is IP-locked so authenticating from one IP and passing the session to another wont work.",
23
        "parameters": [
24
          { "$ref": "#/parameters/cardnumberPostParam" },
25
          { "$ref": "#/parameters/useridPostParam" },
26
          { "$ref": "#/parameters/passwordPostParam" }
27
        ],
28
        "produces": [
29
          "application/json"
30
        ],
31
        "responses": {
32
          "201": {
33
            "description": "A borrower with SSO-relevant fields",
34
            "schema": {
35
              "$ref": "#/definitions/session"
36
            }
37
          },
38
          "401": {
39
            "description": "Bad username/cardnumber and/or password",
40
            "schema": {
41
              "$ref": "#/definitions/error"
42
            }
43
          }
44
        }
45
      }
46
    },
17
    "/patrons": {
47
    "/patrons": {
18
      "get": {
48
      "get": {
19
        "operationId": "listPatrons",
49
        "operationId": "listPatrons",
Lines 345-356 Link Here
345
      "required": true,
375
      "required": true,
346
      "type": "integer"
376
      "type": "integer"
347
    },
377
    },
378
    "cardnumberPostParam": {
379
      "name": "cardnumber",
380
      "in": "formData",
381
      "description": "Borrower's card's barcode/identifier",
382
      "required": false,
383
      "type": "string"
384
    },
348
    "holdIdPathParam": {
385
    "holdIdPathParam": {
349
      "name": "reserve_id",
386
      "name": "reserve_id",
350
      "in": "path",
387
      "in": "path",
351
      "description": "Internal hold identifier",
388
      "description": "Internal hold identifier",
352
      "required": true,
389
      "required": true,
353
      "type": "integer"
390
      "type": "integer"
391
    },
392
    "passwordPostParam": {
393
      "name": "password",
394
      "in": "formData",
395
      "required": true,
396
      "type": "string"
397
    },
398
    "useridPostParam": {
399
      "name": "userid",
400
      "in": "formData",
401
      "description": "The userid of the Borrower, unique value",
402
      "required": false,
403
      "type": "string"
354
    }
404
    }
355
  }
405
  }
356
}
406
}
(-)a/t/db_dependent/api/v1/auth.t (-1 / +101 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/env perl
2
3
# Copyright 2016 Koha-Suomi
4
#
5
# This file is part of Koha.
6
#
7
# Koha is free software; you can redistribute it and/or modify it under the
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 3 of the License, or (at your option) any later
10
# version.
11
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License along
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19
20
use Modern::Perl;
21
22
use Test::More tests => 20;
23
use Test::Mojo;
24
25
use t::lib::TestBuilder;
26
27
use C4::Context;
28
use Koha::AuthUtils;
29
30
my $builder = t::lib::TestBuilder->new();
31
32
my $dbh = C4::Context->dbh;
33
$dbh->{AutoCommit} = 0;
34
$dbh->{RaiseError} = 1;
35
36
$ENV{REMOTE_ADDR} = '127.0.0.1';
37
my $t = Test::Mojo->new('Koha::REST::V1');
38
39
my $categorycode = $builder->build({ source => 'Category' })->{ categorycode };
40
my $branchcode = $builder->build({ source => 'Branch' })->{ branchcode };
41
my $password = "2anxious? if someone finds out";
42
43
my $borrower = $builder->build({
44
    source => 'Borrower',
45
    value => {
46
        branchcode   => $branchcode,
47
        categorycode => $categorycode,
48
        password => Koha::AuthUtils::hash_password($password),
49
    }
50
});
51
52
my $auth_by_userid = {
53
    userid => $borrower->{userid},
54
    password => $password,
55
};
56
my $auth_by_cardnumber = {
57
    cardnumber => $borrower->{cardnumber},
58
    password => $password,
59
};
60
my $invalid_login = {
61
    userid => $borrower->{userid},
62
    password => "please let me in",
63
};
64
my $invalid_login2 = {
65
    cardnumber => $borrower->{cardnumber},
66
    password => "my password is password, don't tell anyone",
67
};
68
69
my $tx = $t->ua->build_tx(POST => '/api/v1/auth/session' => form => $auth_by_userid);
70
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
71
$t->request_ok($tx)
72
  ->status_is(201)
73
  ->json_is('/firstname', $borrower->{firstname})
74
  ->json_is('/surname', $borrower->{surname})
75
  ->json_is('/borrowernumber', $borrower->{borrowernumber})
76
  ->json_is('/email', $borrower->{email})
77
  ->json_has('/sessionid');
78
79
$tx = $t->ua->build_tx(POST => '/api/v1/auth/session' => form => $auth_by_cardnumber);
80
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
81
$t->request_ok($tx)
82
  ->status_is(201)
83
  ->json_is('/firstname', $borrower->{firstname})
84
  ->json_is('/surname', $borrower->{surname})
85
  ->json_is('/borrowernumber', $borrower->{borrowernumber})
86
  ->json_is('/email', $borrower->{email})
87
  ->json_has('/sessionid');
88
89
$tx = $t->ua->build_tx(POST => '/api/v1/auth/session' => form => $invalid_login);
90
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
91
$t->request_ok($tx)
92
  ->status_is(401)
93
  ->json_is('/error', "Login failed.");
94
95
$tx = $t->ua->build_tx(POST => '/api/v1/auth/session' => form => $invalid_login2);
96
$tx->req->env({REMOTE_ADDR => '127.0.0.1'});
97
$t->request_ok($tx)
98
  ->status_is(401)
99
  ->json_is('/error', "Login failed.");
100
101
$dbh->rollback;

Return to bug 17004