Bug 20568: API key management for OPAC users
authorTomas Cohen Arazi <tomascohen@theke.io>
Sat, 14 Apr 2018 20:38:03 +0000 (17:38 -0300)
committerJonathan Druart <jonathan.druart@bugs.koha-community.org>
Wed, 9 May 2018 15:55:58 +0000 (12:55 -0300)
This patch makes the OPAC interface for API keys management work
with the new lib. Verify all actions work for a logged user.

Users without login should be redirected to an error page.

The AllowPatronsManageAPIKeysInOPAC syspref is added to control if the
OPAC feature is enabled or not.

To test:
- Verify the syspref works
- Verify users can manage their API keys

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Julian Maurice <julian.maurice@biblibre.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>

installer/data/mysql/atomicupdate/bug_20568_api_keys.perl
installer/data/mysql/sysprefs.sql
koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/web_services.pref
koha-tmpl/intranet-tmpl/prog/en/modules/members/apikeys.tt
koha-tmpl/opac-tmpl/bootstrap/en/includes/usermenu.inc
koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-apikeys.tt
opac/opac-apikeys.pl

index 7467a10..5748a01 100644 (file)
@@ -24,6 +24,13 @@ if(CheckVersion($DBversion)) {
         ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
     });
 
+    $dbh->do(q{
+        INSERT IGNORE INTO `systempreferences`
+            (variable,value,explanation,options,type)
+        VALUES
+            ('AllowPatronsManageAPIKeysInOPAC', '0', 'If enabled, patrons can manage their own API keys in the OPAC', NULL, 'YesNo');
+    });
+
     print "Upgrade to $DBversion done (Bug 20568 - Add API key management interface for patrons)\n";
     SetVersion($DBversion);
 }
index 4a594f0..5b8a43a 100644 (file)
@@ -30,6 +30,7 @@ INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, `
 ('AllowNotForLoanOverride','0','','If ON, Koha will allow the librarian to loan a not for loan item.','YesNo'),
 ('AllowOfflineCirculation','0','','If on, enables HTML5 offline circulation functionality.','YesNo'),
 ('AllowPatronToSetCheckoutsVisibilityForGuarantor',  '0', NULL, 'If enabled, the patron can set checkouts to be visible to his or her guarantor',  'YesNo'),
+('AllowPatronsManageAPIKeysInOPAC', '0', NULL, 'If enabled, patrons can manage their own API keys in the OPAC',  'YesNo'),
 ('AllowPKIAuth','None','None|Common Name|emailAddress','Use the field from a client-side SSL certificate to look a user in the Koha database','Choice'),
 ('AllowPurchaseSuggestionBranchChoice','0','1','Allow user to choose branch when making a purchase suggestion','YesNo'),
 ('AllowRenewalIfOtherItemsAvailable','0',NULL,'If enabled, allow a patron to renew an item with unfilled holds if other available items can fill that hold.','YesNo'),
index 82f7501..351104e 100644 (file)
@@ -5,6 +5,12 @@ Web services:
             - pref: "RESTdefaultPageSize"
               class: integer
             - "per page"
+        -
+            - pref: AllowPatronsManageAPIKeysInOPAC
+              choices:
+                  yes: Allow
+                  no: "Don't allow"
+            - "patrons to manage their own API keys in the OPAC."
     OAI-PMH:
         -
             - pref: OAI-PMH
index db28346..22a9b2c 100644 (file)
@@ -1,6 +1,6 @@
 [% USE Koha %]
 [% INCLUDE 'doc-head-open.inc' %]
-<title>Koha &rsaquo; Patrons [% IF ( searching ) %]&rsaquo; API Keys[% END %]</title>
+<title>Koha &rsaquo; Patrons &rsaquo; API Keys</title>
 [% INCLUDE 'doc-head-close.inc' %]
 </head>
 <body id="pat_apikeys" class="pat">
                       <input type="hidden" name="patron_id" value="[% patron.id %]">
                       <input type="hidden" name="key" value="[% key.value %]">
                       <input type="hidden" name="op" value="delete">
-                      <input type="submit" value="Delete">
+                      <button class="btn btn-default btn-sm" type="submit">Delete</button>
                     </form>
                     <form action="/cgi-bin/koha/members/apikeys.pl" method="post">
                       <input type="hidden" name="patron_id" value="[% patron.id %]">
                       <input type="hidden" name="key" value="[% key.value %]">
                       [% IF key.active %]
                         <input type="hidden" name="op" value="revoke">
-                        <input type="submit" value="Revoke">
+                        <button class="btn btn-default btn-sm" type="submit">Revoke</button>
                       [% ELSE %]
                         <input type="hidden" name="op" value="activate">
-                        <input type="submit" value="Activate">
+                        <button class="btn btn-default btn-sm" type="submit">Activate</button>
                       [% END %]
                     </form>
                   </td>
index 2b78450..3024121 100644 (file)
                 <a href="/cgi-bin/koha/opac-illrequests.pl">your interlibrary loan requests</a></li>
             [% END %]
 
-            [% IF apikeysview %]
-              <li class="active">
-            [% ELSE %]
-              <li>
+
+            [% IF Koha.Preference('AllowPatronsManageAPIKeysInOPAC') %]
+                [% IF apikeysview %]
+                  <li class="active">
+                [% ELSE %]
+                  <li>
+                [% END %]
+                  <a href="/cgi-bin/koha/opac-apikeys.pl">your API keys</a>
             [% END %]
-              <a href="/cgi-bin/koha/opac-apikeys.pl">your API keys</a>
             </li>
         </ul>
     </div>
index c2235b4..13be49b 100644 (file)
@@ -1,5 +1,5 @@
 [% INCLUDE 'doc-head-open.inc' %]
-[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Your library home
+<title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo; Your API keys</title>
 [% INCLUDE 'doc-head-close.inc' %]
 [% BLOCK cssinclude %][% END %]
 </head>
@@ -11,7 +11,7 @@
         <li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">&rsaquo;</span></li>
         <li>
           <a href="/cgi-bin/koha/opac-user.pl">
-            [% INCLUDE 'patron-title.inc' category_type = borrower.category_type firstname = borrower.firstname surname = borrower.surname othernames = borrower.othernames %]
+            [% INCLUDE 'patron-title.inc' category_type=patron.category.category_type firstname=patron.firstname surname=patron.surname othernames=patron.othernames %]
           </a>
           <span class="divider">&rsaquo;</span>
         </li>
                   <h1>Your API keys</h1>
                   <div>
                     <form action="/cgi-bin/koha/opac-apikeys.pl" method="post">
-                      <input type="hidden" name="op" value="generate">
-                      <input type="submit" value="Generate new key">
+                        <input type="hidden" name="patron_id" value="[% patron.id %]">
+                        <input type="hidden" name="op" value="generate">
+                        <label for="description">Description: </label>
+                        <input type="text" name="description">
+                        <button class="btn btn-default btn-sm" type="submit"><i class="fa fa-plus"></i> Generate a new key</span></button>
                     </form>
                   </div>
-                  [% IF api_keys.size > 0 %]
+                  [% IF api_keys && api_keys.size > 0 %]
                     <table class="table table-bordered table-striped">
                       <thead>
                         <tr>
+                          <th>Description</th>
                           <th>Key</th>
                           <th>Active</th>
                           <th>Actions</th>
                       <tbody>
                         [% FOREACH key IN api_keys %]
                           <tr>
-                            <td>[% key.api_key %]</td>
+                            <td>[% key.description %]</td>
+                            <td>[% key.value %]</td>
                             <td>[% IF key.active %]Yes[% ELSE %]No[% END %]</td>
                             <td>
                               <form action="/cgi-bin/koha/opac-apikeys.pl" method="post" class="form-inline">
-                                <input type="hidden" name="key" value="[% key.api_key %]">
+                                <input type="hidden" name="key" value="[% key.value %]">
                                 <input type="hidden" name="op" value="delete">
-                                <input type="submit" value="Delete">
+                                <button class="btn btn-default btn-sm" type="submit">Delete</button>
                               </form>
                               <form action="/cgi-bin/koha/opac-apikeys.pl" method="post" class="form-inline">
-                                <input type="hidden" name="key" value="[% key.api_key %]">
+                                <input type="hidden" name="key" value="[% key.value %]">
                                 [% IF key.active %]
                                   <input type="hidden" name="op" value="revoke">
-                                  <input type="submit" value="Revoke">
+                                  <button class="btn btn-default btn-sm" type="submit">Revoke</button>
                                 [% ELSE %]
                                   <input type="hidden" name="op" value="activate">
-                                  <input type="submit" value="Activate">
+                                  <button class="btn btn-default btn-sm" type="submit">Activate</button>
                                 [% END %]
                               </form>
                             </td>
@@ -69,6 +74,8 @@
                         [% END %]
                       </tbody>
                     </table>
+                  [% ELSE %]
+                    <span class="warn">No keys defined for the current patron.</span>
                   [% END %]
                 </div> <!-- /#apikeys -->
             </div> <!-- /.span10 -->
index a2008a9..5dbd18c 100755 (executable)
@@ -1,52 +1,62 @@
 #!/usr/bin/env perl
 
-# Copyright 2015 BibLibre
-#
 # This file is part of Koha.
 #
-# Koha is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 2 of the License, or (at your option) any later
-# version.
+# Copyright 2015 BibLibre
 #
-# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
 #
-# You should have received a copy of the GNU General Public License along
-# with Koha; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
 
 use Modern::Perl;
 
 use CGI;
-use String::Random;
 
 use C4::Auth;
-use C4::Members;
 use C4::Output;
+
 use Koha::ApiKeys;
-use Koha::ApiKey;
+use Koha::Patrons;
 
 my $cgi = new CGI;
 
 my ($template, $loggedinuser, $cookie) = get_template_and_user({
-    template_name => 'opac-apikeys.tt',
-    query => $cgi,
-    type => 'opac',
-    authnotrequired => 0,
-    flagsrequired => {borrow => 1},
+    template_name   => 'opac-apikeys.tt',
+    query           => $cgi,
+    type            => 'opac',
+    authnotrequired => 0
 });
 
-my $borrowernumber = $loggedinuser;
-my $borrower = C4::Members::GetMember(borrowernumber => $borrowernumber);
+my $patron_id = $loggedinuser;
+my $patron = Koha::Patrons->find( $patron_id );
+
+if ( not defined $patron
+    or C4::Context->preference('AllowPatronsManageAPIKeysInOPAC') )
+{
+    # patron_id invalid -> exit
+    print $cgi->redirect("/cgi-bin/koha/errors/404.pl");    # escape early
+    exit;
+}
+
+
 my $op = $cgi->param('op');
 
 if ($op) {
     if ($op eq 'generate') {
-        my $apikey = new Koha::ApiKey;
-        $apikey->borrowernumber($borrowernumber);
-        $apikey->api_key(String::Random->new->randregex('[a-zA-Z0-9]{32}'));
+        my $description = $cgi->param('description') // '';
+        my $apikey = Koha::ApiKey->new({
+            patron_id   => $patron_id,
+            description => $description
+        });
         $apikey->store;
         print $cgi->redirect('/cgi-bin/koha/opac-apikeys.pl');
         exit;
@@ -54,7 +64,7 @@ if ($op) {
 
     if ($op eq 'delete') {
         my $key = $cgi->param('key');
-        my $api_key = Koha::ApiKeys->find({borrowernumber => $borrowernumber, api_key => $key});
+        my $api_key = Koha::ApiKeys->find({ patron_id => $patron_id, value => $key});
         if ($api_key) {
             $api_key->delete;
         }
@@ -64,7 +74,7 @@ if ($op) {
 
     if ($op eq 'revoke') {
         my $key = $cgi->param('key');
-        my $api_key = Koha::ApiKeys->find({borrowernumber => $borrowernumber, api_key => $key});
+        my $api_key = Koha::ApiKeys->find({ patron_id => $patron_id, value => $key });
         if ($api_key) {
             $api_key->active(0);
             $api_key->store;
@@ -75,7 +85,7 @@ if ($op) {
 
     if ($op eq 'activate') {
         my $key = $cgi->param('key');
-        my $api_key = Koha::ApiKeys->find({borrowernumber => $borrowernumber, api_key => $key});
+        my $api_key = Koha::ApiKeys->find({ patron_id => $patron_id, value => $key });
         if ($api_key) {
             $api_key->active(1);
             $api_key->store;
@@ -85,13 +95,12 @@ if ($op) {
     }
 }
 
-my @api_keys = Koha::ApiKeys->search({borrowernumber => $borrowernumber});
+my @api_keys = Koha::ApiKeys->search({ patron_id => $patron_id });
 
 $template->param(
+    api_keys    => \@api_keys,
     apikeysview => 1,
-    api_keys => \@api_keys,
-    borrower => $borrower,
-    borrowernumber => $borrowernumber,
+    patron      => $patron
 );
 
 output_html_with_http_headers $cgi, $cookie, $template->output;