Bugzilla – Attachment 193624 Details for
Bug 39224
Migrate SAML/Shibboleth configuration into Identity Providers
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 39224: REST API for identity providers, mappings and hostnames
738dda6.patch (text/plain), 44.03 KB, created by
Martin Renvoize (ashimema)
on 2026-02-23 11:17:04 UTC
(
hide
)
Description:
Bug 39224: REST API for identity providers, mappings and hostnames
Filename:
MIME Type:
Creator:
Martin Renvoize (ashimema)
Created:
2026-02-23 11:17:04 UTC
Size:
44.03 KB
patch
obsolete
>From 738dda632646a6248fbb9b3b36670aa1e7d2770d Mon Sep 17 00:00:00 2001 >From: Martin Renvoize <martin.renvoize@openfifth.co.uk> >Date: Sun, 22 Feb 2026 20:19:12 +0000 >Subject: [PATCH] Bug 39224: REST API for identity providers, mappings and > hostnames > >Adds REST API endpoints for managing identity providers, their field >mappings, and hostname associations: > >- GET/POST /api/v1/auth/identity_providers/{id}/mappings >- GET/PUT/DELETE /api/v1/auth/identity_providers/{id}/mappings/{id} >- GET/POST /api/v1/auth/identity_providers/{id}/hostnames >- GET/PUT/DELETE /api/v1/auth/identity_providers/{id}/hostnames/{id} >- GET /api/v1/auth/hostnames (for hostname lookup) >- Updates existing provider endpoints with new fields > >Includes OpenAPI/Swagger definitions for all new endpoints and >updated definitions for existing endpoints. > >Test plan: >1. Run: prove t/db_dependent/api/v1/identity_providers.t >2. Test CRUD operations on mappings and hostnames via API > >Sponsored-by: ByWater Solutions >--- > Koha/REST/V1/Auth/Hostnames.pm | 76 +++ > .../V1/Auth/Identity/Provider/Hostnames.pm | 239 +++++++++ > .../V1/Auth/Identity/Provider/Mappings.pm | 210 ++++++++ > Koha/REST/V1/Auth/Identity/Providers.pm | 18 +- > api/v1/swagger/definitions/hostname.yaml | 13 + > .../definitions/identity_provider.yaml | 36 +- > .../definitions/identity_provider_domain.yaml | 4 + > .../identity_provider_hostname.yaml | 28 + > .../identity_provider_mapping.yaml | 30 ++ > api/v1/swagger/paths/auth.yaml | 500 ++++++++++++++++++ > api/v1/swagger/swagger.yaml | 36 ++ > 11 files changed, 1164 insertions(+), 26 deletions(-) > create mode 100644 Koha/REST/V1/Auth/Hostnames.pm > create mode 100644 Koha/REST/V1/Auth/Identity/Provider/Hostnames.pm > create mode 100644 Koha/REST/V1/Auth/Identity/Provider/Mappings.pm > create mode 100644 api/v1/swagger/definitions/hostname.yaml > create mode 100644 api/v1/swagger/definitions/identity_provider_hostname.yaml > create mode 100644 api/v1/swagger/definitions/identity_provider_mapping.yaml > >diff --git a/Koha/REST/V1/Auth/Hostnames.pm b/Koha/REST/V1/Auth/Hostnames.pm >new file mode 100644 >index 00000000000..338af56c302 >--- /dev/null >+++ b/Koha/REST/V1/Auth/Hostnames.pm >@@ -0,0 +1,76 @@ >+package Koha::REST::V1::Auth::Hostnames; >+ >+# 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 <https://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Mojo::Base 'Mojolicious::Controller'; >+ >+use Koha::Auth::Hostname; >+use Koha::Auth::Hostnames; >+ >+use Try::Tiny; >+ >+=head1 NAME >+ >+Koha::REST::V1::Auth::Hostnames - Controller library for handling hostname routes. >+ >+=head2 Operations >+ >+=head3 list >+ >+Controller method for listing all known hostnames. >+ >+=cut >+ >+sub list { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ return $c->render( >+ status => 200, >+ openapi => $c->objects->search( Koha::Auth::Hostnames->new ), >+ ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 get >+ >+Controller method for retrieving a single hostname by ID. >+ >+=cut >+ >+sub get { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $hostname = $c->objects->find( >+ Koha::Auth::Hostnames->new, >+ $c->param('hostname_id') >+ ); >+ >+ return $c->render_resource_not_found("Hostname") >+ unless $hostname; >+ >+ return $c->render( status => 200, openapi => $hostname ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+1; >diff --git a/Koha/REST/V1/Auth/Identity/Provider/Hostnames.pm b/Koha/REST/V1/Auth/Identity/Provider/Hostnames.pm >new file mode 100644 >index 00000000000..ab22b84ced7 >--- /dev/null >+++ b/Koha/REST/V1/Auth/Identity/Provider/Hostnames.pm >@@ -0,0 +1,239 @@ >+package Koha::REST::V1::Auth::Identity::Provider::Hostnames; >+ >+# 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 <https://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Mojo::Base 'Mojolicious::Controller'; >+ >+use Koha::Auth::Hostname; >+use Koha::Auth::Hostnames; >+use Koha::Auth::Identity::Provider::Hostname; >+use Koha::Auth::Identity::Provider::Hostnames; >+use Koha::Auth::Identity::Providers; >+ >+use Koha::Database; >+ >+use Scalar::Util qw(blessed); >+use Try::Tiny; >+ >+=head1 NAME >+ >+Koha::REST::V1::Auth::Identity::Provider::Hostnames - Controller library for handling >+identity provider hostname routes. >+ >+Each row is a many-to-many association between a hostname (via hostname_id FK) and an >+identity provider. The unique constraint is on (hostname_id, identity_provider_id). >+ >+=head2 Operations >+ >+=head3 list >+ >+Controller method for listing identity provider hostnames. >+ >+=cut >+ >+sub list { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $provider = Koha::Auth::Identity::Providers->find( $c->param('identity_provider_id') ); >+ >+ return $c->render_resource_not_found("Identity provider") >+ unless $provider; >+ >+ my $hostnames_rs = $provider->hostnames; >+ return $c->render( >+ status => 200, >+ openapi => $c->objects->search($hostnames_rs), >+ ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 get >+ >+Controller method for retrieving an identity provider hostname. >+ >+=cut >+ >+sub get { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $provider = Koha::Auth::Identity::Providers->find( $c->param('identity_provider_id') ); >+ >+ return $c->render_resource_not_found("Identity provider") >+ unless $provider; >+ >+ my $hostnames_rs = $provider->hostnames; >+ >+ my $hostname = $c->objects->find( >+ $hostnames_rs, >+ $c->param('identity_provider_hostname_id') >+ ); >+ >+ return $c->render_resource_not_found("Identity provider hostname") >+ unless $hostname; >+ >+ return $c->render( status => 200, openapi => $hostname ); >+ } catch { >+ $c->unhandled_exception($_); >+ } >+} >+ >+=head3 add >+ >+Controller method for adding an identity provider hostname. >+ >+Accepts either a C<hostname_id> integer (direct FK reference) or a C<hostname> >+string (the backend will find-or-create the canonical hostname record and resolve >+it to a C<hostname_id> before creating the bridge row). >+ >+=cut >+ >+sub add { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $provider = Koha::Auth::Identity::Providers->find( $c->param('identity_provider_id') ); >+ >+ return $c->render_resource_not_found("Identity provider") >+ unless $provider; >+ >+ Koha::Database->new->schema->txn_do( >+ sub { >+ my $body = $c->req->json; >+ $body->{identity_provider_id} = $c->param('identity_provider_id'); >+ >+ # If caller sent a hostname string instead of hostname_id, >+ # resolve it via find_or_create on the hostnames table. >+ unless ( $body->{hostname_id} ) { >+ my $hostname_str = delete $body->{hostname}; >+ my $hostname_rec = Koha::Auth::Hostnames->search( { hostname => $hostname_str } )->next >+ // Koha::Auth::Hostname->new( { hostname => $hostname_str } )->store; >+ $body->{hostname_id} = $hostname_rec->hostname_id; >+ } else { >+ >+ # hostname string is readOnly in the schema; strip it if present >+ delete $body->{hostname}; >+ } >+ >+ my $hostname = Koha::Auth::Identity::Provider::Hostname->new_from_api($body); >+ $hostname->store; >+ >+ $c->res->headers->location( $c->req->url->to_string . '/' . $hostname->id ); >+ return $c->render( >+ status => 201, >+ openapi => $c->objects->to_api($hostname), >+ ); >+ } >+ ); >+ } catch { >+ if ( blessed($_) and $_->isa('Koha::Exceptions::Object::DuplicateID') ) { >+ return $c->render( >+ status => 409, >+ openapi => { >+ error => 'A hostname entry with this hostname already exists for this provider', >+ error_code => 'duplicate_hostname', >+ } >+ ); >+ } >+ >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 update >+ >+Controller method for updating an identity provider hostname. >+ >+=cut >+ >+sub update { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $hostname = Koha::Auth::Identity::Provider::Hostnames->find( >+ { >+ identity_provider_id => $c->param('identity_provider_id'), >+ identity_provider_hostname_id => $c->param('identity_provider_hostname_id'), >+ } >+ ); >+ >+ return $c->render_resource_not_found("Identity provider hostname") >+ unless $hostname; >+ >+ return try { >+ Koha::Database->new->schema->txn_do( >+ sub { >+ my $body = $c->req->json; >+ >+ # hostname string is readOnly; strip it to avoid set_from_api errors >+ delete $body->{hostname}; >+ >+ $hostname->set_from_api($body); >+ $hostname->store->discard_changes; >+ >+ return $c->render( >+ status => 200, >+ openapi => $c->objects->to_api($hostname), >+ ); >+ } >+ ); >+ } catch { >+ if ( blessed($_) and $_->isa('Koha::Exceptions::Object::DuplicateID') ) { >+ return $c->render( >+ status => 409, >+ openapi => { >+ error => 'A hostname entry with this hostname already exists for this provider', >+ error_code => 'duplicate_hostname', >+ } >+ ); >+ } >+ >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 delete >+ >+Controller method for deleting an identity provider hostname. >+ >+=cut >+ >+sub delete { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $hostname = Koha::Auth::Identity::Provider::Hostnames->find( >+ { >+ identity_provider_id => $c->param('identity_provider_id'), >+ identity_provider_hostname_id => $c->param('identity_provider_hostname_id'), >+ } >+ ); >+ >+ return $c->render_resource_not_found("Identity provider hostname") >+ unless $hostname; >+ >+ return try { >+ $hostname->delete; >+ return $c->render_resource_deleted; >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+1; >diff --git a/Koha/REST/V1/Auth/Identity/Provider/Mappings.pm b/Koha/REST/V1/Auth/Identity/Provider/Mappings.pm >new file mode 100644 >index 00000000000..ac4c21952d9 >--- /dev/null >+++ b/Koha/REST/V1/Auth/Identity/Provider/Mappings.pm >@@ -0,0 +1,210 @@ >+package Koha::REST::V1::Auth::Identity::Provider::Mappings; >+ >+# 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 <https://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+use Mojo::Base 'Mojolicious::Controller'; >+ >+use Koha::Auth::Identity::Provider::Mapping; >+use Koha::Auth::Identity::Provider::Mappings; >+use Koha::Auth::Identity::Providers; >+ >+use Koha::Database; >+ >+use Scalar::Util qw(blessed); >+use Try::Tiny; >+ >+=head1 NAME >+ >+Koha::REST::V1::Auth::Identity::Provider::Mappings - Controller for identity >+provider field mapping routes. >+ >+=head2 Operations >+ >+=head3 list >+ >+Controller method for listing field mappings for an identity provider. >+ >+=cut >+ >+sub list { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $provider = Koha::Auth::Identity::Providers->find( $c->param('identity_provider_id') ); >+ >+ return $c->render_resource_not_found("Identity provider") >+ unless $provider; >+ >+ my $mappings_rs = $provider->mappings; >+ return $c->render( >+ status => 200, >+ openapi => $c->objects->search($mappings_rs) >+ ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 get >+ >+Controller method for retrieving a single field mapping. >+ >+=cut >+ >+sub get { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $provider = Koha::Auth::Identity::Providers->find( $c->param('identity_provider_id') ); >+ >+ return $c->render_resource_not_found("Identity provider") >+ unless $provider; >+ >+ my $mapping = $c->objects->find( >+ $provider->mappings, >+ $c->param('identity_provider_mapping_id') >+ ); >+ >+ return $c->render_resource_not_found("Identity provider mapping") >+ unless $mapping; >+ >+ return $c->render( status => 200, openapi => $mapping ); >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 add >+ >+Controller method for adding a field mapping to an identity provider. >+ >+=cut >+ >+sub add { >+ my $c = shift->openapi->valid_input or return; >+ >+ return try { >+ my $provider = Koha::Auth::Identity::Providers->find( $c->param('identity_provider_id') ); >+ >+ return $c->render_resource_not_found("Identity provider") >+ unless $provider; >+ >+ Koha::Database->new->schema->txn_do( >+ sub { >+ my $params = $c->req->json; >+ $params->{identity_provider_id} = $c->param('identity_provider_id'); >+ >+ my $mapping = Koha::Auth::Identity::Provider::Mapping->new_from_api($params); >+ $mapping->store; >+ >+ $c->res->headers->location( $c->req->url->to_string . '/' . $mapping->id ); >+ return $c->render( >+ status => 201, >+ openapi => $c->objects->to_api($mapping), >+ ); >+ } >+ ); >+ } catch { >+ if ( blessed($_) and $_->isa('Koha::Exceptions::MissingParameter') ) { >+ return $c->render( >+ status => 400, >+ openapi => { >+ error => 'Missing parameter: ' . $_->parameter, >+ error_code => 'missing_parameter', >+ } >+ ); >+ } >+ >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 update >+ >+Controller method for updating a field mapping. >+ >+=cut >+ >+sub update { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $mapping = Koha::Auth::Identity::Provider::Mappings->find( >+ { >+ identity_provider_id => $c->param('identity_provider_id'), >+ mapping_id => $c->param('identity_provider_mapping_id'), >+ } >+ ); >+ >+ return $c->render_resource_not_found("Identity provider mapping") >+ unless $mapping; >+ >+ return try { >+ Koha::Database->new->schema->txn_do( >+ sub { >+ $mapping->set_from_api( $c->req->json ); >+ $mapping->store->discard_changes; >+ >+ return $c->render( >+ status => 200, >+ openapi => $c->objects->to_api($mapping), >+ ); >+ } >+ ); >+ } catch { >+ if ( blessed($_) and $_->isa('Koha::Exceptions::MissingParameter') ) { >+ return $c->render( >+ status => 400, >+ openapi => { >+ error => 'Missing parameter: ' . $_->parameter, >+ error_code => 'missing_parameter', >+ } >+ ); >+ } >+ >+ $c->unhandled_exception($_); >+ }; >+} >+ >+=head3 delete >+ >+Controller method for deleting a field mapping. >+ >+=cut >+ >+sub delete { >+ my $c = shift->openapi->valid_input or return; >+ >+ my $mapping = Koha::Auth::Identity::Provider::Mappings->find( >+ { >+ identity_provider_id => $c->param('identity_provider_id'), >+ mapping_id => $c->param('identity_provider_mapping_id'), >+ } >+ ); >+ >+ return $c->render_resource_not_found("Identity provider mapping") >+ unless $mapping; >+ >+ return try { >+ $mapping->delete; >+ return $c->render_resource_deleted; >+ } catch { >+ $c->unhandled_exception($_); >+ }; >+} >+ >+1; >diff --git a/Koha/REST/V1/Auth/Identity/Providers.pm b/Koha/REST/V1/Auth/Identity/Providers.pm >index b3ad363f067..748d929db59 100644 >--- a/Koha/REST/V1/Auth/Identity/Providers.pm >+++ b/Koha/REST/V1/Auth/Identity/Providers.pm >@@ -19,8 +19,6 @@ use Modern::Perl; > > use Mojo::Base 'Mojolicious::Controller'; > >-use Koha::Auth::Identity::Provider::OAuth; >-use Koha::Auth::Identity::Provider::OIDC; > use Koha::Auth::Identity::Providers; > > use Koha::Database; >@@ -94,12 +92,13 @@ sub add { > my $body = $c->req->json; > > my $config = delete $body->{config}; >- my $mapping = delete $body->{mapping}; > my $protocol = delete $body->{protocol}; > >- my $class = Koha::Auth::Identity::Provider::protocol_to_class_mapping->{$protocol}; >+ my $class = Koha::Auth::Identity::Providers->new->_polymorphic_map->{$protocol}; > >- my $provider = $class->new_from_api($body)->set_config($config)->set_mapping($mapping)->store; >+ Koha::Exception->throw("$protocol is not a valid protocol") unless $class; >+ >+ my $provider = $class->new_from_api($body)->set_config($config)->store; > > $c->res->headers->location( $c->req->url->to_string . '/' . $provider->identity_provider_id ); > return $c->render( >@@ -146,12 +145,13 @@ sub update { > > my $body = $c->req->json; > >- my $config = delete $body->{config}; >- my $mapping = delete $body->{mapping}; >+ my $config = delete $body->{config}; > >- $provider = $provider->set_from_api($body)->upgrade_class; >+ $provider->set_from_api($body); >+ $provider = Koha::Auth::Identity::Providers->new->object_class( $provider->_result ) >+ ->_new_from_dbic( $provider->_result ); > >- $provider->set_config($config)->set_mapping($mapping)->store; >+ $provider->set_config($config)->store; > > $provider->discard_changes; > >diff --git a/api/v1/swagger/definitions/hostname.yaml b/api/v1/swagger/definitions/hostname.yaml >new file mode 100644 >index 00000000000..f884429806b >--- /dev/null >+++ b/api/v1/swagger/definitions/hostname.yaml >@@ -0,0 +1,13 @@ >+--- >+type: object >+properties: >+ hostname_id: >+ description: Internally assigned identifier for this hostname >+ type: integer >+ readOnly: true >+ hostname: >+ description: Server hostname string (matches SERVER_NAME) >+ type: string >+additionalProperties: false >+required: >+ - hostname >diff --git a/api/v1/swagger/definitions/identity_provider.yaml b/api/v1/swagger/definitions/identity_provider.yaml >index c9fc649d428..69a32058b77 100644 >--- a/api/v1/swagger/definitions/identity_provider.yaml >+++ b/api/v1/swagger/definitions/identity_provider.yaml >@@ -17,33 +17,35 @@ properties: > enum: > - OAuth > - OIDC >- - CAS (not implemented) >- - LDAP (not implemented) >- mapping: >- description: Attribute mapping >+ - SAML2 >+ config: >+ description: Protocol-specific configuration > 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 >+ description: Icon url for display on login buttons > type: >- - string >- - "null" >+ - string >+ - "null" >+ enabled: >+ description: Whether this provider is active >+ type: boolean > domains: > description: Configured domains for the identity provider > type: > - array > - "null" >+ hostnames: >+ description: Configured hostnames for the identity provider >+ type: >+ - array >+ - "null" >+ mappings: >+ description: Configured mappings for the identity provider >+ type: >+ - array >+ - "null" > additionalProperties: false > required: > - config >diff --git a/api/v1/swagger/definitions/identity_provider_domain.yaml b/api/v1/swagger/definitions/identity_provider_domain.yaml >index b18b1a6f6d6..db3b6209c93 100644 >--- a/api/v1/swagger/definitions/identity_provider_domain.yaml >+++ b/api/v1/swagger/definitions/identity_provider_domain.yaml >@@ -38,6 +38,9 @@ properties: > allow_staff: > description: If this domain can be used for staff login > type: boolean >+ send_welcome_email: >+ description: Send welcome email to patron on first login via this domain >+ type: boolean > additionalProperties: false > required: > - identity_provider_domain_id >@@ -49,3 +52,4 @@ required: > - default_category_id > - allow_opac > - allow_staff >+ - send_welcome_email >diff --git a/api/v1/swagger/definitions/identity_provider_hostname.yaml b/api/v1/swagger/definitions/identity_provider_hostname.yaml >new file mode 100644 >index 00000000000..473dc45094b >--- /dev/null >+++ b/api/v1/swagger/definitions/identity_provider_hostname.yaml >@@ -0,0 +1,28 @@ >+--- >+type: object >+properties: >+ identity_provider_hostname_id: >+ type: integer >+ description: Internally assigned identifier for this hostname-provider association >+ readOnly: true >+ hostname_id: >+ description: Identifier of the associated hostname record >+ type: integer >+ hostname: >+ description: > >+ Server hostname string. When creating a new association, supply either >+ this field (the backend will find-or-create the canonical hostname record) >+ or hostname_id. In responses this field is always populated. >+ type: string >+ identity_provider_id: >+ description: Identity provider associated with this hostname >+ type: integer >+ is_enabled: >+ description: Whether this hostname is active for this provider >+ type: boolean >+ force_sso: >+ description: > >+ Force SSO redirect for users visiting this hostname. Only one >+ identity provider should have this enabled per hostname. >+ type: boolean >+additionalProperties: false >diff --git a/api/v1/swagger/definitions/identity_provider_mapping.yaml b/api/v1/swagger/definitions/identity_provider_mapping.yaml >new file mode 100644 >index 00000000000..11658bf7cb3 >--- /dev/null >+++ b/api/v1/swagger/definitions/identity_provider_mapping.yaml >@@ -0,0 +1,30 @@ >+--- >+type: object >+properties: >+ mapping_id: >+ type: integer >+ description: Internally assigned mapping identifier >+ readOnly: true >+ identity_provider_id: >+ type: integer >+ description: Reference to identity provider >+ readOnly: true >+ provider_field: >+ type: >+ - string >+ - "null" >+ description: Attribute name from the identity provider >+ koha_field: >+ type: string >+ description: Corresponding field in Koha borrowers table >+ default_content: >+ type: >+ - string >+ - "null" >+ description: Default value to use if the provider does not supply this attribute >+ is_matchpoint: >+ type: boolean >+ description: Use this field to match existing patrons (only one per provider) >+additionalProperties: false >+required: >+ - koha_field >diff --git a/api/v1/swagger/paths/auth.yaml b/api/v1/swagger/paths/auth.yaml >index 700023cf555..f63e8a5d749 100644 >--- a/api/v1/swagger/paths/auth.yaml >+++ b/api/v1/swagger/paths/auth.yaml >@@ -616,6 +616,8 @@ > type: string > enum: > - domains >+ - hostnames >+ - mappings > collectionFormat: csv > produces: > - application/json >@@ -731,6 +733,8 @@ > type: string > enum: > - domains >+ - hostnames >+ - mappings > collectionFormat: csv > produces: > - application/json >@@ -1104,6 +1108,183 @@ > x-koha-authorization: > permissions: > parameters: manage_identity_providers >+"/auth/identity_providers/{identity_provider_id}/mappings": >+ get: >+ x-mojo-to: Auth::Identity::Provider::Mappings#list >+ operationId: listIdentityProviderMappings >+ tags: >+ - identity_providers >+ summary: List field mappings for an identity provider >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/identity_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/request_id_header >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: List of field mappings >+ schema: >+ type: array >+ items: >+ $ref: ../swagger.yaml#/definitions/identity_provider_mapping >+ "400": >+ description: | >+ Bad request. Possible `error_code` attribute values: >+ >+ * `invalid_query` >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "404": >+ description: Identity provider not found >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ x-koha-authorization: >+ permissions: >+ parameters: manage_identity_providers >+ post: >+ x-mojo-to: Auth::Identity::Provider::Mappings#add >+ operationId: addIdentityProviderMapping >+ tags: >+ - identity_providers >+ summary: Add a field mapping to an identity provider >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp >+ - name: body >+ in: body >+ description: A field mapping object >+ required: true >+ schema: >+ $ref: ../swagger.yaml#/definitions/identity_provider_mapping >+ produces: >+ - application/json >+ responses: >+ "201": >+ description: The created field mapping >+ schema: >+ $ref: ../swagger.yaml#/definitions/identity_provider_mapping >+ "400": >+ description: Bad request >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "404": >+ description: Identity provider not found >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ x-koha-authorization: >+ permissions: >+ parameters: manage_identity_providers >+"/auth/identity_providers/{identity_provider_id}/mappings/{identity_provider_mapping_id}": >+ get: >+ x-mojo-to: Auth::Identity::Provider::Mappings#get >+ operationId: getIdentityProviderMapping >+ tags: >+ - identity_providers >+ summary: Get a field mapping >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp >+ - $ref: ../swagger.yaml#/parameters/identity_provider_mapping_id_pp >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: A field mapping >+ schema: >+ $ref: ../swagger.yaml#/definitions/identity_provider_mapping >+ "400": >+ description: Bad request >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "404": >+ description: Mapping not found >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ x-koha-authorization: >+ permissions: >+ parameters: manage_identity_providers >+ put: >+ x-mojo-to: Auth::Identity::Provider::Mappings#update >+ operationId: updateIdentityProviderMapping >+ tags: >+ - identity_providers >+ summary: Update a field mapping >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp >+ - $ref: ../swagger.yaml#/parameters/identity_provider_mapping_id_pp >+ - name: body >+ in: body >+ description: Updated mapping object >+ required: true >+ schema: >+ $ref: ../swagger.yaml#/definitions/identity_provider_mapping >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: Updated field mapping >+ schema: >+ $ref: ../swagger.yaml#/definitions/identity_provider_mapping >+ "400": >+ description: Bad request >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "404": >+ description: Mapping not found >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ x-koha-authorization: >+ permissions: >+ parameters: manage_identity_providers >+ delete: >+ x-mojo-to: Auth::Identity::Provider::Mappings#delete >+ operationId: delIdentityProviderMapping >+ tags: >+ - identity_providers >+ summary: Delete a field mapping >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp >+ - $ref: ../swagger.yaml#/parameters/identity_provider_mapping_id_pp >+ produces: >+ - application/json >+ responses: >+ "204": >+ description: Field mapping deleted >+ "400": >+ description: Bad request >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "404": >+ description: Mapping not found >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ x-koha-authorization: >+ permissions: >+ parameters: manage_identity_providers > "/auth/password/validation": > post: > x-mojo-to: Auth::Password#validate >@@ -1184,3 +1365,322 @@ > x-koha-authorization: > permissions: > borrowers: api_validate_password >+"/auth/identity_providers/{identity_provider_id}/hostnames": >+ get: >+ x-mojo-to: Auth::Identity::Provider::Hostnames#list >+ operationId: listIdentityProviderHostnames >+ tags: >+ - identity_providers >+ summary: List identity provider hostnames >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/identity_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/request_id_header >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: A list of identity provider hostnames >+ schema: >+ type: array >+ items: >+ $ref: ../swagger.yaml#/definitions/identity_provider_hostname >+ "400": >+ description: | >+ Bad request. Possible `error_code` attribute values: >+ >+ * `invalid_query` >+ 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_identity_providers >+ post: >+ x-mojo-to: Auth::Identity::Provider::Hostnames#add >+ operationId: addIdentityProviderHostname >+ tags: >+ - identity_providers >+ summary: Add an identity provider hostname >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp >+ - name: body >+ in: body >+ description: An identity provider hostname object >+ required: true >+ schema: >+ $ref: ../swagger.yaml#/definitions/identity_provider_hostname >+ produces: >+ - application/json >+ responses: >+ "201": >+ description: Created identity provider hostname >+ schema: >+ $ref: ../swagger.yaml#/definitions/identity_provider_hostname >+ "400": >+ description: Bad request >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "403": >+ description: Access forbidden >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "404": >+ description: Identity provider not found >+ schema: >+ $ref: ../swagger.yaml#/definitions/error >+ "409": >+ description: Conflict - hostname already exists >+ 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_identity_providers >+"/auth/identity_providers/{identity_provider_id}/hostnames/{identity_provider_hostname_id}": >+ get: >+ x-mojo-to: Auth::Identity::Provider::Hostnames#get >+ operationId: getIdentityProviderHostname >+ tags: >+ - identity_providers >+ summary: Get an identity provider hostname >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp >+ - $ref: ../swagger.yaml#/parameters/identity_provider_hostname_id_pp >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: An identity provider hostname >+ schema: >+ $ref: ../swagger.yaml#/definitions/identity_provider_hostname >+ "400": >+ description: Bad request >+ 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_identity_providers >+ put: >+ x-mojo-to: Auth::Identity::Provider::Hostnames#update >+ operationId: updateIdentityProviderHostname >+ tags: >+ - identity_providers >+ summary: Update an identity provider hostname >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp >+ - $ref: ../swagger.yaml#/parameters/identity_provider_hostname_id_pp >+ - name: body >+ in: body >+ description: An identity provider hostname object >+ required: true >+ schema: >+ $ref: ../swagger.yaml#/definitions/identity_provider_hostname >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: Updated identity provider hostname >+ schema: >+ $ref: ../swagger.yaml#/definitions/identity_provider_hostname >+ "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 >+ "409": >+ description: Conflict - hostname already exists >+ 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_identity_providers >+ delete: >+ x-mojo-to: Auth::Identity::Provider::Hostnames#delete >+ operationId: deleteIdentityProviderHostname >+ tags: >+ - identity_providers >+ summary: Delete an identity provider hostname >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp >+ - $ref: ../swagger.yaml#/parameters/identity_provider_hostname_id_pp >+ produces: >+ - application/json >+ responses: >+ "204": >+ description: Identity provider hostname deleted >+ "400": >+ description: Bad request >+ schema: >+ $ref: "../swagger.yaml#/definitions/error" >+ "401": >+ description: Authentication required >+ 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_identity_providers >+/auth/hostnames: >+ get: >+ x-mojo-to: Auth::Hostnames#list >+ operationId: listHostnames >+ tags: >+ - identity_providers >+ summary: List all known hostnames >+ 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/request_id_header >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: A list of hostnames >+ schema: >+ type: array >+ items: >+ $ref: ../swagger.yaml#/definitions/hostname >+ "400": >+ description: | >+ Bad request. Possible `error_code` attribute values: >+ >+ * `invalid_query` >+ 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_identity_providers >+"/auth/hostnames/{hostname_id}": >+ get: >+ x-mojo-to: Auth::Hostnames#get >+ operationId: getHostname >+ tags: >+ - identity_providers >+ summary: Get a hostname >+ parameters: >+ - $ref: ../swagger.yaml#/parameters/hostname_id_pp >+ produces: >+ - application/json >+ responses: >+ "200": >+ description: A hostname >+ schema: >+ $ref: ../swagger.yaml#/definitions/hostname >+ "400": >+ description: Bad request >+ 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_identity_providers >diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml >index 9a9b7af7565..16805682ce9 100644 >--- a/api/v1/swagger/swagger.yaml >+++ b/api/v1/swagger/swagger.yaml >@@ -20,6 +20,12 @@ definitions: > $ref: ./definitions/identity_provider.yaml > identity_provider_domain: > $ref: ./definitions/identity_provider_domain.yaml >+ identity_provider_mapping: >+ $ref: ./definitions/identity_provider_mapping.yaml >+ hostname: >+ $ref: ./definitions/hostname.yaml >+ identity_provider_hostname: >+ $ref: ./definitions/identity_provider_hostname.yaml > basket: > $ref: ./definitions/basket.yaml > booking: >@@ -269,6 +275,18 @@ paths: > $ref: ./paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}~1domains > "/auth/identity_providers/{identity_provider_id}/domains/{identity_provider_domain_id}": > $ref: ./paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}~1domains~1{identity_provider_domain_id} >+ "/auth/identity_providers/{identity_provider_id}/mappings": >+ $ref: ./paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}~1mappings >+ "/auth/identity_providers/{identity_provider_id}/mappings/{identity_provider_mapping_id}": >+ $ref: "./paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}~1mappings~1{identity_provider_mapping_id}" >+ /auth/hostnames: >+ $ref: ./paths/auth.yaml#/~1auth~1hostnames >+ "/auth/hostnames/{hostname_id}": >+ $ref: "./paths/auth.yaml#/~1auth~1hostnames~1{hostname_id}" >+ "/auth/identity_providers/{identity_provider_id}/hostnames": >+ $ref: "./paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}~1hostnames" >+ "/auth/identity_providers/{identity_provider_id}/hostnames/{identity_provider_hostname_id}": >+ $ref: "./paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}~1hostnames~1{identity_provider_hostname_id}" > /authorised_value_categories: > $ref: ./paths/authorised_value_categories.yaml#/~1authorised_value_categories > "/authorised_value_categories/{authorised_value_category_name}/authorised_values": >@@ -711,6 +729,24 @@ parameters: > name: identity_provider_domain_id > required: true > type: integer >+ identity_provider_mapping_id_pp: >+ description: Identity provider field mapping internal identifier >+ in: path >+ name: identity_provider_mapping_id >+ required: true >+ type: integer >+ hostname_id_pp: >+ description: Hostname internal identifier >+ in: path >+ name: hostname_id >+ required: true >+ type: integer >+ identity_provider_hostname_id_pp: >+ description: Identity provider hostname internal identifier >+ in: path >+ name: identity_provider_hostname_id >+ required: true >+ type: integer > biblio_id_pp: > description: Record internal identifier > in: path >-- >2.53.0 >
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 39224
:
189234
|
189235
|
189236
|
189237
|
189238
|
189239
|
189240
|
189241
|
189242
|
189243
|
189244
|
193618
|
193619
|
193620
|
193621
|
193622
|
193623
|
193624
|
193625
|
193626
|
193627
|
193681
|
193682
|
193683
|
193684
|
193685
|
193686
|
193687
|
193688
|
193689
|
193690
|
193691
|
193692