Bugzilla – Attachment 143193 Details for
Bug 31378
Add a generic OAuth2/OIDC client implementation
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 31378: Add API routes
Bug-31378-Add-API-routes.patch (text/plain), 8.77 KB, created by
Agustín Moyano
on 2022-11-04 12:49:52 UTC
(
hide
)
Description:
Bug 31378: Add API routes
Filename:
MIME Type:
Creator:
Agustín Moyano
Created:
2022-11-04 12:49:52 UTC
Size:
8.77 KB
patch
obsolete
>From c40066ab154ba6e58edc918c6ac21a48c03e1e9f Mon Sep 17 00:00:00 2001 >From: Agustin Moyano <agustinmoyano@theke.io> >Date: Thu, 18 Aug 2022 16:42:10 -0300 >Subject: [PATCH] Bug 31378: Add API routes > >--- > Koha/REST/V1.pm | 13 +++ > Koha/REST/V1/OAuth/Client.pm | 135 +++++++++++++++++++++++++ > api/v1/swagger/paths/public_oauth.yaml | 67 ++++++++++++ > api/v1/swagger/swagger.yaml | 2 + > 4 files changed, 217 insertions(+) > create mode 100644 Koha/REST/V1/OAuth/Client.pm > create mode 100644 api/v1/swagger/paths/public_oauth.yaml > >diff --git a/Koha/REST/V1.pm b/Koha/REST/V1.pm >index 79d73bbb87..5b5ea1e275 100644 >--- a/Koha/REST/V1.pm >+++ b/Koha/REST/V1.pm >@@ -21,10 +21,13 @@ use Mojo::Base 'Mojolicious'; > > use C4::Context; > use Koha::Logger; >+use Koha::Auth::Providers; > >+use Mojolicious::Plugin::OAuth2; > use JSON::Validator::Schema::OpenAPIv2; > > use Try::Tiny qw( catch try ); >+use JSON qw( decode_json ); > > =head1 NAME > >@@ -134,10 +137,20 @@ sub startup { > }; > }; > >+ my $oauth_configuration = {}; >+ my $search_options = { protocol => [ "OIDC", "OAuth" ] }; >+ my $providers = Koha::Auth::Providers->search( $search_options ); >+ >+ while(my $provider = $providers->next) { >+ $oauth_configuration->{$provider->code} = decode_json($provider->config); >+ } >+ > $self->plugin( 'Koha::REST::Plugin::Pagination' ); > $self->plugin( 'Koha::REST::Plugin::Query' ); > $self->plugin( 'Koha::REST::Plugin::Objects' ); > $self->plugin( 'Koha::REST::Plugin::Exceptions' ); >+ $self->plugin( 'Koha::REST::Plugin::Auth' ); >+ $self->plugin( 'Mojolicious::Plugin::OAuth2' => $oauth_configuration ); > } > > 1; >diff --git a/Koha/REST/V1/OAuth/Client.pm b/Koha/REST/V1/OAuth/Client.pm >new file mode 100644 >index 0000000000..36cca8aac6 >--- /dev/null >+++ b/Koha/REST/V1/OAuth/Client.pm >@@ -0,0 +1,135 @@ >+package Koha::REST::V1::OAuth::Client; >+ >+# 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 3 of the License, or >+# (at your option) any later version. >+# >+# 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 Koha::Auth::Client::OAuth; >+ >+use Mojo::Base 'Mojolicious::Controller'; >+use Mojo::URL; >+use Scalar::Util qw(blessed); >+use Try::Tiny; >+use Koha::Logger; >+use URI::Escape qw(uri_escape_utf8); >+ >+=head1 NAME >+ >+Koha::REST::V1::OAuth::Client - Controller library for handling OAuth2-related login attempts >+ >+=head1 API >+ >+=head2 Methods >+ >+=head3 login >+ >+Controller method handling login requests >+ >+=cut >+ >+sub login { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $provider = $c->validation->param('provider_code'); >+ my $interface = $c->validation->param('interface'); >+ >+ my $logger = Koha::Logger->get({ interface => 'api' }); >+ >+ my $provider_config = $c->oauth2->providers->{$provider}; >+ >+ unless ( $provider_config ) { >+ return $c->render( >+ status => 404, >+ openapi => { >+ error => 'Object not found', >+ error_code => 'not_found', >+ } >+ ); >+ } >+ >+ unless ( $provider_config->{authorize_url} =~ /response_type=code/ ) { >+ my $authorize_url = Mojo::URL->new($provider_config->{authorize_url}); >+ $authorize_url->query->append(response_type => 'code'); >+ $provider_config->{authorize_url} = $authorize_url->to_string; >+ } >+ >+ my $uri; >+ >+ if ( $interface eq 'opac' ) { >+ if ( C4::Context->preference('OpacPublic') ) { >+ $uri = '/cgi-bin/koha/opac-user.pl'; >+ } else { >+ $uri = '/cgi-bin/koha/opac-main.pl'; >+ } >+ } else { >+ $uri = '/cgi-bin/koha/mainpage.pl'; >+ } >+ >+ return $c->oauth2->get_token_p($provider)->then( >+ sub { >+ return unless my $response = shift; >+ >+ my ( $patron, $mapped_data, $domain ) = Koha::Auth::Client::OAuth->new->get_user( >+ { provider => $provider, >+ data => $response, >+ interface => $interface, >+ config => $c->oauth2->providers->{$provider} >+ } >+ ); >+ >+ try { >+ # FIXME: We could check if the backend allows registering >+ if ( !$patron ) { >+ $patron = $c->auth->register( >+ { >+ data => $mapped_data, >+ domain => $domain, >+ interface => $interface >+ } >+ ); >+ } >+ >+ my ( $status, $cookie, $session_id ) = $c->auth->session($patron); >+ >+ $c->cookie( CGISESSID => $session_id, { path => "/" } ); >+ >+ $c->redirect_to($uri); >+ } catch { >+ my $error = $_; >+ $logger->error($error); >+ # TODO: Review behavior >+ if ( blessed $error ) { >+ if ( $error->isa('Koha::Exceptions::Auth::Unauthorized') ) { >+ $error = "$error"; >+ } >+ } >+ >+ $error = uri_escape_utf8($error); >+ >+ $c->redirect_to($uri."?auth_error=$error"); >+ }; >+ } >+ )->catch( >+ sub { >+ my $error = shift; >+ $logger->error($error); >+ $error = uri_escape_utf8($error); >+ $c->redirect_to($uri."?auth_error=$error"); >+ } >+ )->wait; >+} >+ >+1; >diff --git a/api/v1/swagger/paths/public_oauth.yaml b/api/v1/swagger/paths/public_oauth.yaml >new file mode 100644 >index 0000000000..dc88455c1c >--- /dev/null >+++ b/api/v1/swagger/paths/public_oauth.yaml >@@ -0,0 +1,67 @@ >+"/public/oauth/login/{provider}/{interface}": >+ get: >+ x-mojo-to: OAuth::Client#login >+ operationId: loginOAuthClient >+ tags: >+ - oauth >+ summary: Login to OAuth provider >+ produces: >+ - application/json >+ parameters: >+ - name: provider >+ in: path >+ description: Name of OAuth provider >+ required: true >+ type: string >+ - name: interface >+ in: path >+ description: Name of the interface this login is for >+ required: true >+ type: string >+ - name: code >+ in: query >+ description: Code returned from OAuth server for Authorization Code grant >+ required: false >+ type: string >+ - name: state >+ in: query >+ description: An opaque value used by the client to maintain state between the request and callback. This is the callback part. >+ required: false >+ type: string >+ - name: scope >+ in: query >+ description: Scope returned by OAuth server >+ type: string >+ - name: prompt >+ in: query >+ description: Prompt returned by OAuth server >+ type: string >+ - name: authuser >+ in: query >+ description: Auth user returned by OAuth server >+ type: string >+ - name: error >+ in: query >+ description: OAuth error code >+ type: string >+ - name: error_description >+ in: query >+ description: OAuth error description >+ type: string >+ - name: error_uri >+ in: query >+ description: Web page with user friendly description of the error >+ type: string >+ responses: >+ "302": >+ description: User authorized >+ schema: >+ type: string >+ "400": >+ description: Bad Request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml >index 1bc55f73d7..587f6622cb 100644 >--- a/api/v1/swagger/swagger.yaml >+++ b/api/v1/swagger/swagger.yaml >@@ -229,6 +229,8 @@ paths: > $ref: ./paths/libraries.yaml#/~1public~1libraries > "/public/libraries/{library_id}": > $ref: "./paths/libraries.yaml#/~1public~1libraries~1{library_id}" >+ "/public/oauth/login/{provider}/{interface}": >+ $ref: ./paths/public_oauth.yaml#/~1public~1oauth~1login~1{provider}~1{interface} > "/public/patrons/{patron_id}/article_requests/{article_request_id}": > $ref: "./paths/article_requests.yaml#/~1public~1patrons~1{patron_id}~1article_requests~1{article_request_id}" > "/public/patrons/{patron_id}/guarantors/can_see_charges": >-- >2.25.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 31378
:
141362
|
141363
|
141364
|
141365
|
141366
|
141367
|
141368
|
141369
|
141370
|
141371
|
141372
|
141373
|
141374
|
141375
|
141376
|
141377
|
141378
|
141514
|
141771
|
141772
|
141773
|
141774
|
141775
|
141776
|
141777
|
141778
|
141779
|
141780
|
141781
|
141782
|
141783
|
141784
|
141785
|
141786
|
141787
|
141788
|
141801
|
141802
|
141803
|
141804
|
141805
|
141806
|
141807
|
141808
|
141809
|
141810
|
141811
|
141812
|
141813
|
141814
|
141815
|
141816
|
141817
|
141818
|
141853
|
143056
|
143087
|
143088
|
143089
|
143090
|
143091
|
143092
|
143093
|
143094
|
143095
|
143096
|
143097
|
143098
|
143099
|
143100
|
143101
|
143102
|
143103
|
143104
|
143105
|
143106
|
143107
|
143186
|
143187
|
143188
|
143189
|
143190
|
143191
|
143192
|
143193
|
143194
|
143195
|
143196
|
143197
|
143198
|
143199
|
143200
|
143202
|
143204
|
143205
|
143206
|
143207
|
143208
|
143215
|
143216
|
143217
|
143218
|
143219
|
143220
|
143221
|
143222
|
143223
|
143224
|
143225
|
143226
|
143227
|
143228
|
143229
|
143230
|
143231
|
143232
|
143233
|
143234
|
143235
|
143236
|
143266
|
143267
|
143268
|
143269
|
143270
|
143271
|
143272
|
143273
|
143274
|
143275
|
143277
|
143278
|
143279
|
143280
|
143281
|
143282
|
143283
|
143284
|
143285
|
143286
|
143287
|
143288
|
143396
|
143397
|
143398
|
143399
|
143400
|
143401
|
143402
|
143403
|
143404
|
143405
|
143406
|
143407
|
143408
|
143409
|
143410
|
143411
|
143412
|
143413
|
143414
|
143415
|
143416
|
143417
|
143418
|
143420
|
143421
|
143422
|
143423
|
143424
|
143425
|
143426
|
143427
|
143428
|
143429
|
143430
|
143431
|
143432
|
143433
|
143434
|
143435
|
143436
|
143437
|
143438
|
143439
|
143440
|
143441
|
143442
|
143443
|
143450
|
144071
|
144175