Bug 31378: Add authentication provider endpoints

This patch adds routes for handling authentication providers to the REST
API.

To test:
1. Apply this patch
2. Run:
   $ kshell
  k$ prove t/db_dependent/api/v1/auth_providers.t
=> SUCCESS: Tests pass!
3. Sign off :-D

Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
Signed-off-by: Lukasz Koszyk <lukasz.koszyk@kit.edu>
Signed-off-by: Nick Clemens <nick@bywatersolutions.com>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
Tomas Cohen Arazi 2022-08-30 10:33:14 -03:00
parent 58d66c35df
commit f97ba16e44
No known key found for this signature in database
GPG Key ID: 0A272EA1B2F3C15F
12 changed files with 1376 additions and 28 deletions

View File

@ -97,22 +97,11 @@ This method stores the passed config in JSON format.
sub set_config {
my ($self, $config) = @_;
my @mandatory;
if ( $self->protocol eq 'OIDC' ) {
@mandatory = qw(key secret well_known_url);
}
elsif ( $self->protocol eq 'OAuth' ) {
@mandatory = qw(key secret authorize_url token_url);
}
else {
Koha::Exception->throw( 'Unsupported protocol ' . $self->protocol );
}
my @mandatory = $self->mandatory_config_attributes;
for my $param (@mandatory) {
unless ( defined( $config->{$param} ) ) {
Koha::Exceptions::MissingParameter->throw(
error => "The $param parameter is mandatory" );
Koha::Exceptions::MissingParameter->throw( parameter => $param );
}
}
@ -167,8 +156,51 @@ sub set_mapping {
return $self;
}
=head3 upgrade_class
my $upgraded_object = $provider->upgrade_class
Returns a new instance of the object, with the right class.
=cut
sub upgrade_class {
my ( $self ) = @_;
my $protocol = $self->protocol;
my $class = $self->protocol_to_class_mapping->{$protocol};
Koha::Exception->throw($protocol . ' is not a valid protocol')
unless $class;
eval "require $class";
return $class->_new_from_dbic( $self->_result );
}
=head2 Internal methods
=head3 to_api
my $json = $provider->to_api;
Overloaded method that returns a JSON representation of the Koha::Auth::Provider object,
suitable for API output.
=cut
sub to_api {
my ( $self, $params ) = @_;
my $config = $self->get_config;
my $mapping = $self->get_mapping;
my $json = $self->SUPER::to_api($params);
$json->{config} = $config;
$json->{mapping} = $mapping;
return $json;
}
=head3 _type
=cut
@ -177,4 +209,31 @@ sub _type {
return 'AuthProvider';
}
=head3 protocol_to_class_mapping
my $mapping = Koha::Auth::Provider::protocol_to_class_mapping
Internal method that returns a mapping between I<protocol> codes and
implementing I<classes>. To be used by B<upgrade_class>.
=cut
sub protocol_to_class_mapping {
return {
OAuth => 'Koha::Auth::Provider::OAuth',
OIDC => 'Koha::Auth::Provider::OIDC',
};
}
=head3 mandatory_config_attributes
Stub method for raising exceptions on invalid protocols.
=cut
sub mandatory_config_attributes {
my ($self) = @_;
Koha::Exception->throw("This method needs to be subclassed");
}
1;

View File

@ -0,0 +1,65 @@
package Koha::Auth::Provider::OAuth;
# Copyright Theke Solutions 2022
#
# 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 base qw(Koha::Auth::Provider);
=head1 NAME
Koha::Auth::Provider::OAuth - Koha Auth Provider Object class
=head1 API
=head2 Class methods
=head3 new
my $oauth = Koha::Auth::Provider::OAuth->new( \%{params} );
Overloaded class to create a new OAuth provider.
=cut
sub new {
my ( $class, $params ) = @_;
$params->{protocol} = 'OAuth';
return $class->SUPER::new($params);
}
=head2 Internal methods
=head3 mandatory_config_attributes
Returns a list of the mandatory config entries for the protocol.
=cut
sub mandatory_config_attributes {
return qw(
key
secret
authorize_url
token_url
);
}
1;

View File

@ -0,0 +1,64 @@
package Koha::Auth::Provider::OIDC;
# Copyright Theke Solutions 2022
#
# 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 base qw(Koha::Auth::Provider);
=head1 NAME
Koha::Auth::Provider::OIDC - Koha Auth Provider Object class
=head1 API
=head2 Class methods
=head3 new
my $oidc = Koha::Auth::Provider::OIDC->new( \%{params} );
Overloaded class to create a new OIDC provider.
=cut
sub new {
my ( $class, $params ) = @_;
$params->{protocol} = 'OIDC';
return $class->SUPER::new($params);
}
=head2 Internal methods
=head3 mandatory_config_attributes
Returns a list of the mandatory config entries for the protocol.
=cut
sub mandatory_config_attributes {
return qw(
key
secret
well_known_url
);
}
1;

View File

@ -0,0 +1,233 @@
package Koha::REST::V1::Auth::Provider::Domains;
# 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 Mojo::Base 'Mojolicious::Controller';
use Koha::Auth::Provider::Domains;
use Koha::Auth::Providers;
use Koha::Database;
use Scalar::Util qw(blessed);
use Try::Tiny;
=head1 NAME
Koha::REST::V1::Auth::Provider::Domains - Controller library for handling
authentication provider domains routes.
=head2 Operations
=head3 list
Controller method for listing authentication provider domains.
=cut
sub list {
my $c = shift->openapi->valid_input or return;
return try {
my $auth_provider_id = $c->validation->param('auth_provider_id');
my $provider = Koha::Auth::Providers->find($auth_provider_id);
unless ($provider) {
return $c->render(
status => 404,
openapi => {
error => 'Object not found',
error_code => 'not_found',
}
);
}
my $domains_rs = $provider->domains;
return $c->render(
status => 200,
openapi => $c->objects->search($domains_rs)
);
} catch {
$c->unhandled_exception($_);
};
}
=head3 get
Controller method for retrieving an authentication provider domain.
=cut
sub get {
my $c = shift->openapi->valid_input or return;
return try {
my $auth_provider_id = $c->validation->param('auth_provider_id');
my $provider = Koha::Auth::Providers->find($auth_provider_id);
unless ($provider) {
return $c->render(
status => 404,
openapi => {
error => 'Object not found',
error_code => 'not_found',
}
);
}
my $domains_rs = $provider->domains;
my $auth_provider_domain_id = $c->validation->param('auth_provider_domain_id');
my $domain = $c->objects->find( $domains_rs, $auth_provider_domain_id );
unless ($domain) {
return $c->render(
status => 404,
openapi => {
error => 'Object not found',
error_code => 'not_found',
}
);
}
return $c->render( status => 200, openapi => $domain );
} catch {
$c->unhandled_exception($_);
}
}
=head3 add
Controller method for adding an authentication provider.
=cut
sub add {
my $c = shift->openapi->valid_input or return;
return try {
Koha::Database->new->schema->txn_do(
sub {
my $domain = Koha::Auth::Provider::Domain->new_from_api( $c->validation->param('body') );
$domain->store;
$c->res->headers->location( $c->req->url->to_string . '/' . $domain->id );
return $c->render(
status => 201,
openapi => $domain->to_api
);
}
);
} catch {
if ( blessed($_) and $_->isa('Koha::Exceptions::Object::FKConstraint') ) {
return $c->render(
status => 404,
openapi => {
error => 'Object not found',
error_code => 'not_found',
}
);
}
$c->unhandled_exception($_);
};
}
=head3 update
Controller method for updating an authentication provider domain.
=cut
sub update {
my $c = shift->openapi->valid_input or return;
my $auth_provider_id = $c->validation->param('auth_provider_id');
my $auth_provider_domain_id = $c->validation->param('auth_provider_domain_id');
my $domain = Koha::Auth::Provider::Domains->find(
{ auth_provider_id => $auth_provider_id, auth_provider_domain_id => $auth_provider_domain_id } );
unless ($domain) {
return $c->render(
status => 404,
openapi => {
error => 'Object not found',
error_code => 'not_found',
}
);
}
return try {
Koha::Database->new->schema->txn_do(
sub {
$domain->set_from_api( $c->validation->param('body') );
$domain->store->discard_changes;
return $c->render(
status => 200,
openapi => $domain->to_api
);
}
);
} catch {
$c->unhandled_exception($_);
};
}
=head3 delete
Controller method for deleting an authentication provider.
=cut
sub delete {
my $c = shift->openapi->valid_input or return;
my $auth_provider_id = $c->validation->param('auth_provider_id');
my $auth_provider_domain_id = $c->validation->param('auth_provider_domain_id');
my $domain = Koha::Auth::Provider::Domains->find(
{ auth_provider_id => $auth_provider_id, auth_provider_domain_id => $auth_provider_domain_id } );
unless ($domain) {
return $c->render(
status => 404,
openapi => {
error => 'Object not found',
error_code => 'not_found',
}
);
}
return try {
$domain->delete;
return $c->render(
status => 204,
openapi => q{}
);
} catch {
$c->unhandled_exception($_);
};
}
1;

View File

@ -0,0 +1,237 @@
package Koha::REST::V1::Auth::Providers;
# 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 Mojo::Base 'Mojolicious::Controller';
use Koha::Auth::Provider::OAuth;
use Koha::Auth::Provider::OIDC;
use Koha::Auth::Providers;
use Koha::Database;
use Scalar::Util qw(blessed);
use Try::Tiny;
=head1 NAME
Koha::REST::V1::Auth::Providers - Controller library for handling
authentication providers routes.
=head2 Operations
=head3 list
Controller method for listing authentication providers.
=cut
sub list {
my $c = shift->openapi->valid_input or return;
return try {
my $providers_rs = Koha::Auth::Providers->new;
return $c->render(
status => 200,
openapi => $c->objects->search($providers_rs)
);
} catch {
$c->unhandled_exception($_);
};
}
=head3 get
Controller method for retrieving an authentication provider.
=cut
sub get {
my $c = shift->openapi->valid_input or return;
return try {
my $auth_provider_id = $c->validation->param('auth_provider_id');
my $provider = $c->objects->find( Koha::Auth::Providers->new, $auth_provider_id );
unless ( $provider ) {
return $c->render(
status => 404,
openapi => {
error => 'Object not found',
error_code => 'not_found',
}
);
}
return $c->render( status => 200, openapi => $provider );
}
catch {
$c->unhandled_exception($_);
}
}
=head3 add
Controller method for adding an authentication provider.
=cut
sub add {
my $c = shift->openapi->valid_input or return;
return try {
Koha::Database->new->schema->txn_do(
sub {
my $body = $c->validation->param('body');
my $config = delete $body->{config};
my $mapping = delete $body->{mapping};
my $protocol = delete $body->{protocol};
my $class = Koha::Auth::Provider::protocol_to_class_mapping->{$protocol};
my $provider = $class->new_from_api( $body );
$provider->store;
$provider->set_config( $config );
$provider->set_mapping( $mapping );
$c->res->headers->location( $c->req->url->to_string . '/' . $provider->auth_provider_id );
return $c->render(
status => 201,
openapi => $provider->to_api
);
}
);
}
catch {
if ( blessed($_) ) {
if ( $_->isa('Koha::Exceptions::MissingParameter') ) {
return $c->render(
status => 400,
openapi => {
error => "Missing parameter config." . $_->parameter,
error_code => 'missing_parameter'
}
);
}
}
$c->unhandled_exception($_);
};
}
=head3 update
Controller method for updating an authentication provider.
=cut
sub update {
my $c = shift->openapi->valid_input or return;
my $auth_provider_id = $c->validation->param('auth_provider_id');
my $provider = Koha::Auth::Providers->find( $auth_provider_id );
unless ( $provider ) {
return $c->render(
status => 404,
openapi => {
error => 'Object not found',
error_code => 'not_found',
}
);
}
return try {
Koha::Database->new->schema->txn_do(
sub {
my $body = $c->validation->param('body');
my $config = delete $body->{config};
my $mapping = delete $body->{mapping};
$provider = $provider->set_from_api( $body )->upgrade_class;
$provider->set_config( $config );
$provider->set_mapping( $mapping );
# set_config and set_mapping already called store()
$provider->discard_changes;
return $c->render(
status => 200,
openapi => $provider->to_api
);
}
);
}
catch {
if ( blessed($_) ) {
if ( $_->isa('Koha::Exceptions::MissingParameter') ) {
return $c->render(
status => 400,
openapi => {
error => "Missing parameter config." . $_->parameter,
error_code => 'missing_parameter'
}
);
}
}
$c->unhandled_exception($_);
};
}
=head3 delete
Controller method for deleting an authentication provider.
=cut
sub delete {
my $c = shift->openapi->valid_input or return;
my $provider = Koha::Auth::Providers->find( $c->validation->param('auth_provider_id') );
unless ( $provider ) {
return $c->render(
status => 404,
openapi => {
error => 'Object not found',
error_code => 'not_found',
}
);
}
return try {
$provider->delete;
return $c->render(
status => 204,
openapi => q{}
);
}
catch {
$c->unhandled_exception($_);
};
}
1;

View File

@ -0,0 +1,49 @@
---
type: object
properties:
auth_provider_id:
type: integer
description: Internally assigned authentication provider identifier
readOnly: true
code:
description: Authentication provider code
type: string
description:
description: User-oriented description for the provider
type: string
protocol:
description: Authentication protocol
type: string
enum:
- OAuth
- OIDC
- CAS (not implemented)
- LDAP (not implemented)
mapping:
description: Attribute mapping
type:
- object
- "null"
matchpoint:
description: Patron attribute that will be used to match
type: string
enum:
- email
- userid
- cardnumber
config:
description: Configuration
type: object
icon_url:
description: Icon url
type: string
domains:
description: Configured domains for the authentication provider
type:
- array
- "null"
additionalProperties: false
required:
- config
- code
- protocol

View File

@ -0,0 +1,48 @@
---
type: object
properties:
auth_provider_domain_id:
type: integer
description: Internally assigned authentication provider domain identifier
readOnly: true
auth_provider_id:
type: integer
description: Internally assigned authentication provider identifier
domain:
description: Matching domain ('*' used as wildcard)
type:
- string
- "null"
auto_register:
description: If patrons will be generated on login if required
type: boolean
update_on_auth:
description: If patron data is updated on login
type: boolean
default_library_id:
description: Internal identifier for the default library to be assigned to the new patrons
type:
- string
- "null"
default_category_id:
description: Internal identifier for the default patron's category
type:
- string
- "null"
allow_opac:
description: If this domain can be used for OPAC login
type: boolean
allow_staff:
description: If this domain can be used for staff login
type: boolean
additionalProperties: false
required:
- auth_provider_domain_id
- auth_provider_id
- domain
- auto_register
- update_on_auth
- default_library_id
- default_category_id
- allow_opac
- allow_staff

View File

@ -128,3 +128,443 @@
x-koha-authorization:
permissions:
catalogue: "1"
/auth/providers:
get:
x-mojo-to: Auth::Providers#list
operationId: listAuthProviders
tags:
- auth_providers
summary: List configured authentication providers
parameters:
- $ref: ../swagger.yaml#/parameters/match
- $ref: ../swagger.yaml#/parameters/order_by
- $ref: ../swagger.yaml#/parameters/page
- $ref: ../swagger.yaml#/parameters/per_page
- $ref: ../swagger.yaml#/parameters/q_param
- $ref: ../swagger.yaml#/parameters/q_body
- $ref: ../swagger.yaml#/parameters/q_header
- $ref: ../swagger.yaml#/parameters/request_id_header
- name: x-koha-embed
in: header
required: false
description: Embed list sent as a request header
type: array
items:
type: string
enum:
- domains
collectionFormat: csv
produces:
- application/json
responses:
"200":
description: A list of authentication providers
schema:
type: array
items:
$ref: ../swagger.yaml#/definitions/auth_provider
"400":
description: Bad Request
schema:
$ref: ../swagger.yaml#/definitions/error
"403":
description: Access forbidden
schema:
$ref: ../swagger.yaml#/definitions/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: ../swagger.yaml#/definitions/error
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error
x-koha-authorization:
permissions:
parameters: manage_authentication_providers
post:
x-mojo-to: Auth::Providers#add
operationId: addAuthProvider
tags:
- auth_providers
summary: Add a new authentication provider
parameters:
- name: body
in: body
description: |
A JSON object containing OAuth provider parameters.
The `config` object required attributes depends on the chosen `protocol`
## OAuth
Requires:
* key
* secret
* authorize_url
* token_url
## OIDC
Requires:
* key
* secret
* well_known_url
required: true
schema:
$ref: ../swagger.yaml#/definitions/auth_provider
produces:
- application/json
responses:
"201":
description: The generated authentication provider
schema:
$ref: ../swagger.yaml#/definitions/auth_provider
"400":
description: Bad Request
schema:
$ref: ../swagger.yaml#/definitions/error
"403":
description: Access forbidden
schema:
$ref: ../swagger.yaml#/definitions/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: ../swagger.yaml#/definitions/error
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error
x-koha-authorization:
permissions:
parameters: manage_authentication_providers
"/auth/providers/{auth_provider_id}":
get:
x-mojo-to: Auth::Providers#get
operationId: getAuthProvider
tags:
- auth_providers
summary: Get authentication provider
parameters:
- $ref: ../swagger.yaml#/parameters/auth_provider_id_pp
- name: x-koha-embed
in: header
required: false
description: Embed list sent as a request header
type: array
items:
type: string
enum:
- domains
collectionFormat: csv
produces:
- application/json
responses:
"200":
description: An authentication provider
schema:
$ref: ../swagger.yaml#/definitions/auth_provider
"404":
description: Object not found
schema:
$ref: ../swagger.yaml#/definitions/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: ../swagger.yaml#/definitions/error
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error
x-koha-authorization:
permissions:
parameters: manage_authentication_providers
put:
x-mojo-to: Auth::Providers#update
operationId: updateAuthProvider
tags:
- auth_providers
summary: Update an authentication provider
parameters:
- $ref: ../swagger.yaml#/parameters/auth_provider_id_pp
- name: body
in: body
description: |
A JSON object containing OAuth provider parameters.
The `config` object required attributes depends on the chosen `protocol`
## OAuth
Requires:
* key
* secret
* authorize_url
* token_url
## OIDC
Requires:
* key
* secret
* well_known_url
required: true
schema:
$ref: ../swagger.yaml#/definitions/auth_provider
produces:
- application/json
responses:
"200":
description: Updated authentication provider
schema:
$ref: ../swagger.yaml#/definitions/auth_provider
"400":
description: Bad Request
schema:
$ref: ../swagger.yaml#/definitions/error
"403":
description: Access forbidden
schema:
$ref: ../swagger.yaml#/definitions/error
"404":
description: Object not found
schema:
$ref: ../swagger.yaml#/definitions/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: ../swagger.yaml#/definitions/error
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error
x-koha-authorization:
permissions:
parameters: manage_authentication_providers
delete:
x-mojo-to: Auth::Providers#delete
operationId: delAuthProvider
tags:
- auth_providers
summary: Delete authentication provider
parameters:
- $ref: ../swagger.yaml#/parameters/auth_provider_id_pp
produces:
- application/json
responses:
"204":
description: Authentication provider deleted
"401":
description: Authentication required
schema:
$ref: ../swagger.yaml#/definitions/error
"403":
description: Access forbidden
schema:
$ref: ../swagger.yaml#/definitions/error
"404":
description: City not found
schema:
$ref: ../swagger.yaml#/definitions/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error
x-koha-authorization:
permissions:
parameters: manage_authentication_providers
"/auth/providers/{auth_provider_id}/domains":
get:
x-mojo-to: Auth::Provider::Domains#list
operationId: listAuthProviderDomains
tags:
- auth_providers
summary: Get authentication provider configured domains
parameters:
- $ref: ../swagger.yaml#/parameters/auth_provider_id_pp
- $ref: ../swagger.yaml#/parameters/match
- $ref: ../swagger.yaml#/parameters/order_by
- $ref: ../swagger.yaml#/parameters/page
- $ref: ../swagger.yaml#/parameters/per_page
- $ref: ../swagger.yaml#/parameters/q_param
- $ref: ../swagger.yaml#/parameters/q_body
- $ref: ../swagger.yaml#/parameters/q_header
- $ref: ../swagger.yaml#/parameters/request_id_header
- name: x-koha-embed
in: header
required: false
description: Embed list sent as a request header
type: array
items:
type: string
enum:
- domains
collectionFormat: csv
produces:
- application/json
responses:
"200":
description: An authentication provider
schema:
items:
$ref: ../swagger.yaml#/definitions/auth_provider_domain
"404":
description: Object not found
schema:
$ref: ../swagger.yaml#/definitions/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: ../swagger.yaml#/definitions/error
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error
x-koha-authorization:
permissions:
parameters: manage_authentication_providers
post:
x-mojo-to: Auth::Provider::Domains#add
operationId: addAuthProviderDomain
tags:
- auth_providers
summary: Add an authentication provider domain
parameters:
- $ref: ../swagger.yaml#/parameters/auth_provider_id_pp
- name: body
in: body
description: An authentication provider domain object
required: true
schema:
$ref: ../swagger.yaml#/definitions/auth_provider_domain
produces:
- application/json
responses:
"201":
description: Updated authentication provider domain
schema:
$ref: ../swagger.yaml#/definitions/auth_provider_domain
"400":
description: Bad Request
schema:
$ref: ../swagger.yaml#/definitions/error
"403":
description: Access forbidden
schema:
$ref: ../swagger.yaml#/definitions/error
"404":
description: Object not found
schema:
$ref: ../swagger.yaml#/definitions/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: ../swagger.yaml#/definitions/error
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error
x-koha-authorization:
permissions:
parameters: manage_authentication_providers
"/auth/providers/{auth_provider_id}/domains/{auth_provider_domain_id}":
get:
x-mojo-to: Auth::Provider::Domains#get
operationId: getAuthProviderDomain
tags:
- auth_providers
summary: Get authentication provider domain
parameters:
- $ref: ../swagger.yaml#/parameters/auth_provider_id_pp
- $ref: ../swagger.yaml#/parameters/auth_provider_domain_id_pp
produces:
- application/json
responses:
"200":
description: An authentication provider
schema:
$ref: ../swagger.yaml#/definitions/auth_provider_domain
"404":
description: Object not found
schema:
$ref: ../swagger.yaml#/definitions/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: ../swagger.yaml#/definitions/error
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error
x-koha-authorization:
permissions:
parameters: manage_authentication_providers
delete:
x-mojo-to: Auth::Provider::Domains#delete
operationId: delAuthProviderDomain
tags:
- auth_providers
summary: Delete authentication provider
parameters:
- $ref: ../swagger.yaml#/parameters/auth_provider_id_pp
- $ref: ../swagger.yaml#/parameters/auth_provider_domain_id_pp
produces:
- application/json
responses:
"204":
description: Authentication provider deleted
"401":
description: Authentication required
schema:
$ref: ../swagger.yaml#/definitions/error
"403":
description: Access forbidden
schema:
$ref: ../swagger.yaml#/definitions/error
"404":
description: City not found
schema:
$ref: ../swagger.yaml#/definitions/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error
x-koha-authorization:
permissions:
parameters: manage_authentication_providers

View File

@ -43,3 +43,82 @@
description: Access forbidden
schema:
$ref: "../swagger.yaml#/definitions/error"
"/oauth/login/{provider_code}/{interface}":
get:
x-mojo-to: OAuth::Client#login
operationId: loginOAuthClient
tags:
- oauth
summary: Login to OAuth provider
produces:
- application/json
parameters:
- name: provider_code
in: path
description: Code for 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
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: ../swagger.yaml#/definitions/error
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error

View File

@ -1,16 +1,16 @@
"/public/oauth/login/{provider}/{interface}":
"/public/oauth/login/{provider_code}/{interface}":
get:
x-mojo-to: OAuth::Client#login
operationId: loginOAuthClient
operationId: loginOAuthClientPublic
tags:
- oauth
summary: Login to OAuth provider
produces:
- application/json
parameters:
- name: provider
- name: provider_code
in: path
description: Name of OAuth provider
description: Code for OAuth provider
required: true
type: string
- name: interface
@ -25,7 +25,8 @@
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.
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
@ -60,8 +61,19 @@
"400":
description: Bad Request
schema:
$ref: "../swagger.yaml#/definitions/error"
$ref: ../swagger.yaml#/definitions/error
"403":
description: Access forbidden
schema:
$ref: "../swagger.yaml#/definitions/error"
$ref: ../swagger.yaml#/definitions/error
"500":
description: |
Internal server error. Possible `error_code` attribute values:
* `internal_server_error`
schema:
$ref: ../swagger.yaml#/definitions/error
"503":
description: Under maintenance
schema:
$ref: ../swagger.yaml#/definitions/error

View File

@ -8,6 +8,10 @@ definitions:
$ref: ./definitions/advancededitormacro.yaml
allows_renewal:
$ref: ./definitions/allows_renewal.yaml
auth_provider:
"$ref": ./definitions/auth_provider.yaml
auth_provider_domain:
"$ref": ./definitions/auth_provider_domain.yaml
basket:
$ref: ./definitions/basket.yaml
bundle_link:
@ -125,6 +129,14 @@ paths:
$ref: paths/auth.yaml#/~1auth~1two-factor~1registration
/auth/two-factor/registration/verification:
$ref: paths/auth.yaml#/~1auth~1two-factor~1registration~1verification
/auth/providers:
$ref: paths/auth.yaml#/~1auth~1providers
"/auth/providers/{auth_provider_id}":
$ref: paths/auth.yaml#/~1auth~1providers~1{auth_provider_id}
"/auth/providers/{auth_provider_id}/domains":
$ref: paths/auth.yaml#/~1auth~1providers~1{auth_provider_id}~1domains
"/auth/providers/{auth_provider_id}/domains/{auth_provider_domain_id}":
$ref: paths/auth.yaml#/~1auth~1providers~1{auth_provider_id}~1domains~1{auth_provider_domain_id}
"/biblios/{biblio_id}":
$ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}"
"/biblios/{biblio_id}/checkouts":
@ -269,8 +281,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/oauth/login/{provider_code}/{interface}":
$ref: ./paths/public_oauth.yaml#/~1public~1oauth~1login~1{provider_code}~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":
@ -324,6 +336,18 @@ parameters:
name: agreement_period_id
required: true
type: integer
auth_provider_id_pp:
description: Authentication provider internal identifier
in: path
name: auth_provider_id
required: true
type: integer
auth_provider_domain_id_pp:
description: Authentication provider domain internal identifier
in: path
name: auth_provider_domain_id
required: true
type: integer
biblio_id_pp:
description: Record internal identifier
in: path
@ -656,6 +680,9 @@ tags:
- description: "Manage article requests\n"
name: article_requests
x-displayName: Article requests
- description: "Manage authentication providers\n"
name: auth_providers
x-displayName: Authentication providers
- description: "Manage baskets for the acquisitions module\n"
name: baskets
x-displayName: Baskets

View File

@ -19,7 +19,7 @@
use Modern::Perl;
use Test::More tests => 5;
use Test::More tests => 6;
use Test::MockModule;
use Test::Exception;
@ -84,6 +84,7 @@ subtest 'set_config() tests' => sub {
plan tests => 4;
my $provider = $builder->build_object( { class => 'Koha::Auth::Providers', value => { protocol => 'OIDC' } } );
$provider = $provider->upgrade_class;
my $config = {
key => 'key',
@ -93,12 +94,12 @@ subtest 'set_config() tests' => sub {
throws_ok { $provider->set_config($config) }
'Koha::Exceptions::MissingParameter', 'Exception thrown on missing parameter';
is( $@->error, 'The well_known_url parameter is mandatory', 'Message is correct' );
is( $@->parameter, 'well_known_url', 'Message is correct' );
$config->{well_known_url} = 'https://koha-community.org/auth';
my $return = $provider->set_config($config);
is( ref($return), 'Koha::Auth::Provider', 'Return type is correct' );
is( ref($return), 'Koha::Auth::Provider::OIDC', 'Return type is correct' );
is_deeply( $provider->get_config, $config, 'Configuration stored correctly' );
};
@ -108,6 +109,7 @@ subtest 'set_config() tests' => sub {
plan tests => 4;
my $provider = $builder->build_object( { class => 'Koha::Auth::Providers', value => { protocol => 'OAuth' } } );
$provider = $provider->upgrade_class;
my $config = {
key => 'key',
@ -118,12 +120,12 @@ subtest 'set_config() tests' => sub {
throws_ok { $provider->set_config($config) }
'Koha::Exceptions::MissingParameter', 'Exception thrown on missing parameter';
is( $@->error, 'The authorize_url parameter is mandatory', 'Message is correct' );
is( $@->parameter, 'authorize_url', 'Message is correct' );
$config->{authorize_url} = 'https://koha-community.org/auth/authorize';
my $return = $provider->set_config($config);
is( ref($return), 'Koha::Auth::Provider', 'Return type is correct' );
is( ref($return), 'Koha::Auth::Provider::OAuth', 'Return type is correct' );
is_deeply( $provider->get_config, $config, 'Configuration stored correctly' );
};
@ -137,7 +139,7 @@ subtest 'set_config() tests' => sub {
throws_ok { $provider->set_config() }
'Koha::Exception', 'Exception thrown on unsupported protocol';
like( "$@", qr/Unsupported protocol CAS/, 'Message is correct' );
like( "$@", qr/This method needs to be subclassed/, 'Message is correct' );
};
$schema->storage->txn_rollback;
@ -177,3 +179,36 @@ subtest 'set_mapping() tests' => sub {
$schema->storage->txn_rollback;
};
subtest 'upgrade_class() tests' => sub {
plan tests => 5;
$schema->storage->txn_begin;
my $mapping = Koha::Auth::Provider::protocol_to_class_mapping;
my @protocols = keys %{ $mapping };
foreach my $protocol (@protocols) {
my $provider = $builder->build_object(
{
class => 'Koha::Auth::Providers',
value => { protocol => $protocol },
}
);
is( ref($provider), 'Koha::Auth::Provider', "Base class used for $protocol" );
# upgrade
$provider = $provider->upgrade_class;
is( ref($provider), $mapping->{$protocol}, "Class upgraded to " . $mapping->{$protocol} . "for protocol $protocol" );
}
my $provider = Koha::Auth::Provider->new({ protocol => 'Invalid' });
throws_ok
{ $provider->upgrade }
'Koha::Exception',
'Exception throw on invalid protocol';
$schema->storage->txn_rollback;
};