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

(-)a/installer/data/mysql/atomicupdate/bug_20568_api_keys.perl (+7 lines)
Lines 24-29 if(CheckVersion($DBversion)) { Link Here
24
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
24
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
25
    });
25
    });
26
26
27
    $dbh->do(q{
28
        INSERT IGNORE INTO `systempreferences`
29
            (variable,value,explanation,options,type)
30
        VALUES
31
            ('AllowPatronsManageAPIKeysInOPAC', '0', 'If enabled, patrons can manage their own API keys in the OPAC', NULL, 'YesNo');
32
    });
33
27
    print "Upgrade to $DBversion done (Bug 20568 - Add API key management interface for patrons)\n";
34
    print "Upgrade to $DBversion done (Bug 20568 - Add API key management interface for patrons)\n";
28
    SetVersion($DBversion);
35
    SetVersion($DBversion);
29
}
36
}
(-)a/installer/data/mysql/sysprefs.sql (+1 lines)
Lines 30-35 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
30
('AllowNotForLoanOverride','0','','If ON, Koha will allow the librarian to loan a not for loan item.','YesNo'),
30
('AllowNotForLoanOverride','0','','If ON, Koha will allow the librarian to loan a not for loan item.','YesNo'),
31
('AllowOfflineCirculation','0','','If on, enables HTML5 offline circulation functionality.','YesNo'),
31
('AllowOfflineCirculation','0','','If on, enables HTML5 offline circulation functionality.','YesNo'),
32
('AllowPatronToSetCheckoutsVisibilityForGuarantor',  '0', NULL, 'If enabled, the patron can set checkouts to be visible to his or her guarantor',  'YesNo'),
32
('AllowPatronToSetCheckoutsVisibilityForGuarantor',  '0', NULL, 'If enabled, the patron can set checkouts to be visible to his or her guarantor',  'YesNo'),
33
('AllowPatronsManageAPIKeysInOPAC', '0', NULL, 'If enabled, patrons can manage their own API keys in the OPAC',  'YesNo'),
33
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
34
('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
34
('AllowPurchaseSuggestionBranchChoice','0','1','Allow user to choose branch when making a purchase suggestion','YesNo'),
35
('AllowPurchaseSuggestionBranchChoice','0','1','Allow user to choose branch when making a purchase suggestion','YesNo'),
35
('AllowRenewalIfOtherItemsAvailable','0',NULL,'If enabled, allow a patron to renew an item with unfilled holds if other available items can fill that hold.','YesNo'),
36
('AllowRenewalIfOtherItemsAvailable','0',NULL,'If enabled, allow a patron to renew an item with unfilled holds if other available items can fill that hold.','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/web_services.pref (+6 lines)
Lines 5-10 Web services: Link Here
5
            - pref: "RESTdefaultPageSize"
5
            - pref: "RESTdefaultPageSize"
6
              class: integer
6
              class: integer
7
            - "per page"
7
            - "per page"
8
        -
9
            - pref: AllowPatronsManageAPIKeysInOPAC
10
              choices:
11
                  yes: Allow
12
                  no: "Don't allow"
13
            - "patrons to manage their own API keys in the OPAC."
8
    OAI-PMH:
14
    OAI-PMH:
9
        -
15
        -
10
            - pref: OAI-PMH
16
            - pref: OAI-PMH
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/apikeys.tt (-4 / +4 lines)
Lines 1-6 Link Here
1
[% USE Koha %]
1
[% USE Koha %]
2
[% INCLUDE 'doc-head-open.inc' %]
2
[% INCLUDE 'doc-head-open.inc' %]
3
<title>Koha &rsaquo; Patrons [% IF ( searching ) %]&rsaquo; API Keys[% END %]</title>
3
<title>Koha &rsaquo; Patrons &rsaquo; API Keys</title>
4
[% INCLUDE 'doc-head-close.inc' %]
4
[% INCLUDE 'doc-head-close.inc' %]
5
</head>
5
</head>
6
<body id="pat_apikeys" class="pat">
6
<body id="pat_apikeys" class="pat">
Lines 56-72 Link Here
56
                      <input type="hidden" name="patron_id" value="[% patron.id %]">
56
                      <input type="hidden" name="patron_id" value="[% patron.id %]">
57
                      <input type="hidden" name="key" value="[% key.value %]">
57
                      <input type="hidden" name="key" value="[% key.value %]">
58
                      <input type="hidden" name="op" value="delete">
58
                      <input type="hidden" name="op" value="delete">
59
                      <input type="submit" value="Delete">
59
                      <button class="btn btn-default btn-sm" type="submit">Delete</button>
60
                    </form>
60
                    </form>
61
                    <form action="/cgi-bin/koha/members/apikeys.pl" method="post">
61
                    <form action="/cgi-bin/koha/members/apikeys.pl" method="post">
62
                      <input type="hidden" name="patron_id" value="[% patron.id %]">
62
                      <input type="hidden" name="patron_id" value="[% patron.id %]">
63
                      <input type="hidden" name="key" value="[% key.value %]">
63
                      <input type="hidden" name="key" value="[% key.value %]">
64
                      [% IF key.active %]
64
                      [% IF key.active %]
65
                        <input type="hidden" name="op" value="revoke">
65
                        <input type="hidden" name="op" value="revoke">
66
                        <input type="submit" value="Revoke">
66
                        <button class="btn btn-default btn-sm" type="submit">Revoke</button>
67
                      [% ELSE %]
67
                      [% ELSE %]
68
                        <input type="hidden" name="op" value="activate">
68
                        <input type="hidden" name="op" value="activate">
69
                        <input type="submit" value="Activate">
69
                        <button class="btn btn-default btn-sm" type="submit">Activate</button>
70
                      [% END %]
70
                      [% END %]
71
                    </form>
71
                    </form>
72
                  </td>
72
                  </td>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/includes/usermenu.inc (-5 / +8 lines)
Lines 115-126 Link Here
115
                <a href="/cgi-bin/koha/opac-illrequests.pl">your interlibrary loan requests</a></li>
115
                <a href="/cgi-bin/koha/opac-illrequests.pl">your interlibrary loan requests</a></li>
116
            [% END %]
116
            [% END %]
117
117
118
            [% IF apikeysview %]
118
119
              <li class="active">
119
            [% IF Koha.Preference('AllowPatronsManageAPIKeysInOPAC') %]
120
            [% ELSE %]
120
                [% IF apikeysview %]
121
              <li>
121
                  <li class="active">
122
                [% ELSE %]
123
                  <li>
124
                [% END %]
125
                  <a href="/cgi-bin/koha/opac-apikeys.pl">your API keys</a>
122
            [% END %]
126
            [% END %]
123
              <a href="/cgi-bin/koha/opac-apikeys.pl">your API keys</a>
124
            </li>
127
            </li>
125
        </ul>
128
        </ul>
126
    </div>
129
    </div>
(-)a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-apikeys.tt (-11 / +18 lines)
Lines 1-5 Link Here
1
[% INCLUDE 'doc-head-open.inc' %]
1
[% INCLUDE 'doc-head-open.inc' %]
2
[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Your library home
2
<title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Your API keys</title>
3
[% INCLUDE 'doc-head-close.inc' %]
3
[% INCLUDE 'doc-head-close.inc' %]
4
[% BLOCK cssinclude %][% END %]
4
[% BLOCK cssinclude %][% END %]
5
</head>
5
</head>
Lines 11-17 Link Here
11
        <li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">&rsaquo;</span></li>
11
        <li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">&rsaquo;</span></li>
12
        <li>
12
        <li>
13
          <a href="/cgi-bin/koha/opac-user.pl">
13
          <a href="/cgi-bin/koha/opac-user.pl">
14
            [% INCLUDE 'patron-title.inc' category_type = borrower.category_type firstname = borrower.firstname surname = borrower.surname othernames = borrower.othernames %]
14
            [% INCLUDE 'patron-title.inc' category_type=patron.category.category_type firstname=patron.firstname surname=patron.surname othernames=patron.othernames %]
15
          </a>
15
          </a>
16
          <span class="divider">&rsaquo;</span>
16
          <span class="divider">&rsaquo;</span>
17
        </li>
17
        </li>
Lines 30-43 Link Here
30
                  <h1>Your API keys</h1>
30
                  <h1>Your API keys</h1>
31
                  <div>
31
                  <div>
32
                    <form action="/cgi-bin/koha/opac-apikeys.pl" method="post">
32
                    <form action="/cgi-bin/koha/opac-apikeys.pl" method="post">
33
                      <input type="hidden" name="op" value="generate">
33
                        <input type="hidden" name="patron_id" value="[% patron.id %]">
34
                      <input type="submit" value="Generate new key">
34
                        <input type="hidden" name="op" value="generate">
35
                        <label for="description">Description: </label>
36
                        <input type="text" name="description">
37
                        <button class="btn btn-default btn-sm" type="submit"><i class="fa fa-plus"></i> Generate a new key</span></button>
35
                    </form>
38
                    </form>
36
                  </div>
39
                  </div>
37
                  [% IF api_keys.size > 0 %]
40
                  [% IF api_keys && api_keys.size > 0 %]
38
                    <table class="table table-bordered table-striped">
41
                    <table class="table table-bordered table-striped">
39
                      <thead>
42
                      <thead>
40
                        <tr>
43
                        <tr>
44
                          <th>Description</th>
41
                          <th>Key</th>
45
                          <th>Key</th>
42
                          <th>Active</th>
46
                          <th>Active</th>
43
                          <th>Actions</th>
47
                          <th>Actions</th>
Lines 46-67 Link Here
46
                      <tbody>
50
                      <tbody>
47
                        [% FOREACH key IN api_keys %]
51
                        [% FOREACH key IN api_keys %]
48
                          <tr>
52
                          <tr>
49
                            <td>[% key.api_key %]</td>
53
                            <td>[% key.description %]</td>
54
                            <td>[% key.value %]</td>
50
                            <td>[% IF key.active %]Yes[% ELSE %]No[% END %]</td>
55
                            <td>[% IF key.active %]Yes[% ELSE %]No[% END %]</td>
51
                            <td>
56
                            <td>
52
                              <form action="/cgi-bin/koha/opac-apikeys.pl" method="post" class="form-inline">
57
                              <form action="/cgi-bin/koha/opac-apikeys.pl" method="post" class="form-inline">
53
                                <input type="hidden" name="key" value="[% key.api_key %]">
58
                                <input type="hidden" name="key" value="[% key.value %]">
54
                                <input type="hidden" name="op" value="delete">
59
                                <input type="hidden" name="op" value="delete">
55
                                <input type="submit" value="Delete">
60
                                <button class="btn btn-default btn-sm" type="submit">Delete</button>
56
                              </form>
61
                              </form>
57
                              <form action="/cgi-bin/koha/opac-apikeys.pl" method="post" class="form-inline">
62
                              <form action="/cgi-bin/koha/opac-apikeys.pl" method="post" class="form-inline">
58
                                <input type="hidden" name="key" value="[% key.api_key %]">
63
                                <input type="hidden" name="key" value="[% key.value %]">
59
                                [% IF key.active %]
64
                                [% IF key.active %]
60
                                  <input type="hidden" name="op" value="revoke">
65
                                  <input type="hidden" name="op" value="revoke">
61
                                  <input type="submit" value="Revoke">
66
                                  <button class="btn btn-default btn-sm" type="submit">Revoke</button>
62
                                [% ELSE %]
67
                                [% ELSE %]
63
                                  <input type="hidden" name="op" value="activate">
68
                                  <input type="hidden" name="op" value="activate">
64
                                  <input type="submit" value="Activate">
69
                                  <button class="btn btn-default btn-sm" type="submit">Activate</button>
65
                                [% END %]
70
                                [% END %]
66
                              </form>
71
                              </form>
67
                            </td>
72
                            </td>
Lines 69-74 Link Here
69
                        [% END %]
74
                        [% END %]
70
                      </tbody>
75
                      </tbody>
71
                    </table>
76
                    </table>
77
                  [% ELSE %]
78
                    <span class="warn">No keys defined for the current patron.</span>
72
                  [% END %]
79
                  [% END %]
73
                </div> <!-- /#apikeys -->
80
                </div> <!-- /#apikeys -->
74
            </div> <!-- /.span10 -->
81
            </div> <!-- /.span10 -->
(-)a/opac/opac-apikeys.pl (-33 / +41 lines)
Lines 1-52 Link Here
1
#!/usr/bin/env perl
1
#!/usr/bin/env perl
2
2
3
# Copyright 2015 BibLibre
4
#
5
# This file is part of Koha.
3
# This file is part of Koha.
6
#
4
#
7
# Koha is free software; you can redistribute it and/or modify it under the
5
# Copyright 2015 BibLibre
8
# terms of the GNU General Public License as published by the Free Software
9
# Foundation; either version 2 of the License, or (at your option) any later
10
# version.
11
#
6
#
12
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
7
# Koha is free software; you can redistribute it and/or modify it
13
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
8
# under the terms of the GNU General Public License as published by
14
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
15
#
11
#
16
# You should have received a copy of the GNU General Public License along
12
# Koha is distributed in the hope that it will be useful, but
17
# with Koha; if not, write to the Free Software Foundation, Inc.,
13
# WITHOUT ANY WARRANTY; without even the implied warranty of
18
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
16
#
17
# You should have received a copy of the GNU General Public License
18
# along with Koha; if not, see <http://www.gnu.org/licenses>.
19
19
20
use Modern::Perl;
20
use Modern::Perl;
21
21
22
use CGI;
22
use CGI;
23
use String::Random;
24
23
25
use C4::Auth;
24
use C4::Auth;
26
use C4::Members;
27
use C4::Output;
25
use C4::Output;
26
28
use Koha::ApiKeys;
27
use Koha::ApiKeys;
29
use Koha::ApiKey;
28
use Koha::Patrons;
30
29
31
my $cgi = new CGI;
30
my $cgi = new CGI;
32
31
33
my ($template, $loggedinuser, $cookie) = get_template_and_user({
32
my ($template, $loggedinuser, $cookie) = get_template_and_user({
34
    template_name => 'opac-apikeys.tt',
33
    template_name   => 'opac-apikeys.tt',
35
    query => $cgi,
34
    query           => $cgi,
36
    type => 'opac',
35
    type            => 'opac',
37
    authnotrequired => 0,
36
    authnotrequired => 0
38
    flagsrequired => {borrow => 1},
39
});
37
});
40
38
41
my $borrowernumber = $loggedinuser;
39
my $patron_id = $loggedinuser;
42
my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber);
40
my $patron = Koha::Patrons->find( $patron_id );
41
42
if ( not defined $patron
43
    or C4::Context->preference('AllowPatronsManageAPIKeysInOPAC') )
44
{
45
    # patron_id invalid -> exit
46
    print $cgi->redirect("/cgi-bin/koha/errors/404.pl");    # escape early
47
    exit;
48
}
49
50
43
my $op = $cgi->param('op');
51
my $op = $cgi->param('op');
44
52
45
if ($op) {
53
if ($op) {
46
    if ($op eq 'generate') {
54
    if ($op eq 'generate') {
47
        my $apikey = new Koha::ApiKey;
55
        my $description = $cgi->param('description') // '';
48
        $apikey->borrowernumber($borrowernumber);
56
        my $apikey = Koha::ApiKey->new({
49
        $apikey->api_key(String::Random->new->randregex('[a-zA-Z0-9]{32}'));
57
            patron_id   => $patron_id,
58
            description => $description
59
        });
50
        $apikey->store;
60
        $apikey->store;
51
        print $cgi->redirect('/cgi-bin/koha/opac-apikeys.pl');
61
        print $cgi->redirect('/cgi-bin/koha/opac-apikeys.pl');
52
        exit;
62
        exit;
Lines 54-60 if ($op) { Link Here
54
64
55
    if ($op eq 'delete') {
65
    if ($op eq 'delete') {
56
        my $key = $cgi->param('key');
66
        my $key = $cgi->param('key');
57
        my $api_key = Koha::ApiKeys->find({borrowernumber => $borrowernumber, api_key => $key});
67
        my $api_key = Koha::ApiKeys->find({ patron_id => $patron_id, value => $key});
58
        if ($api_key) {
68
        if ($api_key) {
59
            $api_key->delete;
69
            $api_key->delete;
60
        }
70
        }
Lines 64-70 if ($op) { Link Here
64
74
65
    if ($op eq 'revoke') {
75
    if ($op eq 'revoke') {
66
        my $key = $cgi->param('key');
76
        my $key = $cgi->param('key');
67
        my $api_key = Koha::ApiKeys->find({borrowernumber => $borrowernumber, api_key => $key});
77
        my $api_key = Koha::ApiKeys->find({ patron_id => $patron_id, value => $key });
68
        if ($api_key) {
78
        if ($api_key) {
69
            $api_key->active(0);
79
            $api_key->active(0);
70
            $api_key->store;
80
            $api_key->store;
Lines 75-81 if ($op) { Link Here
75
85
76
    if ($op eq 'activate') {
86
    if ($op eq 'activate') {
77
        my $key = $cgi->param('key');
87
        my $key = $cgi->param('key');
78
        my $api_key = Koha::ApiKeys->find({borrowernumber => $borrowernumber, api_key => $key});
88
        my $api_key = Koha::ApiKeys->find({ patron_id => $patron_id, value => $key });
79
        if ($api_key) {
89
        if ($api_key) {
80
            $api_key->active(1);
90
            $api_key->active(1);
81
            $api_key->store;
91
            $api_key->store;
Lines 85-97 if ($op) { Link Here
85
    }
95
    }
86
}
96
}
87
97
88
my @api_keys = Koha::ApiKeys->search({borrowernumber => $borrowernumber});
98
my @api_keys = Koha::ApiKeys->search({ patron_id => $patron_id });
89
99
90
$template->param(
100
$template->param(
101
    api_keys    => \@api_keys,
91
    apikeysview => 1,
102
    apikeysview => 1,
92
    api_keys => \@api_keys,
103
    patron      => $patron
93
    borrower => $borrower,
94
    borrowernumber => $borrowernumber,
95
);
104
);
96
105
97
output_html_with_http_headers $cgi, $cookie, $template->output;
106
output_html_with_http_headers $cgi, $cookie, $template->output;
98
- 

Return to bug 20568