Bug 17600: Standardize our EXPORT_OK
[srvgit] / Koha / REST / V1 / Auth.pm
index 884fd99..2361aae 100644 (file)
@@ -28,6 +28,7 @@ use Koha::ApiKeys;
 use Koha::Account::Lines;
 use Koha::Checkouts;
 use Koha::Holds;
+use Koha::Libraries;
 use Koha::OAuth;
 use Koha::OAuthAccessTokens;
 use Koha::Old::Checkouts;
@@ -37,10 +38,10 @@ use Koha::Exceptions;
 use Koha::Exceptions::Authentication;
 use Koha::Exceptions::Authorization;
 
-use MIME::Base64;
+use MIME::Base64 qw( decode_base64 );
 use Module::Load::Conditional;
 use Scalar::Util qw( blessed );
-use Try::Tiny;
+use Try::Tiny qw( catch try );
 
 =head1 NAME
 
@@ -63,7 +64,15 @@ sub under {
 
         # /api/v1/{namespace}
         my $namespace = $c->req->url->to_abs->path->[2] // '';
-        my $is_public = ($namespace eq 'public') ? 1 : 0;
+
+        my $is_public = 0; # By default routes are not public
+        my $is_plugin = 0;
+
+        if ( $namespace eq 'public' ) {
+            $is_public = 1;
+        } elsif ( $namespace eq 'contrib' ) {
+            $is_plugin = 1;
+        }
 
         if ( $is_public
             and !C4::Context->preference('RESTPublicAPI') )
@@ -76,8 +85,11 @@ sub under {
             # Requesting a token shouldn't go through the API authenticaction chain
             $status = 1;
         }
+        elsif ( $namespace eq '' or $namespace eq '.html' ) {
+            $status = 1;
+        }
         else {
-            $status = authenticate_api_request($c, { is_public => $is_public });
+            $status = authenticate_api_request($c, { is_public => $is_public, is_plugin => $is_plugin });
         }
 
     } catch {
@@ -143,6 +155,9 @@ sub authenticate_api_request {
     my $spec = $c->openapi->spec || $c->match->endpoint->pattern->defaults->{'openapi.op_spec'};
 
     $c->stash_embed({ spec => $spec });
+    $c->stash_overrides();
+
+    my $cookie_auth = 0;
 
     my $authorization = $spec->{'x-koha-authorization'};
 
@@ -170,7 +185,6 @@ sub authenticate_api_request {
         if ($valid_token) {
             my $patron_id = Koha::ApiKeys->find( $valid_token->{client_id} )->patron_id;
             $user         = Koha::Patrons->find($patron_id);
-            C4::Context->interface('api');
         }
         else {
             # If we have "Authorization: Bearer" header and oauth authentication
@@ -187,7 +201,6 @@ sub authenticate_api_request {
             );
         }
         $user = $c->_basic_auth( $authorization_header );
-        C4::Context->interface('api');
         unless ( $user ) {
             # If we have "Authorization: Basic" header and authentication
             # failed, do not try other authentication means
@@ -211,6 +224,7 @@ sub authenticate_api_request {
             $user = Koha::Patrons->find( $session->param('number') )
               unless $session->param('sessiontype')
                  and $session->param('sessiontype') eq 'anon';
+            $cookie_auth = 1;
         }
         elsif ($status eq "maintenance") {
             Koha::Exceptions::UnderMaintenance->throw(
@@ -235,11 +249,16 @@ sub authenticate_api_request {
     }
 
     $c->stash('koha.user' => $user);
+    C4::Context->interface('api');
+
+    if ( $user and !$cookie_auth ) { # cookie-auth sets this and more, don't mess with that
+        $c->_set_userenv( $user );
+    }
 
     if ( !$authorization and
          ( $params->{is_public} and
           ( C4::Context->preference('RESTPublicAnonymousRequests') or
-            $user) ) ) {
+            $user) or $params->{is_plugin} ) ) {
         # We do not need any authorization
         # Check the parameters
         validate_query_parameters( $c, $spec );
@@ -294,7 +313,6 @@ sub validate_query_parameters {
     ) if @errors;
 }
 
-
 =head3 allow_owner
 
 Allows access to object for its owner.
@@ -473,4 +491,44 @@ sub _basic_auth {
     return Koha::Patrons->find({ userid => $user_id });
 }
 
+=head3 _set_userenv
+
+    $c->_set_userenv( $patron );
+
+Internal method that sets C4::Context->userenv
+
+=cut
+
+sub _set_userenv {
+    my ( $c, $patron ) = @_;
+
+    my $passed_library_id = $c->req->headers->header('x-koha-library');
+    my $THE_library;
+
+    if ( $passed_library_id ) {
+        $THE_library = Koha::Libraries->find( $passed_library_id );
+        Koha::Exceptions::Authorization::Unauthorized->throw(
+            "Unauthorized attempt to set library to $passed_library_id"
+        ) unless $THE_library and $patron->can_log_into($THE_library);
+    }
+    else {
+        $THE_library = $patron->library;
+    }
+
+    C4::Context->_new_userenv( $patron->borrowernumber );
+    C4::Context->set_userenv(
+        $patron->borrowernumber,  # number,
+        $patron->userid,          # userid,
+        $patron->cardnumber,      # cardnumber
+        $patron->firstname,       # firstname
+        $patron->surname,         # surname
+        $THE_library->branchcode, # branch
+        $THE_library->branchname, # branchname
+        $patron->flags,           # flags,
+        $patron->email,           # emailaddress
+    );
+
+    return $c;
+}
+
 1;