use Modern::Perl;
use Koha::Exceptions::Auth;
-use Koha::Auth::Providers;
+use Koha::Auth::Identity::Providers;
=head1 NAME
my $interface = $params->{interface};
my $config = $params->{config};
- my $provider = Koha::Auth::Providers->search({ code => $provider_code })->next;
+ my $provider = Koha::Auth::Identity::Providers->search({ code => $provider_code })->next;
my ( $mapped_data, $patron ) = $self->_get_data_and_patron({ provider => $provider, data => $data, config => $config });
$mapped_data->{categorycode} = $domain->default_category_id;
$mapped_data->{branchcode} = $domain->default_library_id;
+ $patron->set($mapped_data)->store if $patron && $domain->update_on_auth;
+
return ( $patron, $mapped_data, $domain );
}
}
my $interface = $params->{interface};
my $domains = $provider->domains;
- my $pattern = '@';
my $allow = "allow_$interface";
my @subdomain_matches;
my $default_match;
while ( my $domain = $domains->next ) {
next unless $domain->$allow;
+ my $pattern = '@';
my $domain_text = $domain->domain;
unless ( defined $domain_text && $domain_text ne '') {
$default_match = $domain;
next;
}
my ( $asterisk, $domain_name ) = ( $domain_text =~ /^(\*)?(.+)$/ );
- if ( $asterisk eq '*' ) {
+ if ( defined $asterisk && $asterisk eq '*' ) {
$pattern .= '.*';
}
$domain_name =~ s/\./\\\./g;
$pattern .= $domain_name . '$';
if ( $user_email =~ /$pattern/ ) {
- if ( $asterisk eq '*' ) {
+ if ( defined $asterisk && $asterisk eq '*' ) {
push @subdomain_matches, { domain => $domain, match_length => length $domain_name };
} else {
return $subdomain_matches[0]->{domain};
}
- return $default_match || 0;
+ return $default_match;
}
=head3 has_valid_domain_config
return {};
}
-=head3 _tranverse_hash
+=head3 _traverse_hash
- my $value = $auth_client->_tranverse_hash( { base => $base_hash, keys => $key_string } );
+ my $value = $auth_client->_traverse_hash( { base => $base_hash, keys => $key_string } );
Get deep nested value in a hash.
=cut
-sub _tranverse_hash {
+sub _traverse_hash {
my ($self, $params) = @_;
my $base = $params->{base};
my $keys = $params->{keys};
return unless defined $key;
my $value = ref $base eq 'HASH' ? $base->{$key} : $base->[$key];
return $value unless $rest;
- return $self->_tranverse_hash({ base => $value, keys => $rest });
+ return $self->_traverse_hash({ base => $value, keys => $rest });
}
1;
if ( defined $value and $matchpoint_rs->count ) {
$patron = $matchpoint_rs->next;
}
-
- return ( $mapped_data, $patron )
- if $patron;
}
if ( defined $config->{userinfo_url} ) {
foreach my $key ( keys %$mapping ) {
my $pkey = $mapping->{$key};
- my $value = $self->_tranverse_hash( { base => $claim, keys => $pkey } );
+ my $value = $self->_traverse_hash( { base => $claim, keys => $pkey } );
$mapped_data->{$key} = $value
if defined $value;
}
- my $value = $mapped_data->{$matchpoint};
+ unless ($patron) {
+ my $value = $mapped_data->{$matchpoint};
- my $matchpoint_rs = Koha::Patrons->search( { $matchpoint => $value } );
+ my $matchpoint_rs = Koha::Patrons->search( { $matchpoint => $value } );
- if ( defined $value and $matchpoint_rs->count ) {
- $patron = $matchpoint_rs->next;
+ if ( defined $value and $matchpoint_rs->count ) {
+ $patron = $matchpoint_rs->next;
+ }
}
- return ( $mapped_data, $patron )
- if $patron;
}
+
+ return ( $mapped_data, $patron )
+ if $patron;
}
1;
--- /dev/null
+package Koha::Auth::Identity::Provider;
+
+# 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::Object);
+
+use JSON qw( decode_json encode_json );
+use Try::Tiny;
+
+use Koha::Auth::Identity::Provider::Domains;
+use Koha::Exceptions;
+use Koha::Exceptions::Object;
+
+=head1 NAME
+
+Koha::Auth::Identity::Provider - Koha Auth Provider Object class
+
+=head1 API
+
+=head2 Class methods
+
+=head3 domains
+
+ my $domains = $provider->domains;
+
+Returns the related I<Koha::Auth::Identity::Provider::Domains> iterator.
+
+=cut
+
+sub domains {
+ my ($self) = @_;
+
+ return Koha::Auth::Identity::Provider::Domains->_new_from_dbic( scalar $self->_result->domains );
+}
+
+=head3 get_config
+
+ my $config = $provider->get_config;
+
+Returns a I<hashref> containing the configuration parameters for the provider.
+
+=cut
+
+sub get_config {
+ my ($self) = @_;
+
+ return try {
+ return decode_json( $self->config );
+ }
+ catch {
+ Koha::Exceptions::Object::BadValue->throw("Error reading JSON data: $_");
+ };
+}
+
+=head3 set_config
+
+ # OAuth
+ $provider->set_config(
+ {
+ key => 'APP_ID',
+ secret => 'SECRET_KEY',
+ authorize_url => 'https://provider.example.com/auth',
+ token_url => 'https://provider.example.com/token',
+ }
+ );
+
+ # OIDC
+ $provider->set_config(
+ {
+ key => 'APP_ID',
+ secret => 'SECRET_KEY',
+ well_known_url => 'https://login.microsoftonline.com/tenant-id/v2.0/.well-known/openid-configuration',
+ }
+ );
+
+This method stores the passed config in JSON format.
+
+=cut
+
+sub set_config {
+ my ($self, $config) = @_;
+
+ my @mandatory = $self->mandatory_config_attributes;
+
+ for my $param (@mandatory) {
+ unless ( defined( $config->{$param} ) ) {
+ Koha::Exceptions::MissingParameter->throw( parameter => $param );
+ }
+ }
+
+ try {
+ my $encoded_config = encode_json($config);
+ $self->config($encoded_config)->store;
+ } catch {
+ Koha::Exceptions::Object::BadValue->throw("Error serializing data into JSON: $_");
+ };
+
+ return $self;
+}
+
+=head3 get_mapping
+
+ my $mapping = $provider->get_mapping;
+
+Returns a I<hashref> containing the attribute mapping for the provider.
+
+=cut
+
+sub get_mapping {
+ my ($self) = @_;
+
+ return try {
+ return decode_json( $self->mapping );
+ }
+ catch {
+ Koha::Exceptions::Object::BadValue->throw("Error reading JSON data: $_");
+ };
+}
+
+=head3 set_mapping
+
+ $provider->mapping( $mapping );
+
+This method stores the passed mappings in JSON format.
+
+=cut
+
+sub set_mapping {
+ my ($self, $mapping) = @_;
+
+ try {
+ my $encoded_mapping = encode_json( $mapping );
+ $self->mapping( $encoded_mapping )->store;
+ }
+ catch {
+ Koha::Exceptions::Object::BadValue->throw("Error serializing data into JSON: $_");
+ };
+
+ 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::Identity::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
+
+sub _type {
+ return 'IdentityProvider';
+}
+
+=head3 protocol_to_class_mapping
+
+ my $mapping = Koha::Auth::Identity::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::Identity::Provider::OAuth',
+ OIDC => 'Koha::Auth::Identity::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;
--- /dev/null
+package Koha::Auth::Identity::Provider::Domain;
+
+# 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::Object);
+
+=head1 NAME
+
+Koha::Auth::Identity::Provider::Domain - Koha Auth Provider Domain Object class
+
+=head1 API
+
+=head2 Internal methods
+
+=head3 _type
+
+=cut
+
+sub _type {
+ return 'IdentityProviderDomain';
+}
+
+1;
--- /dev/null
+package Koha::Auth::Identity::Provider::Domains;
+
+# 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 Koha::Database;
+use Koha::Auth::Identity::Provider::Domain;
+
+use base qw(Koha::Objects);
+
+=head1 NAME
+
+Koha::Auth::Identity::Providers - Koha Auth Provider Object class
+
+=head1 API
+
+=head2 Internal methods
+
+=cut
+
+=head3 _type
+
+=cut
+
+sub _type {
+ return 'IdentityProviderDomain';
+}
+
+=head3 object_class
+
+=cut
+
+sub object_class {
+ return 'Koha::Auth::Identity::Provider::Domain';
+}
+
+1;
--- /dev/null
+package Koha::Auth::Identity::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::Identity::Provider);
+
+=head1 NAME
+
+Koha::Auth::Identity::Provider::OAuth - Koha Auth Provider Object class
+
+=head1 API
+
+=head2 Class methods
+
+=head3 new
+
+ my $oauth = Koha::Auth::Identity::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;
--- /dev/null
+package Koha::Auth::Identity::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::Identity::Provider);
+
+=head1 NAME
+
+Koha::Auth::Identity::Provider::OIDC - Koha Auth Provider Object class
+
+=head1 API
+
+=head2 Class methods
+
+=head3 new
+
+ my $oidc = Koha::Auth::Identity::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;
--- /dev/null
+package Koha::Auth::Identity::Providers;
+
+# 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 Koha::Database;
+use Koha::Auth::Identity::Provider;
+
+use base qw(Koha::Objects);
+
+=head1 NAME
+
+Koha::Auth::Identity::Providers - Koha Auth Provider Object class
+
+=head1 API
+
+=head2 Internal methods
+
+=cut
+
+=head3 _type
+
+=cut
+
+sub _type {
+ return 'IdentityProvider';
+}
+
+=head3 object_class
+
+=cut
+
+sub object_class {
+ return 'Koha::Auth::Identity::Provider';
+}
+
+1;
+++ /dev/null
-package Koha::Auth::Provider;
-
-# 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::Object);
-
-use JSON qw( decode_json encode_json );
-use Try::Tiny;
-
-use Koha::Auth::Provider::Domains;
-use Koha::Exceptions;
-use Koha::Exceptions::Object;
-
-=head1 NAME
-
-Koha::Auth::Provider - Koha Auth Provider Object class
-
-=head1 API
-
-=head2 Class methods
-
-=head3 domains
-
- my $domains = $provider->domains;
-
-Returns the related I<Koha::Auth::Provider::Domains> iterator.
-
-=cut
-
-sub domains {
- my ($self) = @_;
-
- return Koha::Auth::Provider::Domains->_new_from_dbic( scalar $self->_result->domains );
-}
-
-=head3 get_config
-
- my $config = $provider->get_config;
-
-Returns a I<hashref> containing the configuration parameters for the provider.
-
-=cut
-
-sub get_config {
- my ($self) = @_;
-
- return try {
- return decode_json( $self->config );
- }
- catch {
- Koha::Exceptions::Object::BadValue->throw("Error reading JSON data: $_");
- };
-}
-
-=head3 set_config
-
- # OAuth
- $provider->set_config(
- {
- key => 'APP_ID',
- secret => 'SECRET_KEY',
- authorize_url => 'https://provider.example.com/auth',
- token_url => 'https://provider.example.com/token',
- }
- );
-
- # OIDC
- $provider->set_config(
- {
- key => 'APP_ID',
- secret => 'SECRET_KEY',
- well_known_url => 'https://login.microsoftonline.com/tenant-id/v2.0/.well-known/openid-configuration',
- }
- );
-
-This method stores the passed config in JSON format.
-
-=cut
-
-sub set_config {
- my ($self, $config) = @_;
-
- my @mandatory = $self->mandatory_config_attributes;
-
- for my $param (@mandatory) {
- unless ( defined( $config->{$param} ) ) {
- Koha::Exceptions::MissingParameter->throw( parameter => $param );
- }
- }
-
- try {
- my $encoded_config = encode_json($config);
- $self->config($encoded_config)->store;
- } catch {
- Koha::Exceptions::Object::BadValue->throw("Error serializing data into JSON: $_");
- };
-
- return $self;
-}
-
-=head3 get_mapping
-
- my $mapping = $provider->get_mapping;
-
-Returns a I<hashref> containing the attribute mapping for the provider.
-
-=cut
-
-sub get_mapping {
- my ($self) = @_;
-
- return try {
- return decode_json( $self->mapping );
- }
- catch {
- Koha::Exceptions::Object::BadValue->throw("Error reading JSON data: $_");
- };
-}
-
-=head3 set_mapping
-
- $provider->mapping( $mapping );
-
-This method stores the passed mappings in JSON format.
-
-=cut
-
-sub set_mapping {
- my ($self, $mapping) = @_;
-
- try {
- my $encoded_mapping = encode_json( $mapping );
- $self->mapping( $encoded_mapping )->store;
- }
- catch {
- Koha::Exceptions::Object::BadValue->throw("Error serializing data into JSON: $_");
- };
-
- 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
-
-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;
+++ /dev/null
-package Koha::Auth::Provider::Domain;
-
-# 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::Object);
-
-=head1 NAME
-
-Koha::Auth::Provider::Domain - Koha Auth Provider Domain Object class
-
-=head1 API
-
-=head2 Internal methods
-
-=head3 _type
-
-=cut
-
-sub _type {
- return 'AuthProviderDomain';
-}
-
-1;
+++ /dev/null
-package Koha::Auth::Provider::Domains;
-
-# 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 Koha::Database;
-use Koha::Auth::Provider::Domain;
-
-use base qw(Koha::Objects);
-
-=head1 NAME
-
-Koha::Auth::Providers - Koha Auth Provider Object class
-
-=head1 API
-
-=head2 Internal methods
-
-=cut
-
-=head3 _type
-
-=cut
-
-sub _type {
- return 'AuthProviderDomain';
-}
-
-=head3 object_class
-
-=cut
-
-sub object_class {
- return 'Koha::Auth::Provider::Domain';
-}
-
-1;
+++ /dev/null
-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;
+++ /dev/null
-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;
+++ /dev/null
-package Koha::Auth::Providers;
-
-# 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 Koha::Database;
-use Koha::Auth::Provider;
-
-use base qw(Koha::Objects);
-
-=head1 NAME
-
-Koha::Auth::Providers - Koha Auth Provider Object class
-
-=head1 API
-
-=head2 Internal methods
-
-=cut
-
-=head3 _type
-
-=cut
-
-sub _type {
- return 'AuthProvider';
-}
-
-=head3 object_class
-
-=cut
-
-sub object_class {
- return 'Koha::Auth::Provider';
-}
-
-1;
+++ /dev/null
-package Koha::REST::Plugin::Auth;
-
-# 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 Mojo::Base 'Mojolicious::Plugin';
-
-use Koha::Exceptions;
-use Koha::Exceptions::Auth;
-use Koha::Patron;
-
-use C4::Auth;
-
-use CGI;
-
-=head1 NAME
-
-Koha::REST::Plugin::Auth
-
-=head1 API
-
-=head2 Helper methods
-
-=cut
-
-sub register {
- my ( $self, $app ) = @_;
-
-=head3 auth.register
-
- my $patron = $c->auth->register(
- { data => $patron_data,
- domain => $domain,
- interface => $interface
- }
- );
-
-If no patron passed, creates a new I<Koha::Patron> if the provider is configured
-to do so for the domain.
-
-=cut
-
- $app->helper(
- 'auth.register' => sub {
- my ( $c, $params ) = @_;
- my $data = $params->{data};
- my $domain = $params->{domain};
- my $interface = $params->{interface};
-
- unless ( $interface eq 'opac' && $domain->auto_register ) {
- Koha::Exceptions::Auth::Unauthorized->throw( code => 401 );
- }
-
- return Koha::Patron->new($data)->store;
- }
- );
-
-=head3 auth.session
-
- my ( $status, $cookie, $session_id ) = $c->auth->session( $patron );
-
-Generates a new session.
-
-=cut
-
- $app->helper(
- 'auth.session' => sub {
- my ( $c, $patron ) = @_;
- my $userid = $patron->userid;
- my $cardnumber = $patron->cardnumber;
- my $cgi = CGI->new;
-
- $cgi->param( userid => $userid );
- $cgi->param( cardnumber => $cardnumber );
- $cgi->param( auth_client_login => 1 );
-
- my ( $status, $cookie, $session_id ) = C4::Auth::check_api_auth($cgi);
-
- Koha::Exceptions::UnderMaintenance->throw( code => 503 )
- if $status eq "maintenance";
-
- Koha::Exceptions::Auth::CannotCreateSession->throw( code => 500 )
- unless $status eq "ok";
-
- return ( $status, $cookie, $session_id );
- }
- );
-}
-
-1;
--- /dev/null
+package Koha::REST::Plugin::Auth::IdP;
+
+# 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 Mojo::Base 'Mojolicious::Plugin';
+
+use Koha::Exceptions;
+use Koha::Exceptions::Auth;
+use Koha::Patron;
+
+use C4::Auth;
+
+use CGI;
+
+=head1 NAME
+
+Koha::REST::Plugin::Auth::IdP
+
+=head1 API
+
+=head2 Helper methods
+
+=cut
+
+sub register {
+ my ( $self, $app ) = @_;
+
+=head3 auth.register
+
+ my $patron = $c->auth->register(
+ { data => $patron_data,
+ domain => $domain,
+ interface => $interface
+ }
+ );
+
+If no patron passed, creates a new I<Koha::Patron> if the provider is configured
+to do so for the domain.
+
+=cut
+
+ $app->helper(
+ 'auth.register' => sub {
+ my ( $c, $params ) = @_;
+ my $data = $params->{data};
+ my $domain = $params->{domain};
+ my $interface = $params->{interface};
+
+ unless ( $interface eq 'opac' && $domain->auto_register ) {
+ Koha::Exceptions::Auth::Unauthorized->throw( code => 401 );
+ }
+
+ return Koha::Patron->new($data)->store;
+ }
+ );
+
+=head3 auth.session
+
+ my ( $status, $cookie, $session_id ) = $c->auth->session( $patron );
+
+Generates a new session.
+
+=cut
+
+ $app->helper(
+ 'auth.session' => sub {
+ my ( $c, $patron ) = @_;
+ my $userid = $patron->userid;
+ my $cardnumber = $patron->cardnumber;
+ my $cgi = CGI->new;
+
+ $cgi->param( userid => $userid );
+ $cgi->param( cardnumber => $cardnumber );
+ $cgi->param( auth_client_login => 1 );
+
+ my ( $status, $cookie, $session_id ) = C4::Auth::check_api_auth($cgi);
+
+ Koha::Exceptions::UnderMaintenance->throw( code => 503 )
+ if $status eq "maintenance";
+
+ Koha::Exceptions::Auth::CannotCreateSession->throw( code => 500 )
+ unless $status eq "ok";
+
+ return ( $status, $cookie, $session_id );
+ }
+ );
+}
+
+1;
use C4::Context;
use Koha::Logger;
-use Koha::Auth::Providers;
+use Koha::Auth::Identity::Providers;
use Mojolicious::Plugin::OAuth2;
use JSON::Validator::Schema::OpenAPIv2;
my $oauth_configuration = {};
my $search_options = { protocol => [ "OIDC", "OAuth" ] };
- my $providers = Koha::Auth::Providers->search( $search_options );
+ my $providers = Koha::Auth::Identity::Providers->search( $search_options );
while(my $provider = $providers->next) {
$oauth_configuration->{$provider->code} = decode_json($provider->config);
$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( 'Koha::REST::Plugin::Auth::IdP' );
$self->plugin( 'Mojolicious::Plugin::OAuth2' => $oauth_configuration );
}
--- /dev/null
+package Koha::REST::V1::Auth::Identity::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::Identity::Provider::Domains;
+use Koha::Auth::Identity::Providers;
+
+use Koha::Database;
+
+use Scalar::Util qw(blessed);
+use Try::Tiny;
+
+=head1 NAME
+
+Koha::REST::V1::Auth::Identity::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 $identity_provider_id = $c->validation->param('identity_provider_id');
+ my $provider = Koha::Auth::Identity::Providers->find($identity_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 $identity_provider_id = $c->validation->param('identity_provider_id');
+ my $provider = Koha::Auth::Identity::Providers->find($identity_provider_id);
+
+ unless ($provider) {
+ return $c->render(
+ status => 404,
+ openapi => {
+ error => 'Object not found',
+ error_code => 'not_found',
+ }
+ );
+ }
+
+ my $domains_rs = $provider->domains;
+
+ my $identity_provider_domain_id = $c->validation->param('identity_provider_domain_id');
+ my $domain = $c->objects->find( $domains_rs, $identity_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 {
+ my $params = $c->validation->param('body');
+ $params->{identity_provider_id} = $c->validation->param('identity_provider_id');
+ Koha::Database->new->schema->txn_do(
+ sub {
+ my $domain = Koha::Auth::Identity::Provider::Domain->new_from_api( $params );
+ $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 $identity_provider_id = $c->validation->param('identity_provider_id');
+ my $identity_provider_domain_id = $c->validation->param('identity_provider_domain_id');
+
+ my $domain = Koha::Auth::Identity::Provider::Domains->find(
+ { identity_provider_id => $identity_provider_id, identity_provider_domain_id => $identity_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 $identity_provider_id = $c->validation->param('identity_provider_id');
+ my $identity_provider_domain_id = $c->validation->param('identity_provider_domain_id');
+
+ my $domain = Koha::Auth::Identity::Provider::Domains->find(
+ { identity_provider_id => $identity_provider_id, identity_provider_domain_id => $identity_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;
--- /dev/null
+package Koha::REST::V1::Auth::Identity::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::Identity::Provider::OAuth;
+use Koha::Auth::Identity::Provider::OIDC;
+use Koha::Auth::Identity::Providers;
+
+use Koha::Database;
+
+use Scalar::Util qw(blessed);
+use Try::Tiny;
+
+=head1 NAME
+
+Koha::REST::V1::Auth::Identity::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::Identity::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 $identity_provider_id = $c->validation->param('identity_provider_id');
+ my $provider = $c->objects->find( Koha::Auth::Identity::Providers->new, $identity_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::Identity::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->identity_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 $identity_provider_id = $c->validation->param('identity_provider_id');
+ my $provider = Koha::Auth::Identity::Providers->find( $identity_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::Identity::Providers->find( $c->validation->param('identity_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;
+++ /dev/null
-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;
+++ /dev/null
-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;
+++ /dev/null
-use utf8;
-package Koha::Schema::Result::AuthProvider;
-
-# Created by DBIx::Class::Schema::Loader
-# DO NOT MODIFY THE FIRST PART OF THIS FILE
-
-=head1 NAME
-
-Koha::Schema::Result::AuthProvider
-
-=cut
-
-use strict;
-use warnings;
-
-use base 'DBIx::Class::Core';
-
-=head1 TABLE: C<auth_providers>
-
-=cut
-
-__PACKAGE__->table("auth_providers");
-
-=head1 ACCESSORS
-
-=head2 auth_provider_id
-
- data_type: 'integer'
- is_auto_increment: 1
- is_nullable: 0
-
-unique key, used to identify the provider
-
-=head2 code
-
- data_type: 'varchar'
- is_nullable: 0
- size: 20
-
-Provider code
-
-=head2 description
-
- data_type: 'varchar'
- is_nullable: 0
- size: 255
-
-Description for the provider
-
-=head2 protocol
-
- data_type: 'enum'
- extra: {list => ["OAuth","OIDC","LDAP","CAS"]}
- is_nullable: 0
-
-Protocol provider speaks
-
-=head2 config
-
- data_type: 'longtext'
- default_value: ''{}''
- is_nullable: 0
-
-Configuration of the provider in JSON format
-
-=head2 mapping
-
- data_type: 'longtext'
- default_value: ''{}''
- is_nullable: 0
-
-Configuration to map provider data to Koha user
-
-=head2 matchpoint
-
- data_type: 'enum'
- extra: {list => ["email","userid","cardnumber"]}
- is_nullable: 0
-
-The patron attribute to be used as matchpoint
-
-=head2 icon_url
-
- data_type: 'varchar'
- is_nullable: 1
- size: 255
-
-Provider icon URL
-
-=cut
-
-__PACKAGE__->add_columns(
- "auth_provider_id",
- { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
- "code",
- { data_type => "varchar", is_nullable => 0, size => 20 },
- "description",
- { data_type => "varchar", is_nullable => 0, size => 255 },
- "protocol",
- {
- data_type => "enum",
- extra => { list => ["OAuth", "OIDC", "LDAP", "CAS"] },
- is_nullable => 0,
- },
- "config",
- { data_type => "longtext", default_value => "'{}'", is_nullable => 0 },
- "mapping",
- { data_type => "longtext", default_value => "'{}'", is_nullable => 0 },
- "matchpoint",
- {
- data_type => "enum",
- extra => { list => ["email", "userid", "cardnumber"] },
- is_nullable => 0,
- },
- "icon_url",
- { data_type => "varchar", is_nullable => 1, size => 255 },
-);
-
-=head1 PRIMARY KEY
-
-=over 4
-
-=item * L</auth_provider_id>
-
-=back
-
-=cut
-
-__PACKAGE__->set_primary_key("auth_provider_id");
-
-=head1 UNIQUE CONSTRAINTS
-
-=head2 C<code>
-
-=over 4
-
-=item * L</code>
-
-=back
-
-=cut
-
-__PACKAGE__->add_unique_constraint("code", ["code"]);
-
-=head1 RELATIONS
-
-=head2 auth_provider_domains
-
-Type: has_many
-
-Related object: L<Koha::Schema::Result::AuthProviderDomain>
-
-=cut
-
-__PACKAGE__->has_many(
- "auth_provider_domains",
- "Koha::Schema::Result::AuthProviderDomain",
- { "foreign.auth_provider_id" => "self.auth_provider_id" },
- { cascade_copy => 0, cascade_delete => 0 },
-);
-
-
-# Created by DBIx::Class::Schema::Loader v0.07049 @ 2022-09-30 19:43:00
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ZqUo3by0ZXca5RI3QFNypw
-
-
-=head2 domains
-
-Type: has_many
-
-Related object: L<Koha::Schema::Result::AuthProviderDomain>
-
-=cut
-
-__PACKAGE__->has_many(
- "domains",
- "Koha::Schema::Result::AuthProviderDomain",
- { "foreign.auth_provider_id" => "self.auth_provider_id" },
- { cascade_copy => 0, cascade_delete => 0 },
-);
-
-sub koha_object_class {
- 'Koha::Auth::Provider';
-}
-sub koha_objects_class {
- 'Koha::Auth::Providers';
-}
-
-1;
+++ /dev/null
-use utf8;
-package Koha::Schema::Result::AuthProviderDomain;
-
-# Created by DBIx::Class::Schema::Loader
-# DO NOT MODIFY THE FIRST PART OF THIS FILE
-
-=head1 NAME
-
-Koha::Schema::Result::AuthProviderDomain
-
-=cut
-
-use strict;
-use warnings;
-
-use base 'DBIx::Class::Core';
-
-=head1 TABLE: C<auth_provider_domains>
-
-=cut
-
-__PACKAGE__->table("auth_provider_domains");
-
-=head1 ACCESSORS
-
-=head2 auth_provider_domain_id
-
- data_type: 'integer'
- is_auto_increment: 1
- is_nullable: 0
-
-unique key, used to identify providers domain
-
-=head2 auth_provider_id
-
- data_type: 'integer'
- is_foreign_key: 1
- is_nullable: 0
-
-Reference to provider
-
-=head2 domain
-
- data_type: 'varchar'
- is_nullable: 1
- size: 100
-
-Domain name. If null means all domains
-
-=head2 auto_register
-
- data_type: 'tinyint'
- default_value: 0
- is_nullable: 0
-
-Allow user auto register
-
-=head2 update_on_auth
-
- data_type: 'tinyint'
- default_value: 0
- is_nullable: 0
-
-Update user data on auth login
-
-=head2 default_library_id
-
- data_type: 'varchar'
- is_foreign_key: 1
- is_nullable: 1
- size: 10
-
-Default library to create user if auto register is enabled
-
-=head2 default_category_id
-
- data_type: 'varchar'
- is_foreign_key: 1
- is_nullable: 1
- size: 10
-
-Default category to create user if auto register is enabled
-
-=head2 allow_opac
-
- data_type: 'tinyint'
- default_value: 1
- is_nullable: 0
-
-Allow provider from opac interface
-
-=head2 allow_staff
-
- data_type: 'tinyint'
- default_value: 1
- is_nullable: 0
-
-Allow provider from staff interface
-
-=cut
-
-__PACKAGE__->add_columns(
- "auth_provider_domain_id",
- { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
- "auth_provider_id",
- { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
- "domain",
- { data_type => "varchar", is_nullable => 1, size => 100 },
- "auto_register",
- { data_type => "tinyint", default_value => 0, is_nullable => 0 },
- "update_on_auth",
- { data_type => "tinyint", default_value => 0, is_nullable => 0 },
- "default_library_id",
- { data_type => "varchar", is_foreign_key => 1, is_nullable => 1, size => 10 },
- "default_category_id",
- { data_type => "varchar", is_foreign_key => 1, is_nullable => 1, size => 10 },
- "allow_opac",
- { data_type => "tinyint", default_value => 1, is_nullable => 0 },
- "allow_staff",
- { data_type => "tinyint", default_value => 1, is_nullable => 0 },
-);
-
-=head1 PRIMARY KEY
-
-=over 4
-
-=item * L</auth_provider_domain_id>
-
-=back
-
-=cut
-
-__PACKAGE__->set_primary_key("auth_provider_domain_id");
-
-=head1 UNIQUE CONSTRAINTS
-
-=head2 C<auth_provider_id>
-
-=over 4
-
-=item * L</auth_provider_id>
-
-=item * L</domain>
-
-=back
-
-=cut
-
-__PACKAGE__->add_unique_constraint("auth_provider_id", ["auth_provider_id", "domain"]);
-
-=head1 RELATIONS
-
-=head2 auth_provider
-
-Type: belongs_to
-
-Related object: L<Koha::Schema::Result::AuthProvider>
-
-=cut
-
-__PACKAGE__->belongs_to(
- "auth_provider",
- "Koha::Schema::Result::AuthProvider",
- { auth_provider_id => "auth_provider_id" },
- { is_deferrable => 1, on_delete => "CASCADE", on_update => "RESTRICT" },
-);
-
-=head2 default_category
-
-Type: belongs_to
-
-Related object: L<Koha::Schema::Result::Category>
-
-=cut
-
-__PACKAGE__->belongs_to(
- "default_category",
- "Koha::Schema::Result::Category",
- { categorycode => "default_category_id" },
- {
- is_deferrable => 1,
- join_type => "LEFT",
- on_delete => "CASCADE",
- on_update => "RESTRICT",
- },
-);
-
-=head2 default_library
-
-Type: belongs_to
-
-Related object: L<Koha::Schema::Result::Branch>
-
-=cut
-
-__PACKAGE__->belongs_to(
- "default_library",
- "Koha::Schema::Result::Branch",
- { branchcode => "default_library_id" },
- {
- is_deferrable => 1,
- join_type => "LEFT",
- on_delete => "CASCADE",
- on_update => "RESTRICT",
- },
-);
-
-
-# Created by DBIx::Class::Schema::Loader v0.07049 @ 2022-08-24 15:03:07
-# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:1b0q+e8Ym8icJ6bYAY/Mbw
-
-sub koha_object_class {
- 'Koha::Auth::Provider::Domain';
-}
-sub koha_objects_class {
- 'Koha::Auth::Providers::Domains';
-}
-
-__PACKAGE__->add_columns(
- '+auto_register' => { is_boolean => 1 },
- '+update_on_auth' => { is_boolean => 1 },
- '+allow_opac' => { is_boolean => 1 },
- '+allow_staff' => { is_boolean => 1 },
-);
-
-1;
--- /dev/null
+use utf8;
+package Koha::Schema::Result::IdentityProvider;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Koha::Schema::Result::IdentityProvider
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 TABLE: C<identity_providers>
+
+=cut
+
+__PACKAGE__->table("identity_providers");
+
+=head1 ACCESSORS
+
+=head2 identity_provider_id
+
+ data_type: 'integer'
+ is_auto_increment: 1
+ is_nullable: 0
+
+unique key, used to identify the provider
+
+=head2 code
+
+ data_type: 'varchar'
+ is_nullable: 0
+ size: 20
+
+Provider code
+
+=head2 description
+
+ data_type: 'varchar'
+ is_nullable: 0
+ size: 255
+
+Description for the provider
+
+=head2 protocol
+
+ data_type: 'enum'
+ extra: {list => ["OAuth","OIDC","LDAP","CAS"]}
+ is_nullable: 0
+
+Protocol provider speaks
+
+=head2 config
+
+ data_type: 'longtext'
+ default_value: ''{}''
+ is_nullable: 0
+
+Configuration of the provider in JSON format
+
+=head2 mapping
+
+ data_type: 'longtext'
+ default_value: ''{}''
+ is_nullable: 0
+
+Configuration to map provider data to Koha user
+
+=head2 matchpoint
+
+ data_type: 'enum'
+ extra: {list => ["email","userid","cardnumber"]}
+ is_nullable: 0
+
+The patron attribute to be used as matchpoint
+
+=head2 icon_url
+
+ data_type: 'varchar'
+ is_nullable: 1
+ size: 255
+
+Provider icon URL
+
+=cut
+
+__PACKAGE__->add_columns(
+ "identity_provider_id",
+ { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
+ "code",
+ { data_type => "varchar", is_nullable => 0, size => 20 },
+ "description",
+ { data_type => "varchar", is_nullable => 0, size => 255 },
+ "protocol",
+ {
+ data_type => "enum",
+ extra => { list => ["OAuth", "OIDC", "LDAP", "CAS"] },
+ is_nullable => 0,
+ },
+ "config",
+ { data_type => "longtext", default_value => "'{}'", is_nullable => 0 },
+ "mapping",
+ { data_type => "longtext", default_value => "'{}'", is_nullable => 0 },
+ "matchpoint",
+ {
+ data_type => "enum",
+ extra => { list => ["email", "userid", "cardnumber"] },
+ is_nullable => 0,
+ },
+ "icon_url",
+ { data_type => "varchar", is_nullable => 1, size => 255 },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</identity_provider_id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("identity_provider_id");
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<code>
+
+=over 4
+
+=item * L</code>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("code", ["code"]);
+
+=head1 RELATIONS
+
+=head2 identity_provider_domains
+
+Type: has_many
+
+Related object: L<Koha::Schema::Result::IdentityProviderDomain>
+
+=cut
+
+__PACKAGE__->has_many(
+ "identity_provider_domains",
+ "Koha::Schema::Result::IdentityProviderDomain",
+ { "foreign.identity_provider_id" => "self.identity_provider_id" },
+ { cascade_copy => 0, cascade_delete => 0 },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07049 @ 2022-10-20 15:27:55
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:jmqAwH7/6QvawJ73/0rkQg
+
+__PACKAGE__->has_many(
+ "domains",
+ "Koha::Schema::Result::IdentityProviderDomain",
+ { "foreign.identity_provider_id" => "self.identity_provider_id" },
+ { cascade_copy => 0, cascade_delete => 0 },
+);
+
+sub koha_object_class {
+ 'Koha::Auth::Identity::Provider';
+}
+sub koha_objects_class {
+ 'Koha::Auth::Identity::Providers';
+}
+
+1;
--- /dev/null
+use utf8;
+package Koha::Schema::Result::IdentityProviderDomain;
+
+# Created by DBIx::Class::Schema::Loader
+# DO NOT MODIFY THE FIRST PART OF THIS FILE
+
+=head1 NAME
+
+Koha::Schema::Result::IdentityProviderDomain
+
+=cut
+
+use strict;
+use warnings;
+
+use base 'DBIx::Class::Core';
+
+=head1 TABLE: C<identity_provider_domains>
+
+=cut
+
+__PACKAGE__->table("identity_provider_domains");
+
+=head1 ACCESSORS
+
+=head2 identity_provider_domain_id
+
+ data_type: 'integer'
+ is_auto_increment: 1
+ is_nullable: 0
+
+unique key, used to identify providers domain
+
+=head2 identity_provider_id
+
+ data_type: 'integer'
+ is_foreign_key: 1
+ is_nullable: 0
+
+Reference to provider
+
+=head2 domain
+
+ data_type: 'varchar'
+ is_nullable: 1
+ size: 100
+
+Domain name. If null means all domains
+
+=head2 auto_register
+
+ data_type: 'tinyint'
+ default_value: 0
+ is_nullable: 0
+
+Allow user auto register
+
+=head2 update_on_auth
+
+ data_type: 'tinyint'
+ default_value: 0
+ is_nullable: 0
+
+Update user data on auth login
+
+=head2 default_library_id
+
+ data_type: 'varchar'
+ is_foreign_key: 1
+ is_nullable: 1
+ size: 10
+
+Default library to create user if auto register is enabled
+
+=head2 default_category_id
+
+ data_type: 'varchar'
+ is_foreign_key: 1
+ is_nullable: 1
+ size: 10
+
+Default category to create user if auto register is enabled
+
+=head2 allow_opac
+
+ data_type: 'tinyint'
+ default_value: 1
+ is_nullable: 0
+
+Allow provider from opac interface
+
+=head2 allow_staff
+
+ data_type: 'tinyint'
+ default_value: 0
+ is_nullable: 0
+
+Allow provider from staff interface
+
+=cut
+
+__PACKAGE__->add_columns(
+ "identity_provider_domain_id",
+ { data_type => "integer", is_auto_increment => 1, is_nullable => 0 },
+ "identity_provider_id",
+ { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
+ "domain",
+ { data_type => "varchar", is_nullable => 1, size => 100 },
+ "auto_register",
+ { data_type => "tinyint", default_value => 0, is_nullable => 0 },
+ "update_on_auth",
+ { data_type => "tinyint", default_value => 0, is_nullable => 0 },
+ "default_library_id",
+ { data_type => "varchar", is_foreign_key => 1, is_nullable => 1, size => 10 },
+ "default_category_id",
+ { data_type => "varchar", is_foreign_key => 1, is_nullable => 1, size => 10 },
+ "allow_opac",
+ { data_type => "tinyint", default_value => 1, is_nullable => 0 },
+ "allow_staff",
+ { data_type => "tinyint", default_value => 0, is_nullable => 0 },
+);
+
+=head1 PRIMARY KEY
+
+=over 4
+
+=item * L</identity_provider_domain_id>
+
+=back
+
+=cut
+
+__PACKAGE__->set_primary_key("identity_provider_domain_id");
+
+=head1 UNIQUE CONSTRAINTS
+
+=head2 C<identity_provider_id>
+
+=over 4
+
+=item * L</identity_provider_id>
+
+=item * L</domain>
+
+=back
+
+=cut
+
+__PACKAGE__->add_unique_constraint("identity_provider_id", ["identity_provider_id", "domain"]);
+
+=head1 RELATIONS
+
+=head2 default_category
+
+Type: belongs_to
+
+Related object: L<Koha::Schema::Result::Category>
+
+=cut
+
+__PACKAGE__->belongs_to(
+ "default_category",
+ "Koha::Schema::Result::Category",
+ { categorycode => "default_category_id" },
+ {
+ is_deferrable => 1,
+ join_type => "LEFT",
+ on_delete => "CASCADE",
+ on_update => "RESTRICT",
+ },
+);
+
+=head2 default_library
+
+Type: belongs_to
+
+Related object: L<Koha::Schema::Result::Branch>
+
+=cut
+
+__PACKAGE__->belongs_to(
+ "default_library",
+ "Koha::Schema::Result::Branch",
+ { branchcode => "default_library_id" },
+ {
+ is_deferrable => 1,
+ join_type => "LEFT",
+ on_delete => "CASCADE",
+ on_update => "RESTRICT",
+ },
+);
+
+=head2 identity_provider
+
+Type: belongs_to
+
+Related object: L<Koha::Schema::Result::IdentityProvider>
+
+=cut
+
+__PACKAGE__->belongs_to(
+ "identity_provider",
+ "Koha::Schema::Result::IdentityProvider",
+ { identity_provider_id => "identity_provider_id" },
+ { is_deferrable => 1, on_delete => "CASCADE", on_update => "RESTRICT" },
+);
+
+
+# Created by DBIx::Class::Schema::Loader v0.07049 @ 2022-11-08 17:35:26
+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:uUnzFzRKWAiYUsmapofXwQ
+
+__PACKAGE__->add_columns(
+ '+auto_register' => { is_boolean => 1 },
+ '+update_on_auth' => { is_boolean => 1 },
+ '+allow_opac' => { is_boolean => 1 },
+ '+allow_staff' => { is_boolean => 1 }
+);
+
+sub koha_object_class {
+ 'Koha::Auth::Identity::Provider::Domain';
+}
+sub koha_objects_class {
+ 'Koha::Auth::Identity::Provider::Domains';
+}
+
+1;
use Template::Plugin;
use base qw( Template::Plugin );
-use Koha::Auth::Providers;
+use Koha::Auth::Identity::Providers;
=head1 NAME
$interface = 'staff'
if $interface eq 'intranet';
- my $providers = Koha::Auth::Providers->search( { "domains.allow_$interface" => 1 }, { prefetch => 'domains' } );
+ my $providers = Koha::Auth::Identity::Providers->search( { "domains.allow_$interface" => 1 }, { prefetch => 'domains' } );
my $base_url = ( $interface ne 'staff' ) ? "/api/v1/public/oauth/login" : "/api/v1/public/oauth/login";
my @urls;
+++ /dev/null
-#!/usr/bin/perl
-
-# Copyright 2022 Theke Solutions
-#
-# 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 CGI qw ( -utf8 );
-use Scalar::Util qw( blessed );
-use Try::Tiny qw( catch try );
-
-use C4::Auth qw( get_template_and_user );
-use C4::Output qw( output_html_with_http_headers );
-
-use Koha::Auth::Providers;
-
-my $input = CGI->new;
-my $op = $input->param('op') || 'list';
-my $domain_ops = $input->param('domain_ops');
-my $auth_provider_id = $input->param('auth_provider_id');
-my $auth_provider;
-
-$auth_provider = Koha::Auth::Providers->find($auth_provider_id)
- unless !$auth_provider_id;
-
-my $template_name = $domain_ops ? 'admin/authentication_provider_domains.tt' : 'admin/authentication_providers.tt';
-
-my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
- { template_name => $template_name,
- query => $input,
- type => "intranet",
- flagsrequired => { parameters => 'manage_authentication_providers' },
- }
-);
-
-my @messages;
-
-if ( !$domain_ops && $op eq 'add' ) {
-
- my $code = $input->param('code');
- my $config = $input->param('config');
- my $description = $input->param('description');
- my $icon_url = $input->param('icon_url');
- my $mapping = $input->param('mapping');
- my $matchpoint = $input->param('matchpoint'),
- my $protocol = $input->param('protocol');
-
- try {
- my $provider = Koha::Auth::Provider->new(
- { code => $code,
- config => $config,
- description => $description,
- icon_url => $icon_url,
- mapping => $mapping,
- matchpoint => $matchpoint,
- protocol => $protocol,
- }
- )->store;
-
- Koha::Auth::Provider::Domain->new(
- {
- auth_provider_id => $provider->auth_provider_id,
- }
- )->store;
-
- push @messages, { type => 'message', code => 'success_on_insert' };
- }
- catch {
- if ( blessed $_ and $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
- push @messages,
- {
- type => 'alert',
- code => 'error_on_insert',
- reason => 'duplicate_id'
- };
- }
- };
-
- # list servers after adding
- $op = 'list';
-}
-elsif ( $domain_ops && $op eq 'add' ) {
-
- my $allow_opac = $input->param('allow_opac');
- my $allow_staff = $input->param('allow_staff');
- my $auth_provider_id = $input->param('auth_provider_id');
- my $auto_register = $input->param('auto_register');
- my $default_category_id = $input->param('default_category_id');
- my $default_library_id = $input->param('default_library_id');
- my $domain = $input->param('domain');
- my $update_on_auth = $input->param('update_on_auth');
-
- try {
-
- Koha::Auth::Provider::Domain->new(
- {
- allow_opac => $allow_opac,
- allow_staff => $allow_staff,
- auth_provider_id => $auth_provider_id,
- auto_register => $auto_register,
- default_category_id => $default_category_id,
- default_library_id => $default_library_id,
- domain => $domain,
- update_on_auth => $update_on_auth,
- }
- )->store;
-
- push @messages, { type => 'message', code => 'success_on_insert' };
- }
- catch {
- if ( blessed $_ and $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
- push @messages,
- {
- type => 'alert',
- code => 'error_on_insert',
- reason => 'duplicate_id'
- };
- }
- };
-
- # list servers after adding
- $op = 'list';
-}
-elsif ( !$domain_ops && $op eq 'edit_form' ) {
-
- if ( $auth_provider ) {
- $template->param(
- auth_provider => $auth_provider
- );
- }
- else {
- push @messages,
- {
- type => 'alert',
- code => 'error_on_edit',
- reason => 'invalid_id'
- };
- }
-}
-elsif ( $domain_ops && $op eq 'edit_form' ) {
- my $auth_provider_domain_id = $input->param('auth_provider_domain_id');
- my $auth_provider_domain;
-
- $auth_provider_domain = Koha::Auth::Provider::Domains->find($auth_provider_domain_id)
- unless !$auth_provider_domain_id;
-
- if ( $auth_provider_domain ) {
- $template->param(
- auth_provider_domain => $auth_provider_domain
- );
- }
- else {
- push @messages,
- {
- type => 'alert',
- code => 'error_on_edit',
- reason => 'invalid_id'
- };
- }
-}
-elsif ( !$domain_ops && $op eq 'edit_save' ) {
-
- if ( $auth_provider ) {
-
- my $code = $input->param('code');
- my $config = $input->param('config');
- my $description = $input->param('description');
- my $icon_url = $input->param('icon_url');
- my $mapping = $input->param('mapping');
- my $matchpoint = $input->param('matchpoint');
- my $protocol = $input->param('protocol');
-
- try {
-
- $auth_provider->set(
- { code => $code,
- config => $config,
- description => $description,
- icon_url => $icon_url,
- mapping => $mapping,
- matchpoint => $matchpoint,
- protocol => $protocol,
- }
- )->store;
-
- push @messages,
- {
- type => 'message',
- code => 'success_on_update'
- };
- }
- catch {
- push @messages,
- {
- type => 'alert',
- code => 'error_on_update'
- };
- };
-
- # list servers after adding
- $op = 'list';
- }
- else {
- push @messages,
- {
- type => 'alert',
- code => 'error_on_update',
- reason => 'invalid_id'
- };
- }
-}
-elsif ( $domain_ops && $op eq 'edit_save' ) {
-
- my $auth_provider_domain_id = $input->param('auth_provider_domain_id');
- my $auth_provider_domain;
-
- $auth_provider_domain = Koha::Auth::Provider::Domains->find($auth_provider_domain_id)
- unless !$auth_provider_domain_id;
-
- if ( $auth_provider_domain ) {
-
- my $auth_provider_id = $input->param('auth_provider_id');
- my $domain = $input->param('domain');
- my $auto_register = $input->param('auto_register');
- my $update_on_auth = $input->param('update_on_auth');
- my $default_library_id = $input->param('default_library_id');
- my $default_category_id = $input->param('default_category_id');
- my $allow_opac = $input->param('allow_opac');
- my $allow_staff = $input->param('allow_staff');
-
- try {
-
- $auth_provider_domain->set(
- {
- auth_provider_id => $auth_provider_id,
- domain => $domain,
- auto_register => $auto_register,
- update_on_auth => $update_on_auth,
- default_library_id => $default_library_id,
- default_category_id => $default_category_id,
- allow_opac => $allow_opac,
- allow_staff => $allow_staff,
- }
- )->store;
-
- push @messages,
- {
- type => 'message',
- code => 'success_on_update'
- };
- }
- catch {
- push @messages,
- {
- type => 'alert',
- code => 'error_on_update'
- };
- };
-
- # list servers after adding
- $op = 'list';
- }
- else {
- push @messages,
- {
- type => 'alert',
- code => 'error_on_update',
- reason => 'invalid_id'
- };
- }
-}
-
-if ( $domain_ops ) {
- $template->param(
- auth_provider_code => $auth_provider->code,
- auth_provider_id => $auth_provider_id,
- );
-}
-
-$template->param(
- op => $op,
- messages => \@messages,
-);
-
-output_html_with_http_headers $input, $cookie, $template->output;
--- /dev/null
+#!/usr/bin/perl
+
+# Copyright 2022 Theke Solutions
+#
+# 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 CGI qw ( -utf8 );
+use Scalar::Util qw( blessed );
+use Try::Tiny qw( catch try );
+
+use C4::Auth qw( get_template_and_user );
+use C4::Output qw( output_html_with_http_headers );
+
+use Koha::Auth::Identity::Providers;
+
+my $input = CGI->new;
+my $op = $input->param('op') || 'list';
+my $domain_ops = $input->param('domain_ops');
+my $identity_provider_id = $input->param('identity_provider_id');
+my $identity_provider;
+
+$identity_provider = Koha::Auth::Identity::Providers->find($identity_provider_id)
+ unless !$identity_provider_id;
+
+my $template_name = $domain_ops ? 'admin/identity_provider_domains.tt' : 'admin/identity_providers.tt';
+
+my ( $template, $borrowernumber, $cookie ) = get_template_and_user(
+ { template_name => $template_name,
+ query => $input,
+ type => "intranet",
+ flagsrequired => { parameters => 'manage_identity_providers' },
+ }
+);
+
+my @messages;
+
+if ( !$domain_ops && $op eq 'add' ) {
+
+ my $code = $input->param('code');
+ my $config = $input->param('config');
+ my $description = $input->param('description');
+ my $icon_url = $input->param('icon_url');
+ my $mapping = $input->param('mapping');
+ my $matchpoint = $input->param('matchpoint'),
+ my $protocol = $input->param('protocol');
+
+ try {
+ my $provider = Koha::Auth::Identity::Provider->new(
+ { code => $code,
+ config => $config,
+ description => $description,
+ icon_url => $icon_url,
+ mapping => $mapping,
+ matchpoint => $matchpoint,
+ protocol => $protocol,
+ }
+ )->store;
+
+ Koha::Auth::Identity::Provider::Domain->new(
+ {
+ identity_provider_id => $provider->identity_provider_id,
+ }
+ )->store;
+
+ push @messages, { type => 'message', code => 'success_on_insert' };
+ }
+ catch {
+ if ( blessed $_ and $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
+ push @messages,
+ {
+ type => 'alert',
+ code => 'error_on_insert',
+ reason => 'duplicate_id'
+ };
+ }
+ };
+
+ # list servers after adding
+ $op = 'list';
+}
+elsif ( $domain_ops && $op eq 'add' ) {
+
+ my $allow_opac = $input->param('allow_opac');
+ my $allow_staff = $input->param('allow_staff');
+ my $identity_provider_id = $input->param('identity_provider_id');
+ my $auto_register = $input->param('auto_register');
+ my $default_category_id = $input->param('default_category_id');
+ my $default_library_id = $input->param('default_library_id');
+ my $domain = $input->param('domain');
+ my $update_on_auth = $input->param('update_on_auth');
+
+ try {
+
+ Koha::Auth::Identity::Provider::Domain->new(
+ {
+ allow_opac => $allow_opac,
+ allow_staff => $allow_staff,
+ identity_provider_id => $identity_provider_id,
+ auto_register => $auto_register,
+ default_category_id => $default_category_id,
+ default_library_id => $default_library_id,
+ domain => $domain,
+ update_on_auth => $update_on_auth,
+ }
+ )->store;
+
+ push @messages, { type => 'message', code => 'success_on_insert' };
+ }
+ catch {
+ if ( blessed $_ and $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
+ push @messages,
+ {
+ type => 'alert',
+ code => 'error_on_insert',
+ reason => 'duplicate_id'
+ };
+ }
+ };
+
+ # list servers after adding
+ $op = 'list';
+}
+elsif ( !$domain_ops && $op eq 'edit_form' ) {
+
+ if ( $identity_provider ) {
+ $template->param(
+ identity_provider => $identity_provider
+ );
+ }
+ else {
+ push @messages,
+ {
+ type => 'alert',
+ code => 'error_on_edit',
+ reason => 'invalid_id'
+ };
+ }
+}
+elsif ( $domain_ops && $op eq 'edit_form' ) {
+ my $identity_provider_domain_id = $input->param('identity_provider_domain_id');
+ my $identity_provider_domain;
+
+ $identity_provider_domain = Koha::Auth::Identity::Provider::Domains->find($identity_provider_domain_id)
+ unless !$identity_provider_domain_id;
+
+ if ( $identity_provider_domain ) {
+ $template->param(
+ identity_provider_domain => $identity_provider_domain
+ );
+ }
+ else {
+ push @messages,
+ {
+ type => 'alert',
+ code => 'error_on_edit',
+ reason => 'invalid_id'
+ };
+ }
+}
+elsif ( !$domain_ops && $op eq 'edit_save' ) {
+
+ if ( $identity_provider ) {
+
+ my $code = $input->param('code');
+ my $config = $input->param('config');
+ my $description = $input->param('description');
+ my $icon_url = $input->param('icon_url');
+ my $mapping = $input->param('mapping');
+ my $matchpoint = $input->param('matchpoint');
+ my $protocol = $input->param('protocol');
+
+ try {
+
+ $identity_provider->set(
+ { code => $code,
+ config => $config,
+ description => $description,
+ icon_url => $icon_url,
+ mapping => $mapping,
+ matchpoint => $matchpoint,
+ protocol => $protocol,
+ }
+ )->store;
+
+ push @messages,
+ {
+ type => 'message',
+ code => 'success_on_update'
+ };
+ }
+ catch {
+ push @messages,
+ {
+ type => 'alert',
+ code => 'error_on_update'
+ };
+ };
+
+ # list servers after adding
+ $op = 'list';
+ }
+ else {
+ push @messages,
+ {
+ type => 'alert',
+ code => 'error_on_update',
+ reason => 'invalid_id'
+ };
+ }
+}
+elsif ( $domain_ops && $op eq 'edit_save' ) {
+
+ my $identity_provider_domain_id = $input->param('identity_provider_domain_id');
+ my $identity_provider_domain;
+
+ $identity_provider_domain = Koha::Auth::Identity::Provider::Domains->find($identity_provider_domain_id)
+ unless !$identity_provider_domain_id;
+
+ if ( $identity_provider_domain ) {
+
+ my $identity_provider_id = $input->param('identity_provider_id');
+ my $domain = $input->param('domain');
+ my $auto_register = $input->param('auto_register');
+ my $update_on_auth = $input->param('update_on_auth');
+ my $default_library_id = $input->param('default_library_id');
+ my $default_category_id = $input->param('default_category_id');
+ my $allow_opac = $input->param('allow_opac');
+ my $allow_staff = $input->param('allow_staff');
+
+ try {
+
+ $identity_provider_domain->set(
+ {
+ identity_provider_id => $identity_provider_id,
+ domain => $domain,
+ auto_register => $auto_register,
+ update_on_auth => $update_on_auth,
+ default_library_id => $default_library_id,
+ default_category_id => $default_category_id,
+ allow_opac => $allow_opac,
+ allow_staff => $allow_staff,
+ }
+ )->store;
+
+ push @messages,
+ {
+ type => 'message',
+ code => 'success_on_update'
+ };
+ }
+ catch {
+ push @messages,
+ {
+ type => 'alert',
+ code => 'error_on_update'
+ };
+ };
+
+ # list servers after adding
+ $op = 'list';
+ }
+ else {
+ push @messages,
+ {
+ type => 'alert',
+ code => 'error_on_update',
+ reason => 'invalid_id'
+ };
+ }
+}
+
+if ( $domain_ops ) {
+ $template->param(
+ identity_provider_code => $identity_provider->code,
+ identity_provider_id => $identity_provider_id,
+ );
+}
+
+$template->param(
+ op => $op,
+ messages => \@messages,
+);
+
+output_html_with_http_headers $input, $cookie, $template->output;
+++ /dev/null
----
-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
+++ /dev/null
----
-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
--- /dev/null
+---
+type: object
+properties:
+ identity_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
+ - "null"
+ domains:
+ description: Configured domains for the authentication provider
+ type:
+ - array
+ - "null"
+additionalProperties: false
+required:
+ - config
+ - code
+ - protocol
--- /dev/null
+---
+type: object
+properties:
+ identity_provider_domain_id:
+ type: integer
+ description: Internally assigned authentication provider domain identifier
+ readOnly: true
+ identity_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:
+ - identity_provider_domain_id
+ - domain
+ - auto_register
+ - update_on_auth
+ - default_library_id
+ - default_category_id
+ - allow_opac
+ - allow_staff
$ref: ../swagger.yaml#/definitions/error
x-koha-authorization:
permissions:
- parameters: manage_authentication_providers
\ No newline at end of file
+ parameters: manage_authentication_providers
+/auth/identity_providers:
+ get:
+ x-mojo-to: Auth::Identity::Providers#list
+ operationId: listIdentityProviders
+ tags:
+ - identity_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/identity_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_identity_providers
+ post:
+ x-mojo-to: Auth::Identity::Providers#add
+ operationId: addIdentityProvider
+ tags:
+ - identity_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/identity_provider
+ produces:
+ - application/json
+ responses:
+ "201":
+ description: The generated authentication provider
+ schema:
+ $ref: ../swagger.yaml#/definitions/identity_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_identity_providers
+"/auth/identity_providers/{identity_provider_id}":
+ get:
+ x-mojo-to: Auth::Identity::Providers#get
+ operationId: getIdentityProvider
+ tags:
+ - identity_providers
+ summary: Get authentication provider
+ parameters:
+ - $ref: ../swagger.yaml#/parameters/identity_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/identity_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_identity_providers
+ put:
+ x-mojo-to: Auth::Identity::Providers#update
+ operationId: updateIdentityProvider
+ tags:
+ - identity_providers
+ summary: Update an authentication provider
+ parameters:
+ - $ref: ../swagger.yaml#/parameters/identity_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/identity_provider
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: Updated authentication provider
+ schema:
+ $ref: ../swagger.yaml#/definitions/identity_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_identity_providers
+ delete:
+ x-mojo-to: Auth::Identity::Providers#delete
+ operationId: delIdentityProvider
+ tags:
+ - identity_providers
+ summary: Delete authentication provider
+ parameters:
+ - $ref: ../swagger.yaml#/parameters/identity_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_identity_providers
+"/auth/identity_providers/{identity_provider_id}/domains":
+ get:
+ x-mojo-to: Auth::Identity::Provider::Domains#list
+ operationId: listIdentityProviderDomains
+ tags:
+ - identity_providers
+ summary: Get authentication provider configured domains
+ 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/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/identity_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_identity_providers
+ post:
+ x-mojo-to: Auth::Identity::Provider::Domains#add
+ operationId: addIdentityProviderDomain
+ tags:
+ - identity_providers
+ summary: Add an authentication provider domain
+ parameters:
+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp
+ - name: body
+ in: body
+ description: An authentication provider domain object
+ required: true
+ schema:
+ $ref: ../swagger.yaml#/definitions/identity_provider_domain
+ produces:
+ - application/json
+ responses:
+ "201":
+ description: Updated authentication provider domain
+ schema:
+ $ref: ../swagger.yaml#/definitions/identity_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_identity_providers
+"/auth/identity_providers/{identity_provider_id}/domains/{identity_provider_domain_id}":
+ get:
+ x-mojo-to: Auth::Identity::Provider::Domains#get
+ operationId: getIdentityProviderDomain
+ tags:
+ - identity_providers
+ summary: Get authentication provider domain
+ parameters:
+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp
+ - $ref: ../swagger.yaml#/parameters/identity_provider_domain_id_pp
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: An authentication provider
+ schema:
+ $ref: ../swagger.yaml#/definitions/identity_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_identity_providers
+ put:
+ x-mojo-to: Auth::Identity::Provider::Domains#update
+ operationId: updateIdentityProviderDomain
+ tags:
+ - identity_providers
+ summary: Update an authentication provider domain
+ parameters:
+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp
+ - $ref: ../swagger.yaml#/parameters/identity_provider_domain_id_pp
+ - name: body
+ in: body
+ description: An authentication provider domain object
+ required: true
+ schema:
+ $ref: ../swagger.yaml#/definitions/identity_provider_domain
+ produces:
+ - application/json
+ responses:
+ "200":
+ description: Updated authentication provider domain
+ schema:
+ $ref: ../swagger.yaml#/definitions/identity_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_identity_providers
+ delete:
+ x-mojo-to: Auth::Identity::Provider::Domains#delete
+ operationId: delIdentityProviderDomain
+ tags:
+ - identity_providers
+ summary: Delete authentication provider
+ parameters:
+ - $ref: ../swagger.yaml#/parameters/identity_provider_id_pp
+ - $ref: ../swagger.yaml#/parameters/identity_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_identity_providers
\ No newline at end of file
$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
+ identity_provider:
+ "$ref": ./definitions/identity_provider.yaml
+ identity_provider_domain:
+ "$ref": ./definitions/identity_provider_domain.yaml
basket:
$ref: ./definitions/basket.yaml
bundle_link:
$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}
+ /auth/identity_providers:
+ $ref: paths/auth.yaml#/~1auth~1identity_providers
+ "/auth/identity_providers/{identity_provider_id}":
+ $ref: paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}
+ "/auth/identity_providers/{identity_provider_id}/domains":
+ $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}
"/biblios/{biblio_id}":
$ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}"
"/biblios/{biblio_id}/checkouts":
name: agreement_period_id
required: true
type: integer
- auth_provider_id_pp:
+ identity_provider_id_pp:
description: Authentication provider internal identifier
in: path
- name: auth_provider_id
+ name: identity_provider_id
required: true
type: integer
- auth_provider_domain_id_pp:
+ identity_provider_domain_id_pp:
description: Authentication provider domain internal identifier
in: path
- name: auth_provider_domain_id
+ name: identity_provider_domain_id
required: true
type: integer
biblio_id_pp:
- 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 identity providers\n"
+ name: identity_providers
+ x-displayName: Identity providers
- description: "Manage baskets for the acquisitions module\n"
name: baskets
x-displayName: Baskets
return {
bug_number => "31378",
- description => "Add auth_provider and auth_provider_domains configuration tables",
+ description => "Add identity_provider and identity_provider_domains configuration tables",
up => sub {
my ($args) = @_;
my ($dbh, $out) = @$args{qw(dbh out)};
$dbh->do(qq{
INSERT IGNORE permissions (module_bit, code, description)
VALUES
- ( 3, 'manage_authentication_providers', 'Manage authentication providers')
+ ( 3, 'manage_identity_providers', 'Manage authentication providers')
});
- say $out "manage_authentication_providers permission added";
+ say $out "manage_identity_providers permission added";
- unless (TableExists('auth_providers')) {
+ unless (TableExists('identity_providers')) {
$dbh->do(q{
- CREATE TABLE `auth_providers` (
- `auth_provider_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique key, used to identify the provider',
+ CREATE TABLE `identity_providers` (
+ `identity_provider_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique key, used to identify the provider',
`code` varchar(20) NOT NULL COMMENT 'Provider code',
`description` varchar(255) NOT NULL COMMENT 'Description for the provider',
`protocol` enum('OAuth', 'OIDC', 'LDAP', 'CAS') COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Protocol provider speaks',
`mapping` longtext NOT NULL DEFAULT '{}' COMMENT 'Configuration to map provider data to Koha user',
`matchpoint` enum('email','userid','cardnumber') NOT NULL COMMENT 'The patron attribute to be used as matchpoint',
`icon_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Provider icon URL',
- PRIMARY KEY (`auth_provider_id`),
+ PRIMARY KEY (`identity_provider_id`),
UNIQUE KEY (`code`),
KEY `protocol` (`protocol`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
});
}
- unless (TableExists('auth_provider_domains')) {
+ unless (TableExists('identity_provider_domains')) {
$dbh->do(q{
- CREATE TABLE `auth_provider_domains` (
- `auth_provider_domain_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique key, used to identify providers domain',
- `auth_provider_id` int(11) NOT NULL COMMENT 'Reference to provider',
+ CREATE TABLE `identity_provider_domains` (
+ `identity_provider_domain_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique key, used to identify providers domain',
+ `identity_provider_id` int(11) NOT NULL COMMENT 'Reference to provider',
`domain` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Domain name. If null means all domains',
`auto_register` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Allow user auto register',
`update_on_auth` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Update user data on auth login',
`default_library_id` varchar(10) DEFAULT NULL COMMENT 'Default library to create user if auto register is enabled',
`default_category_id` varchar(10) DEFAULT NULL COMMENT 'Default category to create user if auto register is enabled',
`allow_opac` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Allow provider from opac interface',
- `allow_staff` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Allow provider from staff interface',
- PRIMARY KEY (`auth_provider_domain_id`),
- UNIQUE KEY (`auth_provider_id`, `domain`),
+ `allow_staff` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Allow provider from staff interface',
+ PRIMARY KEY (`identity_provider_domain_id`),
+ UNIQUE KEY (`identity_provider_id`, `domain`),
KEY `domain` (`domain`),
KEY `allow_opac` (`allow_opac`),
KEY `allow_staff` (`allow_staff`),
- CONSTRAINT `auth_provider_domain_ibfk_1` FOREIGN KEY (`auth_provider_id`) REFERENCES `auth_providers` (`auth_provider_id`) ON DELETE CASCADE,
- CONSTRAINT `auth_provider_domain_ibfk_2` FOREIGN KEY (`default_library_id`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE,
- CONSTRAINT `auth_provider_domain_ibfk_3` FOREIGN KEY (`default_category_id`) REFERENCES `categories` (`categorycode`) ON DELETE CASCADE
+ CONSTRAINT `identity_provider_domain_ibfk_1` FOREIGN KEY (`identity_provider_id`) REFERENCES `identity_providers` (`identity_provider_id`) ON DELETE CASCADE,
+ CONSTRAINT `identity_provider_domain_ibfk_2` FOREIGN KEY (`default_library_id`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE,
+ CONSTRAINT `identity_provider_domain_ibfk_3` FOREIGN KEY (`default_category_id`) REFERENCES `categories` (`categorycode`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
});
}
# Print useful stuff here
say $out "Setting google provider";
$dbh->do(q{
- INSERT INTO `auth_providers` (name, protocol, config, mapping), auto_register, registration_config, interface)
+ INSERT INTO `identity_providers` (name, protocol, config, mapping), auto_register, registration_config, interface)
SELECT 'google' as name,
'OIDC' as protocol,
JSON_OBJECT("key", k.value, "secret", s.value, "well_known_url", "https://accounts.google.com/.well-known/openid-configuration", "scope", "openid email profile") as config,
});
$dbh->do(q{
- INSERT INTO `auth_provider_domains` (auth_provider_id, domain, auto_register, update_on_auth, default_library_id, default_category_id, allow_opac, allow_staff)
+ INSERT INTO `identity_provider_domains` (identity_provider_id, domain, auto_register, update_on_auth, default_library_id, default_category_id, allow_opac, allow_staff)
p.id as provider_id,
d.value as domain,
r.value as auto_register,
1 as allow_opac,
0 as allow_interface
FROM
- (SELECT id FROM `auth_provider` WHERE name = 'google') p
+ (SELECT id FROM `identity_provider` WHERE name = 'google') p
JOIN
(SELECT CASE WHEN value = '' OR value IS NULL THEN NULL ELSE value END as value FROM `systempreferences` where variable = 'GoogleOpenIDConnectDomain') d
JOIN
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `auth_provider`
+-- Table structure for table `identity_provider`
--
-DROP TABLE IF EXISTS `auth_providers`;
+DROP TABLE IF EXISTS `identity_providers`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `auth_providers` (
- `auth_provider_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique key, used to identify the provider',
+CREATE TABLE `identity_providers` (
+ `identity_provider_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique key, used to identify the provider',
`code` varchar(20) NOT NULL COMMENT 'Provider code',
`description` varchar(255) NOT NULL COMMENT 'Description for the provider',
`protocol` enum('OAuth', 'OIDC', 'LDAP', 'CAS') COLLATE utf8mb4_unicode_ci NOT NULL COMMENT 'Protocol provider speaks',
`mapping` longtext NOT NULL DEFAULT '{}' COMMENT 'Configuration to map provider data to Koha user',
`matchpoint` enum('email','userid','cardnumber') NOT NULL COMMENT 'The patron attribute to be used as matchpoint',
`icon_url` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Provider icon URL',
- PRIMARY KEY (`auth_provider_id`),
+ PRIMARY KEY (`identity_provider_id`),
UNIQUE KEY (`code`),
KEY `protocol` (`protocol`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
/*!40101 SET character_set_client = @saved_cs_client */;
--
--- Table structure for table `auth_provider`
+-- Table structure for table `identity_provider`
--
-DROP TABLE IF EXISTS `auth_provider_domains`;
+DROP TABLE IF EXISTS `identity_provider_domains`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
-CREATE TABLE `auth_provider_domains` (
- `auth_provider_domain_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique key, used to identify providers domain',
- `auth_provider_id` int(11) NOT NULL COMMENT 'Reference to provider',
+CREATE TABLE `identity_provider_domains` (
+ `identity_provider_domain_id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'unique key, used to identify providers domain',
+ `identity_provider_id` int(11) NOT NULL COMMENT 'Reference to provider',
`domain` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Domain name. If null means all domains',
`auto_register` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Allow user auto register',
`update_on_auth` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Update user data on auth login',
`default_library_id` varchar(10) DEFAULT NULL COMMENT 'Default library to create user if auto register is enabled',
`default_category_id` varchar(10) DEFAULT NULL COMMENT 'Default category to create user if auto register is enabled',
`allow_opac` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Allow provider from opac interface',
- `allow_staff` tinyint(1) NOT NULL DEFAULT 1 COMMENT 'Allow provider from staff interface',
- PRIMARY KEY (`auth_provider_domain_id`),
- UNIQUE KEY (`auth_provider_id`, `domain`),
+ `allow_staff` tinyint(1) NOT NULL DEFAULT 0 COMMENT 'Allow provider from staff interface',
+ PRIMARY KEY (`identity_provider_domain_id`),
+ UNIQUE KEY (`identity_provider_id`, `domain`),
KEY `domain` (`domain`),
KEY `allow_opac` (`allow_opac`),
KEY `allow_staff` (`allow_staff`),
- CONSTRAINT `auth_provider_domain_ibfk_1` FOREIGN KEY (`auth_provider_id`) REFERENCES `auth_providers` (`auth_provider_id`) ON DELETE CASCADE,
- CONSTRAINT `auth_provider_domain_ibfk_2` FOREIGN KEY (`default_library_id`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE,
- CONSTRAINT `auth_provider_domain_ibfk_3` FOREIGN KEY (`default_category_id`) REFERENCES `categories` (`categorycode`) ON DELETE CASCADE
+ CONSTRAINT `identity_provider_domain_ibfk_1` FOREIGN KEY (`identity_provider_id`) REFERENCES `identity_providers` (`identity_provider_id`) ON DELETE CASCADE,
+ CONSTRAINT `identity_provider_domain_ibfk_2` FOREIGN KEY (`default_library_id`) REFERENCES `branches` (`branchcode`) ON DELETE CASCADE,
+ CONSTRAINT `identity_provider_domain_ibfk_3` FOREIGN KEY (`default_category_id`) REFERENCES `categories` (`categorycode`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
--
( 3, 'manage_background_jobs', 'Manage background jobs'),
( 3, 'manage_curbside_pickups', 'Manage curbside pickups'),
( 3, 'manage_search_filters', 'Manage custom search filters'),
- ( 3, 'manage_authentication_providers', 'Manage authentication providers'),
+ ( 3, 'manage_identity_providers', 'Manage authentication providers'),
( 4, 'delete_borrowers', 'Delete patrons'),
( 4, 'edit_borrowers', 'Add, modify and view patron information'),
( 4, 'view_borrower_infos_from_any_libraries', 'View patron infos from any libraries'),
</ul>
[% END %]
- [% IF ( CAN_user_parameters_manage_authentication_providers || CAN_user_parameters_manage_smtp_servers || CAN_user_parameters_manage_search_targets || CAN_user_parameters_manage_didyoumean || CAN_user_parameters_manage_column_config || CAN_user_parameters_manage_audio_alerts || ( CAN_user_parameters_manage_sms_providers && Koha.Preference('SMSSendDriver') == 'Email' ) || CAN_user_parameters_manage_usage_stats || CAN_user_parameters_manage_additional_fields || ( Koha.Preference('EnableAdvancedCatalogingEditor') && CAN_user_parameters_manage_keyboard_shortcuts ) ) %]
+ [% IF ( CAN_user_parameters_manage_identity_providers || CAN_user_parameters_manage_smtp_servers || CAN_user_parameters_manage_search_targets || CAN_user_parameters_manage_didyoumean || CAN_user_parameters_manage_column_config || CAN_user_parameters_manage_audio_alerts || ( CAN_user_parameters_manage_sms_providers && Koha.Preference('SMSSendDriver') == 'Email' ) || CAN_user_parameters_manage_usage_stats || CAN_user_parameters_manage_additional_fields || ( Koha.Preference('EnableAdvancedCatalogingEditor') && CAN_user_parameters_manage_keyboard_shortcuts ) ) %]
<h5>Additional parameters</h5>
<ul>
- [% IF ( CAN_user_parameters_manage_authentication_providers) %]
- <li><a href="/cgi-bin/koha/admin/authentication_providers.pl">Authentication providers</a></li>
+ [% IF ( CAN_user_parameters_manage_identity_providers) %]
+ <li><a href="/cgi-bin/koha/admin/identity_providers.pl">Authentication providers</a></li>
[% END %]
[% IF ( CAN_user_parameters_manage_search_targets ) %]
<li><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50/SRU servers</a></li>
Manage recalls for patrons
</span>
<span class="permissioncode">([% name | html %])</span>
- [%# authentication_providers %]
- [%- CASE 'manage_authentication_providers' -%]
- <span class="sub_permission manage_authentication_providers_subpermission">
+ [%# identity_providers %]
+ [%- CASE 'manage_identity_providers' -%]
+ <span class="sub_permission manage_identity_providers_subpermission">
Manage authentication providers
</span>
<span class="permissioncode">([% name | html %])</span>
</dl>
[% END %]
- [% IF ( ( CAN_user_parameters_manage_authentication_providers || CAN_user_parameters_manage_smtp_servers || CAN_user_parameters_manage_search_targets || CAN_user_parameters_manage_didyoumean || CAN_user_parameters_manage_column_config || CAN_user_parameters_manage_audio_alerts || CAN_user_parameters_manage_sms_providers && Koha.Preference('SMSSendDriver') == 'Email' ) || CAN_user_parameters_manage_usage_stats || CAN_user_parameters_manage_additional_fields || CAN_user_parameters_manage_mana || (Koha.Preference('EnableAdvancedCatalogingEditor') && CAN_user_parameters_manage_keyboard_shortcuts) ) %]
+ [% IF ( ( CAN_user_parameters_manage_identity_providers || CAN_user_parameters_manage_smtp_servers || CAN_user_parameters_manage_search_targets || CAN_user_parameters_manage_didyoumean || CAN_user_parameters_manage_column_config || CAN_user_parameters_manage_audio_alerts || CAN_user_parameters_manage_sms_providers && Koha.Preference('SMSSendDriver') == 'Email' ) || CAN_user_parameters_manage_usage_stats || CAN_user_parameters_manage_additional_fields || CAN_user_parameters_manage_mana || (Koha.Preference('EnableAdvancedCatalogingEditor') && CAN_user_parameters_manage_keyboard_shortcuts) ) %]
<h3>Additional parameters</h3>
<dl>
<!-- <dt><a href="/cgi-bin/koha/admin/printers.pl">Network Printers</a></dt>
<dd>Printers (UNIX paths).</dd> -->
- [% IF ( CAN_user_parameters_manage_authentication_providers) %]
- <dt><a href="/cgi-bin/koha/admin/authentication_providers.pl">Authentication providers</a></dt>
- <dd>Define which external authentication providers to use</dd>
+ [% IF ( CAN_user_parameters_manage_identity_providers) %]
+ <dt><a href="/cgi-bin/koha/admin/identity_providers.pl">Identity providers</a></dt>
+ <dd>Define which external identity providers to use</dd>
[% END %]
[% IF ( CAN_user_parameters_manage_search_targets ) %]
<dt><a href="/cgi-bin/koha/admin/z3950servers.pl">Z39.50/SRU servers</a></dt>
+++ /dev/null
-[% USE raw %]
-[% USE Asset %]
-[% USE Branches %]
-[% USE Categories %]
-[% SET footerjs = 1 %]
-[% INCLUDE 'doc-head-open.inc' %]
-<title>
- [% IF op == 'add_form' %]
- New authentication provider domain › [% ELSIF op == 'edit_form' %]
- Edit authentication provider domain › [% END %]
-
- Authentication providers › Administration › Koha
-</title>
-[% INCLUDE 'doc-head-close.inc' %]
-</head>
-
-<body id="admin_auth_provider_domains" class="admin">
-[% INCLUDE 'header.inc' %]
-[% INCLUDE 'prefs-admin-search.inc' %]
-
-<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
- <ol>
- <li>
- <a href="/cgi-bin/koha/mainpage.pl">Home</a>
- </li>
- <li>
- <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
- </li>
-
- <li>
- <a href="/cgi-bin/koha/admin/authentication_providers.pl">Authentication providers</a>
- </li>
-
- [% IF op == 'add_form' %]
- <li>
- <a href="/cgi-bin/koha/admin/authentication_providers.pl?domain_ops=1&auth_provider_id=[%- auth_provider_id | uri -%]">Domains for [%- auth_provider_name | html -%]</a>
- </li>
- <li>
- <a href="#" aria-current="page">
- New Domain
- </a>
- </li>
-
- [% ELSIF op == 'edit_form' %]
- <li>
- <a href="/cgi-bin/koha/admin/authentication_providers.pl?domain_ops=1&auth_provider_id=[%- auth_provider_id | uri -%]">Domains for [%- auth_provider_name | html -%]</a>
- </li>
- <li>
- <a href="#" aria-current="page">
- Edit Domain
- </a>
- </li>
-
- [% ELSE %]
- <li>
- <a href="#" aria-current="page">
- Domains for [%- auth_provider_code | html -%]
- </a>
- </li>
- [% END %]
- </ol>
-</nav>
-
-<div class="main container-fluid">
- <div class="row">
- <div class="col-sm-10 col-sm-push-2">
- <main>
-
-[% FOREACH m IN messages %]
- <div class="dialog [% m.type | html %]" id="auth_provider_domain_action_result_dialog">
- [% SWITCH m.code %]
- [% CASE 'error_on_update' %]
- <span>An error occurred trying to open the authentication provider domain for editing. The passed id is invalid.</span>
- [% CASE 'error_on_insert' %]
- <span>An error occurred when adding a new authentication provider domain.</span>
- [% CASE 'success_on_update' %]
- <span>Authentication provider domain updated successfully.</span>
- [% CASE 'success_on_insert' %]
- <span>Authentication provider domain added successfully.</span>
- [% CASE %]
- <span>[% m.code | html %]</span>
- [% END %]
- </div>
-[% END %]
-
- <div class="dialog message" id="auth_provider_domain_delete_success" style="display: none;"></div>
- <div class="dialog alert" id="auth_provider_domain_delete_error" style="display: none;"></div>
-
-[% IF op == 'add_form' %]
- <h1>New authentication provider domain</h1>
- <form action="/cgi-bin/koha/admin/authentication_providers.pl" id="add" name="add" class="validated" method="post">
- <input type="hidden" name="op" value="add" />
- <input type="hidden" name="domain_ops" value="1" />
- <input type="hidden" name="auth_provider_id" value="[%- auth_provider_id | html -%]" />
- <fieldset class="rows">
- <ol>
- <li>
- <label for="domain">Domain: </label>
- <input type="text" name="domain" id="domain" size="60" />
- </li>
- </ol>
- </fieldset>
-
- <fieldset class="rows">
- <ol>
- <li>
- <label for="update_on_auth">Update on login: </label>
- <select name="update_on_auth" id="update_on_auth">
- <option value="1">Update</option>
- <option value="0" selected="selected">Don't update</option>
- </select>
- <span>user data on login</span>
- </li>
- <li>
- <label for="auto_register">Auto register: </label>
- <select name="auto_register" id="auto_register">
- <option value="1">Allow</option>
- <option value="0" selected="selected">Don't allow</option>
- </select>
- <span>users to auto register on login</span>
- </li>
- <li>
- <label for="default_library_id">Default library: </label>
- <select id="default_library_id" name="default_library_id">
- [% PROCESS options_for_libraries libraries => Branches.all( unfiltered => 1, do_not_select_my_library => 1 ) %]
- </select>
- </li>
- <li>
- <label for="default_category_id">Default category: </label>
- [% SET categories = Categories.all() %]
- <select name="default_category_id" id="default_category_id">
- [% FOREACH category IN categories %]
- <option value="[% category.categorycode | html %]">[% category.description | html %]</option>
- [% END %]
- </select>
- </li>
- <li>
- <label for="allow_opac">Allow opac: </label>
- <select name="allow_opac" id="allow_opac">
- <option value="1" selected="selected">Allow</option>
- <option value="0">Don't allow</option>
- </select>
- <span>opac users of this domain to login with this authentication provider</span>
- </li>
- <li>
- <label for="allow_opac">Allow staff: </label>
- <select name="allow_staff" id="allow_staff">
- <option value="1" selected="selected">Allow</option>
- <option value="0">Don't allow</option>
- </select>
- <span>of this domain </span>
- </li>
- </ol>
- </fieldset>
- <fieldset class="action">
- <input type="submit" value="Submit" />
- <a class="cancel" href="/cgi-bin/koha/admin/authentication_providers.pl?domain_ops=1&auth_provider_id=[%- auth_provider_id | html -%]">Cancel</a>
- </fieldset>
- </form>
-[% END %]
-
-[% IF op == 'edit_form' %]
- <h1>Edit authentication provider domain</h1>
- <form action="/cgi-bin/koha/admin/authentication_providers.pl" id="edit_save" name="edit_save" class="validated" method="post">
- <input type="hidden" name="op" value="edit_save" />
- <input type="hidden" name="domain_ops" value="1" />
- <input type="hidden" name="auth_provider_id" value="[%- auth_provider_id | html -%]" />
- <input type="hidden" name="auth_provider_domain_id" value="[%- auth_provider_domain.auth_provider_domain_id | html -%]" />
- <fieldset class="rows">
- <ol>
- <li>
- <label for="domain">Domain: </label>
- <input type="text" name="domain" id="domain" size="60" value="[%- auth_provider_domain.domain | html -%]"/>
- </li>
- </ol>
- </fieldset>
-
- <fieldset class="rows">
- <ol>
- <li>
- <label for="update_on_auth">Update on login: </label>
- <select name="update_on_auth" id="update_on_auth">
- [% IF auth_provider_domain.update_on_auth == "1" %]
- <option value="1" selected="selected">Update</option>
- <option value="0">Don't update</option>
- [% ELSE %]
- <option value="1">Update</option>
- <option value="0" selected="selected">Don't update</option>
- [% END %]
- </select>
- <span>user data on login</span>
- </li>
- <li>
- <label for="auto_register">Auto register: </label>
- <select name="auto_register" id="auto_register">
- [% IF auth_provider_domain.auto_register == "1" %]
- <option value="1" selected="selected">Allow</option>
- <option value="0">Don't allow</option>
- [% ELSE %]
- <option value="1">Allow</option>
- <option value="0" selected="selected">Don't allow</option>
- [% END %]
- </select>
- <span>users to auto register on login</span>
- </li>
- <li>
- <label for="default_library_id">Default library: </label>
- <select id="default_library_id" name="default_library_id">
- [% PROCESS options_for_libraries libraries => Branches.all( selected => auth_provider_domain.default_library_id, unfiltered => 1, do_not_select_my_library => 1 ) %]
- </select>
- </li>
- <li>
- <label for="default_category_id">Default category: </label>
- [% SET categories = Categories.all() %]
- <select name="default_category_id" id="default_category_id">
- [% FOREACH category IN categories %]
- [% IF category.categorycode == auth_provider_domain.default_category_id %]
- <option value="[% category.categorycode | html %]" selected="selected">[% category.description | html %]</option>
- [% ELSE %]
- <option value="[% category.categorycode | html %]">[% category.description | html %]</option>
- [% END %]
- [% END %]
- </select>
- </li>
- <li>
- <label for="allow_opac">Allow opac: </label>
- <select name="allow_opac" id="allow_opac">
- [% IF auth_provider_domain.allow_opac == "1" %]
- <option value="1" selected="selected">Allow</option>
- <option value="0">Don't allow</option>
- [% ELSE %]
- <option value="1">Allow</option>
- <option value="0" selected="selected">Don't allow</option>
- [% END %]
- </select>
- <span>opac users of this domain to login with this authentication provider</span>
- </li>
- <li>
- <label for="allow_opac">Allow staff: </label>
- <select name="allow_staff" id="allow_staff">
- [% IF auth_provider_domain.allow_staff == "1" %]
- <option value="1" selected="selected">Allow</option>
- <option value="0">Don't allow</option>
- [% ELSE %]
- <option value="1">Allow</option>
- <option value="0" selected="selected">Don't allow</option>
- [% END %]
- </select>
- <span>staff users of this domain to login with this authentication provider</span>
- </li>
- </ol>
- </fieldset>
- <fieldset class="action">
- <input type="submit" value="Submit" />
- <a class="cancel" href="/cgi-bin/koha/admin/authentication_providers.pl?domain_ops=1&auth_provider_id=[%- auth_provider_id | html -%]">Cancel</a>
- </fieldset>
- </form>
-[% END %]
-
-[% IF op == 'list' %]
-
- <div id="toolbar" class="btn-toolbar">
- <a class="btn btn-default" id="new_auth_provider_domain" href="/cgi-bin/koha/admin/authentication_providers.pl?domain_ops=1&auth_provider_id=[%- auth_provider_id | html -%]&op=add_form"><i class="fa fa-plus"></i> New authentication provider domain</a>
- </div>
-
- <h1>Authentication provider domains</h1>
-
- <table id="auth_provider_domains">
- <thead>
- <tr>
- <th>Domain</th>
- <th>Update on login</th>
- <th>Auto register</th>
- <th>Default library</th>
- <th>Default category</th>
- <th>Allow opac</th>
- <th>Allow staff</th>
- <th data-class-name="actions noExport">Actions</th>
- </tr>
- </thead>
- </table>
-[% END %]
-
- <div id="delete_confirm_modal" class="modal" tabindex="-1" role="dialog" aria-labelledby="delete_confirm_modal_label" aria-hidden="true">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ă—</button>
- <h3 id="delete_confirm_modal_label">Delete authentication provider domain</h3>
- </div>
- <div class="modal-body">
- <div id="delete_confirm_dialog"></div>
- </div>
- <div class="modal-footer">
- <a href="#" class="btn btn-default" id="delete_confirm_modal_button" role="button" data-toggle="modal">Delete</a>
- <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
- </div>
- </div> <!-- /.modal-content -->
- </div> <!-- /.modal-dialog -->
- </div> <!-- #delete_confirm_modal -->
-
- </main>
- </div> <!-- /.col-sm-10.col-sm-push-2 -->
-
- <div class="col-sm-2 col-sm-pull-10">
- <aside>
- [% INCLUDE 'admin-menu.inc' %]
- </aside>
- </div> <!-- /.col-sm-2.col-sm-pull-10 -->
- </div> <!-- /.row -->
-
-
-[% MACRO jsinclude BLOCK %]
- [% Asset.js("js/admin-menu.js") | $raw %]
- [% INCLUDE 'datatables.inc' %]
- <script>
- $(document).ready(function() {
-
- var auth_provider_domains_url = '/api/v1/auth/providers/[%- auth_provider_id | html -%]/domains';
- [% SET categories = Categories.all() %]
- var categories = {
- [% FOREACH category IN categories %]
- "[% category.categorycode | html %]": "[% category.description | html %]",
- [% END %]
- };
- [% SET libraries = Branches.all() %]
- var libraries = {
- [% FOREACH library IN libraries %]
- "[% library.branchcode | html %]": "[% library.branchname | html %]",
- [% END %]
- };
- window.auth_provider_domains = $("#auth_provider_domains").kohaTable({
- "ajax": {
- "url": auth_provider_domains_url
- },
- 'language': {
- 'emptyTable': '<div class="dialog message">'+_("There are no authentication provider domains defined.")+'</div>'
- },
- "columnDefs": [ {
- "targets": [1],
- "render": function (data, type, row, meta) {
- if ( type == 'display' ) {
- if ( data != null ) {
- return data.escapeHtml();
- }
- else {
- return "";
- }
- }
- return data;
- }
- } ],
- "columns": [
- {
- "data": "domain",
- "searchable": true,
- "orderable": true,
- "render": function(data, type, row, meta) {
- if ( data != null ) {
- return data.escapeHtml();
- }
- else {
- return "*";
- }
- }
- },
- {
- "data": function( row, type, val, meta ) {
- if (row.update_on_auth) {
- return _("Yes");
- } else {
- return _("No");
- }
- },
- "searchable": true,
- "orderable": true
- },
- {
- "data": function( row, type, val, meta ) {
- if (row.auto_register) {
- return _("Yes");
- } else {
- return _("No");
- }
- },
- "searchable": true,
- "orderable": true
- },
- {
- "data": function( row, type, val, meta ) {
- return libraries[row.default_library_id] || "";
- },
- "searchable": true,
- "orderable": true
- },
- {
- "data": function( row, type, val, meta ) {
- return categories[row.default_category_id] || "";
- },
- "searchable": true,
- "orderable": true
- },
- {
- "data": function( row, type, val, meta ) {
- if (row.allow_opac) {
- return _("Yes");
- } else {
- return _("No");
- }
- },
- "searchable": true,
- "orderable": true
- },
- {
- "data": function( row, type, val, meta ) {
- if (row.allow_staff) {
- return _("Yes");
- } else {
- return _("No");
- }
- },
- "searchable": true,
- "orderable": true
- },
- {
- "data": function( row, type, val, meta ) {
- var result = '<a class="btn btn-default btn-xs" role="button" href="/cgi-bin/koha/admin/authentication_providers.pl?domain_ops=1&auth_provider_id=[%- auth_provider_id | html -%]&op=edit_form&auth_provider_domain_id='+ encodeURIComponent(row.auth_provider_domain_id) +'"><i class="fa fa-pencil" aria-hidden="true"></i> '+_("Edit")+'</a>'+"\n";
- result += '<a class="btn btn-default btn-xs delete_auth_provider_domain" role="button" href="#" data-toggle="modal" data-target="#delete_confirm_modal" data-auth-provider-domain-id="'+ encodeURIComponent(row.auth_provider_domain_id) +'" data-auth-provider-domain="'+ encodeURIComponent((row.domain || '').escapeHtml()) +'"><i class="fa fa-trash" aria-hidden="true"></i> '+_("Delete")+'</a>';
- return result;
- },
- "searchable": false,
- "orderable": false
- }
- ],
- createdRow: function (row, data, dataIndex) {
- if ( data.debug ) {
- $(row).addClass('debug');
- }
- },
- });
-
- $('#auth_provider_domains').on( "click", '.delete_auth_provider_domain', function () {
- var auth_provider_domain_id = $(this).data('auth-provider-domain-id');
- var auth_provider_domain = decodeURIComponent($(this).data('auth-provider-domain'));
-
- $("#delete_confirm_dialog").html(
- _("You are about to delete the '%s' authentication provider domain.").format(auth_provider_domain)
- );
- $("#delete_confirm_modal_button").data('auth-provider-domain-id', auth_provider_domain_id);
- $("#delete_confirm_modal_button").data('auth-provider-domain', auth_provider_domain);
- });
-
- $("#delete_confirm_modal_button").on( "click", function () {
-
- var auth_provider_domain_id = $(this).data('auth-provider-domain-id');
- var auth_provider_domain = $(this).data('auth-provider-domain');
-
- $.ajax({
- method: "DELETE",
- url: auth_provider_domains_url+"/"+auth_provider_domain_id
- }).success(function() {
- window.auth_provider_domains.api().ajax.reload(function (data) {
- $("#smtp_action_result_dialog").hide();
- $("#smtp_delete_success").html(_("Server '%s' deleted successfully.").format(auth_provider_domain)).show();
- });
- }).fail(function () {
- $("#smtp_delete_error").html(_("Error deleting server '%s'. Check the logs.").format(auth_provider_domain)).show();
- }).done(function () {
- $("#delete_confirm_modal").modal('hide');
- });
- });
- });
- </script>
-[% END %]
-
-[% INCLUDE 'intranet-bottom.inc' %]
+++ /dev/null
-[% USE raw %]
-[% USE Asset %]
-[% SET footerjs = 1 %]
-[% INCLUDE 'doc-head-open.inc' %]
-<title>
- [% IF op == 'add_form' %]
- New authentication provider › [% ELSIF op == 'edit_form' %]
- Edit authentication provider › [% END %]
-
- Authentication providers › Administration › Koha
-</title>
-[% INCLUDE 'doc-head-close.inc' %]
-</head>
-
-<body id="admin_auth_providers" class="admin">
-[% INCLUDE 'header.inc' %]
-[% INCLUDE 'prefs-admin-search.inc' %]
-
-<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
- <ol>
- <li>
- <a href="/cgi-bin/koha/mainpage.pl">Home</a>
- </li>
- <li>
- <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
- </li>
-
- [% IF op == 'add_form' %]
- <li>
- <a href="/cgi-bin/koha/admin/authentication_providers.pl">Authentication providers</a>
- </li>
- <li>
- <a href="#" aria-current="page">
- New
- </a>
- </li>
-
- [% ELSIF op == 'edit_form' %]
- <li>
- <a href="/cgi-bin/koha/admin/authentication_providers.pl">Authentication providers</a>
- </li>
- <li>
- <a href="#" aria-current="page">
- Edit
- </a>
- </li>
-
- [% ELSE %]
- <li>
- <a href="#" aria-current="page">
- Authentication providers
- </a>
- </li>
- [% END %]
- </ol>
-</nav>
-
-<div class="main container-fluid">
- <div class="row">
- <div class="col-sm-10 col-sm-push-2">
- <main>
-
-[% FOREACH m IN messages %]
- <div class="dialog [% m.type | html %]" id="auth_provider_action_result_dialog">
- [% SWITCH m.code %]
- [% CASE 'error_on_update' %]
- <span>An error occurred trying to open the authentication provider for editing. The passed id is invalid.</span>
- [% CASE 'error_on_insert' %]
- <span>An error occurred when adding a new authentication provider.</span>
- [% CASE 'success_on_update' %]
- <span>Authentication provider updated successfully.</span>
- [% CASE 'success_on_insert' %]
- <span>Authentication provider added successfully.</span>
- [% CASE %]
- <span>[% m.code | html %]</span>
- [% END %]
- </div>
-[% END %]
-
- <div class="dialog message" id="auth_provider_delete_success" style="display: none;"></div>
- <div class="dialog alert" id="auth_provider_delete_error" style="display: none;"></div>
-
-[% IF op == 'add_form' %]
- <h1>New authentication provider</h1>
- <form action="/cgi-bin/koha/admin/authentication_providers.pl" id="add" name="add" class="validated" method="post">
- <input type="hidden" name="op" value="add" />
- <fieldset class="rows">
- <ol>
- <li>
- <label for="code" class="required">Code: </label>
- <input type="text" name="code" id="code" size="60" class="required" required="required" />
- <span class="required">Required</span>
- </li>
- <li>
- <label for="description" class="required">Description: </label>
- <input type="text" name="description" id="description" size="60" class="required" required="required" />
- <span class="required">Required</span>
- </li>
- <li>
- <label for="protocol">Protocol: </label>
- <select name="protocol" id="protocol">
- <option value="OAuth">OAuth</option>
- <option value="OIDC">OIDC</option>
- <!-- Not implemented yet
- <option value="LDAP">LDAP</option>
- <option value="CAS">CAS</option>
- -->
- </select>
- </li>
- </ol>
- </fieldset>
-
- <fieldset class="rows">
- <ol>
- <li>
- <div>
- <label for="config" class="required json">Configuration: </label>
- <textarea name="config" id="config" class="required"></textarea>
- <span class="required">Required</span>
- </div>
- <div>
- <label></label>
- <button class="btn btn-ligth defaults" data-default-target="config" id="default-config">Add default OAuth configuration</button>
- </div>
- </li>
- <li>
- <div>
- <label for="mapping" class="required json">Mapping: </label>
- <textarea name="mapping" id="mapping" class="required"></textarea>
- <span class="required">Required</span>
- </div>
- <div>
- <label></label>
- <button class="btn btn-ligth defaults" data-default-target="mapping" id="default-mapping">Add default OAuth mapping</button>
- </div>
- </li>
- <li>
- <label for="matchpoint" class="required">Matchpoint: </label>
- <select name="matchpoint" id="matchpoint" class="required">
- <option value="email">Email</option>
- <option value="userid">User id</option>
- <option value="cardnumber">Card number</option>
- </select>
- <span class="required">Required</span>
- </li>
- <li>
- <label for="icon_url">Icon URL: </label>
- <input type="text" name="icon_url" id="icon_url" size="60" />
- </li>
- </ol>
- </fieldset>
- <fieldset class="action">
- <input type="submit" value="Submit" />
- <a class="cancel" href="/cgi-bin/koha/admin/authentication_providers.pl">Cancel</a>
- </fieldset>
- </form>
-[% END %]
-
-[% IF op == 'edit_form' %]
- <h1>Edit authentication provider</h1>
- <form action="/cgi-bin/koha/admin/authentication_providers.pl" id="edit_save" name="edit_save" class="validated" method="post">
- <input type="hidden" name="op" value="edit_save" />
- <input type="hidden" name="auth_provider_id" value="[%- auth_provider.auth_provider_id | html -%]" />
- <fieldset class="rows">
- <ol>
- <li>
- <label for="code" class="required">Code: </label>
- <input type="text" name="code" id="code" size="60" class="required" required="required" value="[%- auth_provider.code | html -%]"/>
- <span class="required">Required</span>
- </li>
- <li>
- <label for="description" class="required">Description: </label>
- <input type="text" name="description" id="description" size="60" class="required" required="required" value="[%- auth_provider.description | html -%]"/>
- <span class="required">Required</span>
- </li>
- <li>
- <label for="protocol">Protocol: </label>
- <select name="protocol" id="protocol">
- [% IF auth_provider.protocol == 'OAuth' %]
- <option value="OAuth" selected="selected">OAuth</option>
- <option value="OIDC">OIDC</option>
- <!-- Not implemented yet
- <option value="LDAP">LDAP</option>
- <option value="CAS">CAS</option>
- -->
- [% ELSE %]
- <option value="OAuth">OAuth</option>
- <option value="OIDC" selected="selected">OIDC</option>
- <!-- Not implemented yet
- <option value="LDAP">LDAP</option>
- <option value="CAS">CAS</option>
- -->
- [% END %]
- </select>
- </li>
- </ol>
- </fieldset>
-
- <fieldset class="rows">
- <ol>
- <li>
- <div>
- <label for="config" class="required json">Configuration: </label>
- <textarea name="config" id="config" class="required">[%- auth_provider.config | html -%]</textarea>
- <span class="required">Required</span>
- </div>
- <div>
- <label></label>
- <button class="btn btn-ligth defaults" data-default-target="config" id="default-config">Add default [%- auth_provider.protocol | html -%] configuration</button>
- </div>
- </li>
- <li>
- <div>
- <label for="mapping" class="required json">Mapping: </label>
- <textarea name="mapping" id="mapping" class="required">[%- auth_provider.mapping | html -%]</textarea>
- <span class="required">Required</span>
- </div>
- <div>
- <label></label>
- <button class="btn btn-ligth defaults" data-default-target="mapping" id="default-mapping">Add default [%- auth_provider.protocol | html -%] mapping</button>
- </div>
- </li>
- <li>
- <label for="matchpoint" class="required">matchpoint: </label>
- <select name="matchpoint" id="matchpoint" class="required">
- [%- IF auth_provider.matchpoint == 'email' -%]
- <option value="email" selected="selected">Email</option>
- [%- ELSE -%]
- <option value="email">Email</option>
- [%- END -%]
- [%- IF auth_provider.matchpoint == 'userid' -%]
- <option value="userid" selected="selected">User id</option>
- [%- ELSE -%]
- <option value="userid">User id</option>
- [%- END -%]
- [%- IF auth_provider.matchpoint == 'cardnumber' -%]
- <option value="cardnumber" selected="selected">Card number</option>
- [%- ELSE -%]
- <option value="cardnumber">Card number</option>
- [%- END -%]
- </select>
- <span class="required">Required</span>
- </li>
- <li>
- <label for="icon_url">Icon URL: </label>
- <input type="text" name="icon_url" id="icon_url" size="60" value="[%- auth_provider.icon_url | html -%]"/>
- </li>
- </ol>
- </fieldset>
- <fieldset class="action">
- <input type="submit" value="Submit" />
- <a class="cancel" href="/cgi-bin/koha/admin/authentication_providers.pl">Cancel</a>
- </fieldset>
- </form>
-[% END %]
-
-[% IF op == 'list' %]
-
- <div id="toolbar" class="btn-toolbar">
- <a class="btn btn-default" id="new_auth_provider" href="/cgi-bin/koha/admin/authentication_providers.pl?op=add_form"><i class="fa fa-plus"></i> New authentication provider</a>
- </div>
-
- <h1>Authentication providers</h1>
-
- <table id="auth_providers">
- <thead>
- <tr>
- <th>Code</th>
- <th>Description</th>
- <th>Protocol</th>
- <th data-class-name="actions noExport">Actions</th>
- </tr>
- </thead>
- </table>
-[% END %]
-
- <div id="delete_confirm_modal" class="modal" tabindex="-1" role="dialog" aria-labelledby="delete_confirm_modal_label" aria-hidden="true">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ă—</button>
- <h3 id="delete_confirm_modal_label">Delete authentication provider</h3>
- </div>
- <div class="modal-body">
- <div id="delete_confirm_dialog"></div>
- </div>
- <div class="modal-footer">
- <a href="#" class="btn btn-default" id="delete_confirm_modal_button" role="button" data-toggle="modal">Delete</a>
- <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
- </div>
- </div> <!-- /.modal-content -->
- </div> <!-- /.modal-dialog -->
- </div> <!-- #delete_confirm_modal -->
-
- </main>
- </div> <!-- /.col-sm-10.col-sm-push-2 -->
-
- <div class="col-sm-2 col-sm-pull-10">
- <aside>
- [% INCLUDE 'admin-menu.inc' %]
- </aside>
- </div> <!-- /.col-sm-2.col-sm-pull-10 -->
- </div> <!-- /.row -->
-
-
-[% MACRO jsinclude BLOCK %]
- [% Asset.js("js/admin-menu.js") | $raw %]
- [% INCLUDE 'datatables.inc' %]
- <script>
- $(document).ready(function() {
-
- var auth_providers_url = '/api/v1/auth/providers';
- window.auth_providers = $("#auth_providers").kohaTable({
- "ajax": {
- "url": auth_providers_url
- },
- 'language': {
- 'emptyTable': '<div class="dialog message">'+_("There are no authentication providers defined.")+'</div>'
- },
- "columnDefs": [ {
- "targets": [0,1,2],
- "render": function (data, type, row, meta) {
- if ( type == 'display' ) {
- if ( data != null ) {
- return data.escapeHtml();
- }
- else {
- return "Default";
- }
- }
- return data;
- }
- } ],
- "columns": [
- {
- "data": "code",
- "searchable": true,
- "orderable": true
- },
- {
- "data": "description",
- "searchable": true,
- "orderable": true
- },
- {
- "data": "protocol",
- "searchable": true,
- "orderable": true
- },
- {
- "data": function( row, type, val, meta ) {
- var result = '<a class="btn btn-default btn-xs" role="button" href="/cgi-bin/koha/admin/authentication_providers.pl?op=edit_form&auth_provider_id='+ encodeURIComponent(row.auth_provider_id) +'"><i class="fa fa-pencil" aria-hidden="true"></i> '+_("Edit")+'</a>'+"\n";
- result += '<a class="btn btn-default btn-xs delete_auth_provider" role="button" href="#" data-toggle="modal" data-target="#delete_confirm_modal" data-auth-provider-id="'+ encodeURIComponent(row.auth_provider_id) +'" data-auth-provider-code="'+ encodeURIComponent(row.code.escapeHtml()) +'"><i class="fa fa-trash" aria-hidden="true"></i> '+_("Delete")+'</a>'+"\n";
- result += '<a class="btn btn-default btn-xs edit_domains" role="button" href="/cgi-bin/koha/admin/authentication_providers.pl?domain_ops=1&auth_provider_id='+ encodeURIComponent(row.auth_provider_id) +'"><i class="fa fa-cog" aria-hidden="true"></i> '+_("Manage Domains")+'</a>';
- return result;
- },
- "searchable": false,
- "orderable": false
- }
- ],
- createdRow: function (row, data, dataIndex) {
- if ( data.debug ) {
- $(row).addClass('debug');
- }
- },
- });
-
- $('#auth_providers').on( "click", '.delete_auth_provider', function () {
- var auth_provider_id = $(this).data('auth-provider-id');
- var auth_provider_code = decodeURIComponent($(this).data('auth-provider-code'));
-
- $("#delete_confirm_dialog").html(
- _("You are about to delete the '%s' authentication provider.").format(auth_provider_code)
- );
- $("#delete_confirm_modal_button").data('auth-provider-id', auth_provider_id);
- $("#delete_confirm_modal_button").data('auth-provider-code', auth_provider_code);
- });
-
- $("#delete_confirm_modal_button").on( "click", function () {
-
- var auth_provider_id = $(this).data('auth-provider-id');
- var auth_provider_code = $(this).data('auth-provider-code');
-
- $.ajax({
- method: "DELETE",
- url: auth_providers_url+"/"+auth_provider_id
- }).success(function() {
- window.auth_providers.api().ajax.reload(function (data) {
- $("#auth_provider_action_result_dialog").hide();
- $("#auth_provider_delete_success").html(_("Server '%s' deleted successfully.").format(auth_provider_code)).show();
- });
- }).fail(function () {
- $("#auth_provider_delete_error").html(_("Error deleting server '%s'. Check the logs.").format(auth_provider_code)).show();
- }).done(function () {
- $("#delete_confirm_modal").modal('hide');
- });
- });
-
- $.validator.addMethod('json', function(value, element) {
- if (this.optional(element)) return true;
- try {
- JSON.parse(value)
- } catch (error) {
- return false;
- }
- return true;
- }, _('Not a valid JSON'));
-
- $('#config, #mapping').each(function() {
- $(this).rules('add', {
- required: true,
- json: true
- });
- });
-
- var defaults = {
- OIDC: {
- config: {
- key: "<enter client id>",
- secret: "<enter client secret>",
- well_known_url: "<enter openid configuration endpoint>",
- scope: "openid email"
- },
- mapping: {
- email: "email",
- given_name: "firstname",
- family_name: "surname"
- }
- },
- OAuth: {
- config: {
- key: "<enter client id>",
- secret: "<enter client secret>",
- authorize_url: "<enter authorization endpoint>",
- token_url: "<enter token endpoint>",
- userinfo_url: "<enter user info endpoint (optional)>",
- scope: "email"
- },
- mapping: {
- email: "email",
- given_name: "firstname",
- family_name: "surname"
- }
- }
- };
-
- $('#protocol').on('change', function() {
- var protocol = $(this).val();
- $('#default-config').html(_('Add default %s configuration').format(protocol));
- $('#default-mapping').html(_('Add default %s mapping').format(protocol));
- });
-
- $('button.defaults').on('click', function(event) {
- event.preventDefault();
- var target = $(this).data('defaultTarget');
- if($('#'+target).html() !== '' && !confirm(_('Are you sure you want to replace current %s contents?').format(target))) {
- return;
- }
- var protocol = $('#protocol').val();
- $('#'+target).html(JSON.stringify(defaults[protocol][target], null, 2));
- })
- });
- </script>
-[% END %]
-
-[% INCLUDE 'intranet-bottom.inc' %]
--- /dev/null
+[% USE raw %]
+[% USE Asset %]
+[% USE Branches %]
+[% USE Categories %]
+[% SET footerjs = 1 %]
+[% INCLUDE 'doc-head-open.inc' %]
+<title>
+ [% IF op == 'add_form' %]
+ New identity provider domain › [% ELSIF op == 'edit_form' %]
+ Edit identity provider domain › [% END %]
+
+ Identity providers › Administration › Koha
+</title>
+[% INCLUDE 'doc-head-close.inc' %]
+</head>
+
+<body id="admin_identity_provider_domains" class="admin">
+[% INCLUDE 'header.inc' %]
+[% INCLUDE 'prefs-admin-search.inc' %]
+
+<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
+ <ol>
+ <li>
+ <a href="/cgi-bin/koha/mainpage.pl">Home</a>
+ </li>
+ <li>
+ <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
+ </li>
+
+ <li>
+ <a href="/cgi-bin/koha/admin/identity_providers.pl">Identity providers</a>
+ </li>
+
+ [% IF op == 'add_form' %]
+ <li>
+ <a href="/cgi-bin/koha/admin/identity_providers.pl?domain_ops=1&identity_provider_id=[%- identity_provider_id | uri -%]">Domains for [%- identity_provider_name | html -%]</a>
+ </li>
+ <li>
+ <a href="#" aria-current="page">
+ New Domain
+ </a>
+ </li>
+
+ [% ELSIF op == 'edit_form' %]
+ <li>
+ <a href="/cgi-bin/koha/admin/identity_providers.pl?domain_ops=1&identity_provider_id=[%- identity_provider_id | uri -%]">Domains for [%- identity_provider_name | html -%]</a>
+ </li>
+ <li>
+ <a href="#" aria-current="page">
+ Edit Domain
+ </a>
+ </li>
+
+ [% ELSE %]
+ <li>
+ <a href="#" aria-current="page">
+ Domains for [%- identity_provider_code | html -%]
+ </a>
+ </li>
+ [% END %]
+ </ol>
+</nav>
+
+<div class="main container-fluid">
+ <div class="row">
+ <div class="col-sm-10 col-sm-push-2">
+ <main>
+
+[% FOREACH m IN messages %]
+ <div class="dialog [% m.type | html %]" id="identity_provider_domain_action_result_dialog">
+ [% SWITCH m.code %]
+ [% CASE 'error_on_update' %]
+ <span>An error occurred trying to open the identity provider domain for editing. The passed id is invalid.</span>
+ [% CASE 'error_on_insert' %]
+ <span>An error occurred when adding a new identity provider domain.</span>
+ [% CASE 'success_on_update' %]
+ <span>Identity provider domain updated successfully.</span>
+ [% CASE 'success_on_insert' %]
+ <span>Identity provider domain added successfully.</span>
+ [% CASE %]
+ <span>[% m.code | html %]</span>
+ [% END %]
+ </div>
+[% END %]
+
+ <div class="dialog message" id="identity_provider_domain_delete_success" style="display: none;"></div>
+ <div class="dialog alert" id="identity_provider_domain_delete_error" style="display: none;"></div>
+
+[% IF op == 'add_form' %]
+ <h1>New identity provider domain</h1>
+ <form action="/cgi-bin/koha/admin/identity_providers.pl" id="add" name="add" class="validated" method="post">
+ <input type="hidden" name="op" value="add" />
+ <input type="hidden" name="domain_ops" value="1" />
+ <input type="hidden" name="identity_provider_id" value="[%- identity_provider_id | html -%]" />
+ <fieldset class="rows">
+ <ol>
+ <li>
+ <label for="domain">Domain: </label>
+ <input type="text" name="domain" id="domain" size="60" />
+ </li>
+ </ol>
+ </fieldset>
+
+ <fieldset class="rows">
+ <ol>
+ <li>
+ <label for="update_on_auth">Update on login: </label>
+ <select name="update_on_auth" id="update_on_auth">
+ <option value="1">Update</option>
+ <option value="0" selected="selected">Don't update</option>
+ </select>
+ <span>user data on login</span>
+ </li>
+ <li>
+ <label for="auto_register">Auto register: </label>
+ <select name="auto_register" id="auto_register">
+ <option value="1">Allow</option>
+ <option value="0" selected="selected">Don't allow</option>
+ </select>
+ <span>users to auto register on login</span>
+ </li>
+ <li>
+ <label for="default_library_id">Default library: </label>
+ <select id="default_library_id" name="default_library_id">
+ [% PROCESS options_for_libraries libraries => Branches.all( unfiltered => 1, do_not_select_my_library => 1 ) %]
+ </select>
+ </li>
+ <li>
+ <label for="default_category_id">Default category: </label>
+ [% SET categories = Categories.all() %]
+ <select name="default_category_id" id="default_category_id">
+ [% FOREACH category IN categories %]
+ <option value="[% category.categorycode | html %]">[% category.description | html %]</option>
+ [% END %]
+ </select>
+ </li>
+ <li>
+ <label for="allow_opac">Allow opac: </label>
+ <select name="allow_opac" id="allow_opac">
+ <option value="1" selected="selected">Allow</option>
+ <option value="0">Don't allow</option>
+ </select>
+ <span>opac users of this domain to login with this identity provider</span>
+ </li>
+ <li>
+ <label for="allow_opac">Allow staff: </label>
+ <select name="allow_staff" id="allow_staff">
+ <option value="1" selected="selected">Allow</option>
+ <option value="0">Don't allow</option>
+ </select>
+ <span>of this domain </span>
+ </li>
+ </ol>
+ </fieldset>
+ <fieldset class="action">
+ <input type="submit" value="Submit" />
+ <a class="cancel" href="/cgi-bin/koha/admin/identity_providers.pl?domain_ops=1&identity_provider_id=[%- identity_provider_id | html -%]">Cancel</a>
+ </fieldset>
+ </form>
+[% END %]
+
+[% IF op == 'edit_form' %]
+ <h1>Edit identity provider domain</h1>
+ <form action="/cgi-bin/koha/admin/identity_providers.pl" id="edit_save" name="edit_save" class="validated" method="post">
+ <input type="hidden" name="op" value="edit_save" />
+ <input type="hidden" name="domain_ops" value="1" />
+ <input type="hidden" name="identity_provider_id" value="[%- identity_provider_id | html -%]" />
+ <input type="hidden" name="identity_provider_domain_id" value="[%- identity_provider_domain.identity_provider_domain_id | html -%]" />
+ <fieldset class="rows">
+ <ol>
+ <li>
+ <label for="domain">Domain: </label>
+ <input type="text" name="domain" id="domain" size="60" value="[%- identity_provider_domain.domain | html -%]"/>
+ </li>
+ </ol>
+ </fieldset>
+
+ <fieldset class="rows">
+ <ol>
+ <li>
+ <label for="update_on_auth">Update on login: </label>
+ <select name="update_on_auth" id="update_on_auth">
+ [% IF identity_provider_domain.update_on_auth == "1" %]
+ <option value="1" selected="selected">Update</option>
+ <option value="0">Don't update</option>
+ [% ELSE %]
+ <option value="1">Update</option>
+ <option value="0" selected="selected">Don't update</option>
+ [% END %]
+ </select>
+ <span>user data on login</span>
+ </li>
+ <li>
+ <label for="auto_register">Auto register: </label>
+ <select name="auto_register" id="auto_register">
+ [% IF identity_provider_domain.auto_register == "1" %]
+ <option value="1" selected="selected">Allow</option>
+ <option value="0">Don't allow</option>
+ [% ELSE %]
+ <option value="1">Allow</option>
+ <option value="0" selected="selected">Don't allow</option>
+ [% END %]
+ </select>
+ <span>users to auto register on login</span>
+ </li>
+ <li>
+ <label for="default_library_id">Default library: </label>
+ <select id="default_library_id" name="default_library_id">
+ [% PROCESS options_for_libraries libraries => Branches.all( selected => identity_provider_domain.default_library_id, unfiltered => 1, do_not_select_my_library => 1 ) %]
+ </select>
+ </li>
+ <li>
+ <label for="default_category_id">Default category: </label>
+ [% SET categories = Categories.all() %]
+ <select name="default_category_id" id="default_category_id">
+ [% FOREACH category IN categories %]
+ [% IF category.categorycode == identity_provider_domain.default_category_id %]
+ <option value="[% category.categorycode | html %]" selected="selected">[% category.description | html %]</option>
+ [% ELSE %]
+ <option value="[% category.categorycode | html %]">[% category.description | html %]</option>
+ [% END %]
+ [% END %]
+ </select>
+ </li>
+ <li>
+ <label for="allow_opac">Allow opac: </label>
+ <select name="allow_opac" id="allow_opac">
+ [% IF identity_provider_domain.allow_opac == "1" %]
+ <option value="1" selected="selected">Allow</option>
+ <option value="0">Don't allow</option>
+ [% ELSE %]
+ <option value="1">Allow</option>
+ <option value="0" selected="selected">Don't allow</option>
+ [% END %]
+ </select>
+ <span>opac users of this domain to login with this identity provider</span>
+ </li>
+ <li>
+ <label for="allow_opac">Allow staff: </label>
+ <select name="allow_staff" id="allow_staff">
+ [% IF identity_provider_domain.allow_staff == "1" %]
+ <option value="1" selected="selected">Allow</option>
+ <option value="0">Don't allow</option>
+ [% ELSE %]
+ <option value="1">Allow</option>
+ <option value="0" selected="selected">Don't allow</option>
+ [% END %]
+ </select>
+ <span>staff users of this domain to login with this identity provider</span>
+ </li>
+ </ol>
+ </fieldset>
+ <fieldset class="action">
+ <input type="submit" value="Submit" />
+ <a class="cancel" href="/cgi-bin/koha/admin/identity_providers.pl?domain_ops=1&identity_provider_id=[%- identity_provider_id | html -%]">Cancel</a>
+ </fieldset>
+ </form>
+[% END %]
+
+[% IF op == 'list' %]
+
+ <div id="toolbar" class="btn-toolbar">
+ <a class="btn btn-default" id="new_identity_provider_domain" href="/cgi-bin/koha/admin/identity_providers.pl?domain_ops=1&identity_provider_id=[%- identity_provider_id | html -%]&op=add_form"><i class="fa fa-plus"></i> New identity provider domain</a>
+ </div>
+
+ <h1>Identity provider domains</h1>
+
+ <table id="identity_provider_domains">
+ <thead>
+ <tr>
+ <th>Domain</th>
+ <th>Update on login</th>
+ <th>Auto register</th>
+ <th>Default library</th>
+ <th>Default category</th>
+ <th>Allow opac</th>
+ <th>Allow staff</th>
+ <th data-class-name="actions noExport">Actions</th>
+ </tr>
+ </thead>
+ </table>
+[% END %]
+
+ <div id="delete_confirm_modal" class="modal" tabindex="-1" role="dialog" aria-labelledby="delete_confirm_modal_label" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ă—</button>
+ <h3 id="delete_confirm_modal_label">Delete identity provider domain</h3>
+ </div>
+ <div class="modal-body">
+ <div id="delete_confirm_dialog"></div>
+ </div>
+ <div class="modal-footer">
+ <a href="#" class="btn btn-default" id="delete_confirm_modal_button" role="button" data-toggle="modal">Delete</a>
+ <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
+ </div>
+ </div> <!-- /.modal-content -->
+ </div> <!-- /.modal-dialog -->
+ </div> <!-- #delete_confirm_modal -->
+
+ </main>
+ </div> <!-- /.col-sm-10.col-sm-push-2 -->
+
+ <div class="col-sm-2 col-sm-pull-10">
+ <aside>
+ [% INCLUDE 'admin-menu.inc' %]
+ </aside>
+ </div> <!-- /.col-sm-2.col-sm-pull-10 -->
+ </div> <!-- /.row -->
+
+
+[% MACRO jsinclude BLOCK %]
+ [% Asset.js("js/admin-menu.js") | $raw %]
+ [% INCLUDE 'datatables.inc' %]
+ <script>
+ $(document).ready(function() {
+
+ var identity_provider_domains_url = '/api/v1/auth/identity_providers/[%- identity_provider_id | html -%]/domains';
+ [% SET categories = Categories.all() %]
+ var categories = {
+ [% FOREACH category IN categories %]
+ "[% category.categorycode | html %]": "[% category.description | html %]",
+ [% END %]
+ };
+ [% SET libraries = Branches.all() %]
+ var libraries = {
+ [% FOREACH library IN libraries %]
+ "[% library.branchcode | html %]": "[% library.branchname | html %]",
+ [% END %]
+ };
+ window.identity_provider_domains = $("#identity_provider_domains").kohaTable({
+ "ajax": {
+ "url": identity_provider_domains_url
+ },
+ 'language': {
+ 'emptyTable': '<div class="dialog message">'+_("There are no identity provider domains defined.")+'</div>'
+ },
+ "columnDefs": [ {
+ "targets": [1],
+ "render": function (data, type, row, meta) {
+ if ( type == 'display' ) {
+ if ( data != null ) {
+ return data.escapeHtml();
+ }
+ else {
+ return "";
+ }
+ }
+ return data;
+ }
+ } ],
+ "columns": [
+ {
+ "data": "domain",
+ "searchable": true,
+ "orderable": true,
+ "render": function(data, type, row, meta) {
+ if ( data != null ) {
+ return data.escapeHtml();
+ }
+ else {
+ return "*";
+ }
+ }
+ },
+ {
+ "data": function( row, type, val, meta ) {
+ if (row.update_on_auth) {
+ return _("Yes");
+ } else {
+ return _("No");
+ }
+ },
+ "searchable": true,
+ "orderable": true
+ },
+ {
+ "data": function( row, type, val, meta ) {
+ if (row.auto_register) {
+ return _("Yes");
+ } else {
+ return _("No");
+ }
+ },
+ "searchable": true,
+ "orderable": true
+ },
+ {
+ "data": function( row, type, val, meta ) {
+ return libraries[row.default_library_id] || "";
+ },
+ "searchable": true,
+ "orderable": true
+ },
+ {
+ "data": function( row, type, val, meta ) {
+ return categories[row.default_category_id] || "";
+ },
+ "searchable": true,
+ "orderable": true
+ },
+ {
+ "data": function( row, type, val, meta ) {
+ if (row.allow_opac) {
+ return _("Yes");
+ } else {
+ return _("No");
+ }
+ },
+ "searchable": true,
+ "orderable": true
+ },
+ {
+ "data": function( row, type, val, meta ) {
+ if (row.allow_staff) {
+ return _("Yes");
+ } else {
+ return _("No");
+ }
+ },
+ "searchable": true,
+ "orderable": true
+ },
+ {
+ "data": function( row, type, val, meta ) {
+ var result = '<a class="btn btn-default btn-xs" role="button" href="/cgi-bin/koha/admin/identity_providers.pl?domain_ops=1&identity_provider_id=[%- identity_provider_id | html -%]&op=edit_form&identity_provider_domain_id='+ encodeURIComponent(row.identity_provider_domain_id) +'"><i class="fa fa-pencil" aria-hidden="true"></i> '+_("Edit")+'</a>'+"\n";
+ result += '<a class="btn btn-default btn-xs delete_identity_provider_domain" role="button" href="#" data-toggle="modal" data-target="#delete_confirm_modal" data-auth-provider-domain-id="'+ encodeURIComponent(row.identity_provider_domain_id) +'" data-auth-provider-domain="'+ encodeURIComponent((row.domain || '').escapeHtml()) +'"><i class="fa fa-trash" aria-hidden="true"></i> '+_("Delete")+'</a>';
+ return result;
+ },
+ "searchable": false,
+ "orderable": false
+ }
+ ],
+ createdRow: function (row, data, dataIndex) {
+ if ( data.debug ) {
+ $(row).addClass('debug');
+ }
+ },
+ });
+
+ $('#identity_provider_domains').on( "click", '.delete_identity_provider_domain', function () {
+ var identity_provider_domain_id = $(this).data('auth-provider-domain-id');
+ var identity_provider_domain = decodeURIComponent($(this).data('auth-provider-domain'));
+
+ $("#delete_confirm_dialog").html(
+ _("You are about to delete the '%s' identity provider domain.").format(identity_provider_domain)
+ );
+ $("#delete_confirm_modal_button").data('auth-provider-domain-id', identity_provider_domain_id);
+ $("#delete_confirm_modal_button").data('auth-provider-domain', identity_provider_domain);
+ });
+
+ $("#delete_confirm_modal_button").on( "click", function () {
+
+ var identity_provider_domain_id = $(this).data('auth-provider-domain-id');
+ var identity_provider_domain = $(this).data('auth-provider-domain');
+
+ $.ajax({
+ method: "DELETE",
+ url: identity_provider_domains_url+"/"+identity_provider_domain_id
+ }).success(function() {
+ window.identity_provider_domains.api().ajax.reload(function (data) {
+ $("#smtp_action_result_dialog").hide();
+ $("#smtp_delete_success").html(_("Server '%s' deleted successfully.").format(identity_provider_domain)).show();
+ });
+ }).fail(function () {
+ $("#smtp_delete_error").html(_("Error deleting server '%s'. Check the logs.").format(identity_provider_domain)).show();
+ }).done(function () {
+ $("#delete_confirm_modal").modal('hide');
+ });
+ });
+ });
+ </script>
+[% END %]
+
+[% INCLUDE 'intranet-bottom.inc' %]
--- /dev/null
+[% USE raw %]
+[% USE Asset %]
+[% SET footerjs = 1 %]
+[% INCLUDE 'doc-head-open.inc' %]
+<title>
+ [% IF op == 'add_form' %]
+ New identity provider › [% ELSIF op == 'edit_form' %]
+ Edit identity provider › [% END %]
+
+ Identity providers › Administration › Koha
+</title>
+[% INCLUDE 'doc-head-close.inc' %]
+</head>
+
+<body id="admin_identity_providers" class="admin">
+[% INCLUDE 'header.inc' %]
+[% INCLUDE 'prefs-admin-search.inc' %]
+
+<nav id="breadcrumbs" aria-label="Breadcrumb" class="breadcrumb">
+ <ol>
+ <li>
+ <a href="/cgi-bin/koha/mainpage.pl">Home</a>
+ </li>
+ <li>
+ <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
+ </li>
+
+ [% IF op == 'add_form' %]
+ <li>
+ <a href="/cgi-bin/koha/admin/identity_providers.pl">Identity providers</a>
+ </li>
+ <li>
+ <a href="#" aria-current="page">
+ New
+ </a>
+ </li>
+
+ [% ELSIF op == 'edit_form' %]
+ <li>
+ <a href="/cgi-bin/koha/admin/identity_providers.pl">Identity providers</a>
+ </li>
+ <li>
+ <a href="#" aria-current="page">
+ Edit
+ </a>
+ </li>
+
+ [% ELSE %]
+ <li>
+ <a href="#" aria-current="page">
+ Identity providers
+ </a>
+ </li>
+ [% END %]
+ </ol>
+</nav>
+
+<div class="main container-fluid">
+ <div class="row">
+ <div class="col-sm-10 col-sm-push-2">
+ <main>
+
+[% FOREACH m IN messages %]
+ <div class="dialog [% m.type | html %]" id="identity_provider_action_result_dialog">
+ [% SWITCH m.code %]
+ [% CASE 'error_on_update' %]
+ <span>An error occurred trying to open the identity provider for editing. The passed id is invalid.</span>
+ [% CASE 'error_on_insert' %]
+ <span>An error occurred when adding a new identity provider.</span>
+ [% CASE 'success_on_update' %]
+ <span>Identity provider updated successfully.</span>
+ [% CASE 'success_on_insert' %]
+ <span>Identity provider added successfully.</span>
+ [% CASE %]
+ <span>[% m.code | html %]</span>
+ [% END %]
+ </div>
+[% END %]
+
+ <div class="dialog message" id="identity_provider_delete_success" style="display: none;"></div>
+ <div class="dialog alert" id="identity_provider_delete_error" style="display: none;"></div>
+
+[% IF op == 'add_form' %]
+ <h1>New identity provider</h1>
+ <form action="/cgi-bin/koha/admin/identity_providers.pl" id="add" name="add" class="validated" method="post">
+ <input type="hidden" name="op" value="add" />
+ <fieldset class="rows">
+ <ol>
+ <li>
+ <label for="code" class="required">Code: </label>
+ <input type="text" name="code" id="code" size="60" class="required" required="required" />
+ <span class="required">Required</span>
+ </li>
+ <li>
+ <label for="description" class="required">Description: </label>
+ <input type="text" name="description" id="description" size="60" class="required" required="required" />
+ <span class="required">Required</span>
+ </li>
+ <li>
+ <label for="protocol">Protocol: </label>
+ <select name="protocol" id="protocol">
+ <option value="OAuth">OAuth</option>
+ <option value="OIDC">OIDC</option>
+ <!-- Not implemented yet
+ <option value="LDAP">LDAP</option>
+ <option value="CAS">CAS</option>
+ -->
+ </select>
+ </li>
+ </ol>
+ </fieldset>
+
+ <fieldset class="rows">
+ <ol>
+ <li>
+ <div>
+ <label for="config" class="required json">Configuration: </label>
+ <textarea name="config" id="config" class="required"></textarea>
+ <span class="required">Required</span>
+ </div>
+ <div>
+ <label></label>
+ <button class="btn btn-ligth defaults" data-default-target="config" id="default-config">Add default OAuth configuration</button>
+ </div>
+ </li>
+ <li>
+ <div>
+ <label for="mapping" class="required json">Mapping: </label>
+ <textarea name="mapping" id="mapping" class="required"></textarea>
+ <span class="required">Required</span>
+ </div>
+ <div>
+ <label></label>
+ <button class="btn btn-ligth defaults" data-default-target="mapping" id="default-mapping">Add default OAuth mapping</button>
+ </div>
+ </li>
+ <li>
+ <label for="matchpoint" class="required">Matchpoint: </label>
+ <select name="matchpoint" id="matchpoint" class="required">
+ <option value="email">Email</option>
+ <option value="userid">User id</option>
+ <option value="cardnumber">Card number</option>
+ </select>
+ <span class="required">Required</span>
+ </li>
+ <li>
+ <label for="icon_url">Icon URL: </label>
+ <input type="text" name="icon_url" id="icon_url" size="60" />
+ </li>
+ </ol>
+ </fieldset>
+ <fieldset class="action">
+ <input type="submit" value="Submit" />
+ <a class="cancel" href="/cgi-bin/koha/admin/identity_providers.pl">Cancel</a>
+ </fieldset>
+ </form>
+[% END %]
+
+[% IF op == 'edit_form' %]
+ <h1>Edit identity provider</h1>
+ <form action="/cgi-bin/koha/admin/identity_providers.pl" id="edit_save" name="edit_save" class="validated" method="post">
+ <input type="hidden" name="op" value="edit_save" />
+ <input type="hidden" name="identity_provider_id" value="[%- identity_provider.identity_provider_id | html -%]" />
+ <fieldset class="rows">
+ <ol>
+ <li>
+ <label for="code" class="required">Code: </label>
+ <input type="text" name="code" id="code" size="60" class="required" required="required" value="[%- identity_provider.code | html -%]"/>
+ <span class="required">Required</span>
+ </li>
+ <li>
+ <label for="description" class="required">Description: </label>
+ <input type="text" name="description" id="description" size="60" class="required" required="required" value="[%- identity_provider.description | html -%]"/>
+ <span class="required">Required</span>
+ </li>
+ <li>
+ <label for="protocol">Protocol: </label>
+ <select name="protocol" id="protocol">
+ [% IF identity_provider.protocol == 'OAuth' %]
+ <option value="OAuth" selected="selected">OAuth</option>
+ <option value="OIDC">OIDC</option>
+ <!-- Not implemented yet
+ <option value="LDAP">LDAP</option>
+ <option value="CAS">CAS</option>
+ -->
+ [% ELSE %]
+ <option value="OAuth">OAuth</option>
+ <option value="OIDC" selected="selected">OIDC</option>
+ <!-- Not implemented yet
+ <option value="LDAP">LDAP</option>
+ <option value="CAS">CAS</option>
+ -->
+ [% END %]
+ </select>
+ </li>
+ </ol>
+ </fieldset>
+
+ <fieldset class="rows">
+ <ol>
+ <li>
+ <div>
+ <label for="config" class="required json">Configuration: </label>
+ <textarea name="config" id="config" class="required">[%- identity_provider.config | html -%]</textarea>
+ <span class="required">Required</span>
+ </div>
+ <div>
+ <label></label>
+ <button class="btn btn-ligth defaults" data-default-target="config" id="default-config">Add default [%- identity_provider.protocol | html -%] configuration</button>
+ </div>
+ </li>
+ <li>
+ <div>
+ <label for="mapping" class="required json">Mapping: </label>
+ <textarea name="mapping" id="mapping" class="required">[%- identity_provider.mapping | html -%]</textarea>
+ <span class="required">Required</span>
+ </div>
+ <div>
+ <label></label>
+ <button class="btn btn-ligth defaults" data-default-target="mapping" id="default-mapping">Add default [%- identity_provider.protocol | html -%] mapping</button>
+ </div>
+ </li>
+ <li>
+ <label for="matchpoint" class="required">matchpoint: </label>
+ <select name="matchpoint" id="matchpoint" class="required">
+ [%- IF identity_provider.matchpoint == 'email' -%]
+ <option value="email" selected="selected">Email</option>
+ [%- ELSE -%]
+ <option value="email">Email</option>
+ [%- END -%]
+ [%- IF identity_provider.matchpoint == 'userid' -%]
+ <option value="userid" selected="selected">User id</option>
+ [%- ELSE -%]
+ <option value="userid">User id</option>
+ [%- END -%]
+ [%- IF identity_provider.matchpoint == 'cardnumber' -%]
+ <option value="cardnumber" selected="selected">Card number</option>
+ [%- ELSE -%]
+ <option value="cardnumber">Card number</option>
+ [%- END -%]
+ </select>
+ <span class="required">Required</span>
+ </li>
+ <li>
+ <label for="icon_url">Icon URL: </label>
+ <input type="text" name="icon_url" id="icon_url" size="60" value="[%- identity_provider.icon_url | html -%]"/>
+ </li>
+ </ol>
+ </fieldset>
+ <fieldset class="action">
+ <input type="submit" value="Submit" />
+ <a class="cancel" href="/cgi-bin/koha/admin/identity_providers.pl">Cancel</a>
+ </fieldset>
+ </form>
+[% END %]
+
+[% IF op == 'list' %]
+
+ <div id="toolbar" class="btn-toolbar">
+ <a class="btn btn-default" id="new_identity_provider" href="/cgi-bin/koha/admin/identity_providers.pl?op=add_form"><i class="fa fa-plus"></i> New identity provider</a>
+ </div>
+
+ <h1>Identity providers</h1>
+
+ <table id="identity_providers">
+ <thead>
+ <tr>
+ <th>Code</th>
+ <th>Description</th>
+ <th>Protocol</th>
+ <th data-class-name="actions noExport">Actions</th>
+ </tr>
+ </thead>
+ </table>
+[% END %]
+
+ <div id="delete_confirm_modal" class="modal" tabindex="-1" role="dialog" aria-labelledby="delete_confirm_modal_label" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">Ă—</button>
+ <h3 id="delete_confirm_modal_label">Delete identity provider</h3>
+ </div>
+ <div class="modal-body">
+ <div id="delete_confirm_dialog"></div>
+ </div>
+ <div class="modal-footer">
+ <a href="#" class="btn btn-default" id="delete_confirm_modal_button" role="button" data-toggle="modal">Delete</a>
+ <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
+ </div>
+ </div> <!-- /.modal-content -->
+ </div> <!-- /.modal-dialog -->
+ </div> <!-- #delete_confirm_modal -->
+
+ </main>
+ </div> <!-- /.col-sm-10.col-sm-push-2 -->
+
+ <div class="col-sm-2 col-sm-pull-10">
+ <aside>
+ [% INCLUDE 'admin-menu.inc' %]
+ </aside>
+ </div> <!-- /.col-sm-2.col-sm-pull-10 -->
+ </div> <!-- /.row -->
+
+
+[% MACRO jsinclude BLOCK %]
+ [% Asset.js("js/admin-menu.js") | $raw %]
+ [% INCLUDE 'datatables.inc' %]
+ <script>
+ $(document).ready(function() {
+
+ var identity_providers_url = '/api/v1/auth/identity_providers';
+ window.identity_providers = $("#identity_providers").kohaTable({
+ "ajax": {
+ "url": identity_providers_url
+ },
+ 'language': {
+ 'emptyTable': '<div class="dialog message">'+_("There are no identity providers defined.")+'</div>'
+ },
+ "columnDefs": [ {
+ "targets": [0,1,2],
+ "render": function (data, type, row, meta) {
+ if ( type == 'display' ) {
+ if ( data != null ) {
+ return data.escapeHtml();
+ }
+ else {
+ return "Default";
+ }
+ }
+ return data;
+ }
+ } ],
+ "columns": [
+ {
+ "data": "code",
+ "searchable": true,
+ "orderable": true
+ },
+ {
+ "data": "description",
+ "searchable": true,
+ "orderable": true
+ },
+ {
+ "data": "protocol",
+ "searchable": true,
+ "orderable": true
+ },
+ {
+ "data": function( row, type, val, meta ) {
+ var result = '<a class="btn btn-default btn-xs" role="button" href="/cgi-bin/koha/admin/identity_providers.pl?op=edit_form&identity_provider_id='+ encodeURIComponent(row.identity_provider_id) +'"><i class="fa fa-pencil" aria-hidden="true"></i> '+_("Edit")+'</a>'+"\n";
+ result += '<a class="btn btn-default btn-xs delete_identity_provider" role="button" href="#" data-toggle="modal" data-target="#delete_confirm_modal" data-auth-provider-id="'+ encodeURIComponent(row.identity_provider_id) +'" data-auth-provider-code="'+ encodeURIComponent(row.code.escapeHtml()) +'"><i class="fa fa-trash" aria-hidden="true"></i> '+_("Delete")+'</a>'+"\n";
+ result += '<a class="btn btn-default btn-xs edit_domains" role="button" href="/cgi-bin/koha/admin/identity_providers.pl?domain_ops=1&identity_provider_id='+ encodeURIComponent(row.identity_provider_id) +'"><i class="fa fa-cog" aria-hidden="true"></i> '+_("Manage Domains")+'</a>';
+ return result;
+ },
+ "searchable": false,
+ "orderable": false
+ }
+ ],
+ createdRow: function (row, data, dataIndex) {
+ if ( data.debug ) {
+ $(row).addClass('debug');
+ }
+ },
+ });
+
+ $('#identity_providers').on( "click", '.delete_identity_provider', function () {
+ var identity_provider_id = $(this).data('auth-provider-id');
+ var identity_provider_code = decodeURIComponent($(this).data('auth-provider-code'));
+
+ $("#delete_confirm_dialog").html(
+ _("You are about to delete the '%s' identity provider.").format(identity_provider_code)
+ );
+ $("#delete_confirm_modal_button").data('auth-provider-id', identity_provider_id);
+ $("#delete_confirm_modal_button").data('auth-provider-code', identity_provider_code);
+ });
+
+ $("#delete_confirm_modal_button").on( "click", function () {
+
+ var identity_provider_id = $(this).data('auth-provider-id');
+ var identity_provider_code = $(this).data('auth-provider-code');
+
+ $.ajax({
+ method: "DELETE",
+ url: identity_providers_url+"/"+identity_provider_id
+ }).success(function() {
+ window.identity_providers.api().ajax.reload(function (data) {
+ $("#identity_provider_action_result_dialog").hide();
+ $("#identity_provider_delete_success").html(_("Server '%s' deleted successfully.").format(identity_provider_code)).show();
+ });
+ }).fail(function () {
+ $("#identity_provider_delete_error").html(_("Error deleting server '%s'. Check the logs.").format(identity_provider_code)).show();
+ }).done(function () {
+ $("#delete_confirm_modal").modal('hide');
+ });
+ });
+
+ $.validator.addMethod('json', function(value, element) {
+ if (this.optional(element)) return true;
+ try {
+ JSON.parse(value)
+ } catch (error) {
+ return false;
+ }
+ return true;
+ }, _('Not a valid JSON'));
+
+ $('#config, #mapping').each(function() {
+ $(this).rules('add', {
+ required: true,
+ json: true
+ });
+ });
+
+ var defaults = {
+ OIDC: {
+ config: {
+ key: "<enter client id>",
+ secret: "<enter client secret>",
+ well_known_url: "<enter openid configuration endpoint>",
+ scope: "openid email"
+ },
+ mapping: {
+ email: "email",
+ given_name: "firstname",
+ family_name: "surname"
+ }
+ },
+ OAuth: {
+ config: {
+ key: "<enter client id>",
+ secret: "<enter client secret>",
+ authorize_url: "<enter authorization endpoint>",
+ token_url: "<enter token endpoint>",
+ userinfo_url: "<enter user info endpoint (optional)>",
+ scope: "email"
+ },
+ mapping: {
+ email: "email",
+ firstname: "given_name",
+ surname: "family_name"
+ }
+ }
+ };
+
+ $('#protocol').on('change', function() {
+ var protocol = $(this).val();
+ $('#default-config').html(_('Add default %s configuration').format(protocol));
+ $('#default-mapping').html(_('Add default %s mapping').format(protocol));
+ });
+
+ $('button.defaults').on('click', function(event) {
+ event.preventDefault();
+ var target = $(this).data('defaultTarget');
+ if($('#'+target).html() !== '' && !confirm(_('Are you sure you want to replace current %s contents?').format(target))) {
+ return;
+ }
+ var protocol = $('#protocol').val();
+ $('#'+target).html(JSON.stringify(defaults[protocol][target], null, 2));
+ })
+ });
+ </script>
+[% END %]
+
+[% INCLUDE 'intranet-bottom.inc' %]
[% IF !TwoFA_prompt && !TwoFA_setup && !Koha.Preference('staffShibOnly') %]
<!-- login prompt time-->
- [% SET auth_providers = AuthClient.get_providers('staff') %]
- [% IF ( ! auth_providers.empty ) %]
- [% FOREACH provider IN auth_providers %]
+ [% SET identity_providers = AuthClient.get_providers('staff') %]
+ [% IF ( ! identity_providers.empty ) %]
+ [% FOREACH provider IN identity_providers %]
<p class="clearfix">
<a href="[% provider.url | url %]" class="btn btn-light col-xs-12" id="provider_[% provider.code | html %]">
[% IF provider.icon_url %]
[% END %]
<hr/>
<p>If you do not have an external account, but do have a local account, you can still log in: </p>
- [% END # /IF auth_providers.size %]
+ [% END # /IF identity_providers.size %]
<form action="[% script_name | html %]" method="post" name="loginform" id="loginform">
<input type="hidden" name="koha_login_context" value="intranet" />
[% END %]
[% END %]
[% UNLESS Koha.Preference('opacShibOnly') %]
- [% SET auth_providers = AuthClient.get_providers('opac') %]
- [% IF ( ! auth_providers.empty ) %]
- [% FOREACH provider IN auth_providers %]
+ [% SET identity_providers = AuthClient.get_providers('opac') %]
+ [% IF ( ! identity_providers.empty ) %]
+ [% FOREACH provider IN identity_providers %]
<p class="clearfix">
<a href="[% provider.url | url %]" class="btn btn-light col-md-12" id="provider_[% provider.code | html %]">
[% IF provider.icon_url %]
[% END %]
<hr/>
<p>If you do not have an external account, but do have a local account, you can still log in: </p>
- [% END # /IF auth_providers.size %]
+ [% END # /IF identity_providers.size %]
<input type="hidden" name="koha_login_context" value="opac" />
<fieldset class="brief">
<div class="local-login">
[% END # / IF casAuthentication %]
- [% SET auth_providers = AuthClient.get_providers('opac') %]
- [% IF ( ! auth_providers.empty ) %]
- [% FOREACH provider IN auth_providers %]
+ [% SET identity_providers = AuthClient.get_providers('opac') %]
+ [% IF ( ! identity_providers.empty ) %]
+ [% FOREACH provider IN identity_providers %]
<p class="clearfix">
<a href="[% provider.url | url %]" class="btn btn-light col-md-12" id="provider_[% provider.code | html %]">
[% IF provider.icon_url %]
[% END %]
<hr/>
<p>If you do not have an external account, but do have a local account, you can still log in: </p>
- [% END # /IF auth_providers %]
+ [% END # /IF identity_providers %]
[% IF ( Koha.Preference('GoogleOpenIDConnect') == 1 ) %]
[% IF ( invalidGoogleOpenIDConnectLogin ) %]
<a href="/cgi-bin/koha/svc/auth/googleopenidconnect" class="btn btn-light" id="openid_connect"><i class="fa fa-google" aria-hidden="true"></i> Log in with Google</a>
<p>If you do not have a Google account, but do have a local account, you can still log in: </p>
[% END # /IF GoogleOpenIDConnect %]
- [% SET auth_providers = AuthClient.get_providers('opac') %]
- [% IF ( ! auth_providers.empty ) %]
- [% FOREACH provider IN auth_providers %]
+ [% SET identity_providers = AuthClient.get_providers('opac') %]
+ [% IF ( ! identity_providers.empty ) %]
+ [% FOREACH provider IN identity_providers %]
<p class="clearfix">
<a href="[% provider.url | url %]" class="btn btn-light col-md-12" id="provider_[% provider.code | html %]">
[% IF provider.icon_url %]
[% END %]
<hr/>
<p>If you do not have an external account, but do have a local account, you can still log in: </p>
- [% END # /IF auth_providers.size %]
+ [% END # /IF identity_providers.size %]
<div class="local-login">
<label for="userid">Login:</label>
<input class="form-control" type="text" id="userid" name="userid" autocomplete="off" />
--- /dev/null
+#!/usr/bin/perl
+
+# Copyright 2022 Theke Solutions
+#
+# 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 Test::More tests => 4;
+
+use Test::MockModule;
+use Test::Exception;
+
+use JSON qw(encode_json);
+use MIME::Base64 qw{ encode_base64url };
+
+use Koha::Auth::Client;
+use Koha::Auth::Client::OAuth;
+use Koha::Patrons;
+
+use t::lib::TestBuilder;
+use t::lib::Mocks;
+
+my $schema = Koha::Database->new->schema;
+my $builder = t::lib::TestBuilder->new;
+
+subtest 'get_user() tests' => sub {
+ plan tests => 4;
+
+ $schema->storage->txn_begin;
+
+ my $client = Koha::Auth::Client::OAuth->new;
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { matchpoint => 'email' } } );
+ my $domain = $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id, domain => '', allow_opac => 1, allow_staff => 0 } } );
+ my $patron = $builder->build_object( { class => 'Koha::Patrons', value => { email => 'patron@test.com' } } );
+ my $mapping = {
+ email => 'electronic_mail',
+ firstname => 'given_name',
+ surname => 'family_name'
+ };
+ $provider->set_mapping($mapping)->store;
+
+ my $id_token = 'header.'.encode_base64url(encode_json({
+ electronic_mail => 'patron@test.com',
+ given_name => 'test name'
+ })).'.footer';
+
+ my $data = {
+ id_token => $id_token
+ };
+
+ my ($resolved_patron, $mapped_data, $resolved_domain) = $client->get_user({ provider => $provider->code, data => $data, interface => 'opac' });
+ is_deeply( $resolved_patron->to_api, $patron->to_api, 'Patron correctly retrieved' );
+ is( $mapped_data->{firstname}, 'test name', 'Data mapped correctly' );
+ is( $mapped_data->{surname}, undef, 'No surname mapped');
+ is( $domain->identity_provider_domain_id, $resolved_domain->identity_provider_domain_id, 'Is the same domain');
+
+ $schema->storage->txn_rollback;
+
+};
+
+subtest 'get_valid_domain_config() tests' => sub {
+ plan tests => 10;
+
+ $schema->storage->txn_begin;
+
+ my $client = Koha::Auth::Client->new;
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { matchpoint => 'email' } } );
+ my $domain1 = $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id, domain => '', allow_opac => 0, allow_staff => 0 } } );
+ my $domain2 = $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id, domain => '*library.com', allow_opac => 1, allow_staff => 0 } } );
+ my $domain3 = $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id, domain => '*.library.com', allow_opac => 1, allow_staff => 0 } } );
+ my $domain4 = $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id, domain => 'student.library.com', allow_opac => 1, allow_staff => 0 } } );
+ my $domain5 = $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id, domain => 'staff.library.com', allow_opac => 1, allow_staff => 1 } } );
+
+ my $retrieved_domain;
+
+ # Test @gmail.com
+ $retrieved_domain = $client->get_valid_domain_config({ provider => $provider, email => 'user@gmail.com', interface => 'opac'});
+ is($retrieved_domain, undef, 'gmail user cannot enter opac');
+ $retrieved_domain = $client->get_valid_domain_config({ provider => $provider, email => 'user@gmail.com', interface => 'staff'});
+ is($retrieved_domain, undef, 'gmail user cannot enter staff');
+
+ # Test @otherlibrary.com
+ $retrieved_domain = $client->get_valid_domain_config({ provider => $provider, email => 'user@otherlibrary.com', interface => 'opac'});
+ is($retrieved_domain->identity_provider_domain_id, $domain2->identity_provider_domain_id, 'otherlibaray user can enter opac with domain2');
+ $retrieved_domain = $client->get_valid_domain_config({ provider => $provider, email => 'user@otherlibrary.com', interface => 'staff'});
+ is($retrieved_domain, undef, 'otherlibrary user cannot enter staff');
+
+ # Test @provider.library.com
+ $retrieved_domain = $client->get_valid_domain_config({ provider => $provider, email => 'user@provider.library.com', interface => 'opac'});
+ is($retrieved_domain->identity_provider_domain_id, $domain3->identity_provider_domain_id, 'provider.library user can enter opac with domain3');
+ $retrieved_domain = $client->get_valid_domain_config({ provider => $provider, email => 'user@provider.library.com', interface => 'staff'});
+ is($retrieved_domain, undef, 'provider.library user cannot enter staff');
+
+ # Test @student.library.com
+ $retrieved_domain = $client->get_valid_domain_config({ provider => $provider, email => 'user@student.library.com', interface => 'opac'});
+ is($retrieved_domain->identity_provider_domain_id, $domain4->identity_provider_domain_id, 'student.library user can enter opac with domain4');
+ $retrieved_domain = $client->get_valid_domain_config({ provider => $provider, email => 'user@student.library.com', interface => 'staff'});
+ is($retrieved_domain, undef, 'student.library user cannot enter staff');
+
+ # Test @staff.library.com
+ $retrieved_domain = $client->get_valid_domain_config({ provider => $provider, email => 'user@staff.library.com', interface => 'opac'});
+ is($retrieved_domain->identity_provider_domain_id, $domain5->identity_provider_domain_id, 'staff.library user can enter opac with domain5');
+ $retrieved_domain = $client->get_valid_domain_config({ provider => $provider, email => 'user@staff.library.com', interface => 'staff'});
+ is($retrieved_domain->identity_provider_domain_id, $domain5->identity_provider_domain_id, 'staff.library user can enter staff with domain5');
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'has_valid_domain_config() tests' => sub {
+ plan tests => 2;
+ $schema->storage->txn_begin;
+
+ my $client = Koha::Auth::Client->new;
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { matchpoint => 'email' } } );
+ my $domain1 = $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id, domain => '', allow_opac => 1, allow_staff => 0 } } );
+
+ # Test @gmail.com
+ my $retrieved_domain = $client->has_valid_domain_config({ provider => $provider, email => 'user@gmail.com', interface => 'opac'});
+ is($retrieved_domain->identity_provider_domain_id, $domain1->identity_provider_domain_id, 'gmail user can enter opac with domain1');
+ throws_ok { $client->has_valid_domain_config({ provider => $provider, email => 'user@gmail.com', interface => 'staff'}) } 'Koha::Exceptions::Auth::NoValidDomain', 'gmail user cannot enter staff';
+
+ $schema->storage->txn_rollback;
+};
+
+subtest '_traverse_hash() tests' => sub {
+ plan tests => 3;
+
+ my $client = Koha::Auth::Client->new;
+
+ my $hash = {
+ a => {
+ hash => {
+ with => 'complicated structure'
+ }
+ },
+ an => {
+ array => [
+ {
+ inside => 'a hash'
+ },
+ {
+ inside => 'second element'
+ }
+ ]
+ }
+ };
+
+ my $first_result = $client->_traverse_hash({
+ base => $hash,
+ keys => 'a.hash.with'
+ });
+ is($first_result, 'complicated structure', 'get the value whithin a hash structure');
+
+ my $second_result = $client->_traverse_hash({
+ base => $hash,
+ keys => 'an.array.0.inside'
+ });
+ is($second_result, 'a hash', 'get the value of the first element of an array within a hash structure');
+
+ my $third_result = $client->_traverse_hash({
+ base => $hash,
+ keys => 'an.array.1.inside'
+ });
+ is($third_result, 'second element', 'get the value of the second element of an array within a hash structure');
+};
\ No newline at end of file
--- /dev/null
+#!/usr/bin/perl
+
+# Copyright 2022 Theke Solutions
+#
+# 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 Test::More tests => 6;
+
+use Test::MockModule;
+use Test::Exception;
+
+use JSON qw(encode_json);
+
+use Koha::Auth::Identity::Providers;
+
+use t::lib::TestBuilder;
+use t::lib::Mocks;
+
+my $schema = Koha::Database->new->schema;
+my $builder = t::lib::TestBuilder->new;
+
+subtest 'domains() tests' => sub {
+
+ plan tests => 3;
+
+ $schema->storage->txn_begin;
+
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
+ my $domains = $provider->domains;
+
+ is( ref($domains), 'Koha::Auth::Identity::Provider::Domains', 'Type is correct' );
+ is( $domains->count, 0, 'No domains defined' );
+
+ $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id } } );
+ $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id } } );
+
+ is( $provider->domains->count, 2, 'The provider has 2 domains defined' );
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'get_config() tests' => sub {
+
+ plan tests => 2;
+
+ $schema->storage->txn_begin;
+
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { config => '{' } } );
+
+ throws_ok { $provider->get_config() }
+ 'Koha::Exceptions::Object::BadValue', 'Expected exception thrown on bad JSON';
+
+ my $config = { some => 'value', and => 'another' };
+ $provider->config( encode_json($config) )->store;
+
+ is_deeply( $provider->get_config, $config, 'Config correctly retrieved' );
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'set_config() tests' => sub {
+
+ plan tests => 3;
+
+ $schema->storage->txn_begin;
+
+ subtest 'OIDC protocol tests' => sub {
+
+ plan tests => 4;
+
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { protocol => 'OIDC' } } );
+ $provider = $provider->upgrade_class;
+
+ my $config = {
+ key => 'key',
+ secret => 'secret',
+ };
+
+ throws_ok { $provider->set_config($config) }
+ 'Koha::Exceptions::MissingParameter', 'Exception thrown on missing parameter';
+
+ 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::Identity::Provider::OIDC', 'Return type is correct' );
+
+ is_deeply( $provider->get_config, $config, 'Configuration stored correctly' );
+ };
+
+ subtest 'OAuth protocol tests' => sub {
+
+ plan tests => 4;
+
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { protocol => 'OAuth' } } );
+ $provider = $provider->upgrade_class;
+
+ my $config = {
+ key => 'key',
+ secret => 'secret',
+ token_url => 'https://koha-community.org/auth/token',
+ };
+
+ throws_ok { $provider->set_config($config) }
+ 'Koha::Exceptions::MissingParameter', 'Exception thrown on missing parameter';
+
+ 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::Identity::Provider::OAuth', 'Return type is correct' );
+
+ is_deeply( $provider->get_config, $config, 'Configuration stored correctly' );
+ };
+
+ subtest 'Unsupported protocol tests' => sub {
+
+ plan tests => 2;
+
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { protocol => 'CAS' } } );
+
+ throws_ok { $provider->set_config() }
+ 'Koha::Exception', 'Exception thrown on unsupported protocol';
+
+ like( "$@", qr/This method needs to be subclassed/, 'Message is correct' );
+ };
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'get_mapping() tests' => sub {
+
+ plan tests => 2;
+
+ $schema->storage->txn_begin;
+
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { config => '{' } } );
+
+ throws_ok { $provider->get_mapping() }
+ 'Koha::Exceptions::Object::BadValue', 'Expected exception thrown on bad JSON';
+
+ my $mapping = { some => 'value', and => 'another' };
+ $provider->mapping( encode_json($mapping) )->store;
+
+ is_deeply( $provider->get_mapping, $mapping, 'Mapping correctly retrieved' );
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'set_mapping() tests' => sub {
+
+ plan tests => 1;
+
+ $schema->storage->txn_begin;
+
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers' } );
+
+ my $mapping = { some => 'value', and => 'another' };
+ $provider->set_mapping($mapping)->store;
+
+ is_deeply( $provider->get_mapping, $mapping, 'Mapping correctly retrieved' );
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'upgrade_class() tests' => sub {
+
+ plan tests => 5;
+
+ $schema->storage->txn_begin;
+
+ my $mapping = Koha::Auth::Identity::Provider::protocol_to_class_mapping;
+ my @protocols = keys %{ $mapping };
+
+ foreach my $protocol (@protocols) {
+
+ my $provider = $builder->build_object(
+ {
+ class => 'Koha::Auth::Identity::Providers',
+ value => { protocol => $protocol },
+ }
+ );
+
+ is( ref($provider), 'Koha::Auth::Identity::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::Identity::Provider->new({ protocol => 'Invalid' });
+ throws_ok
+ { $provider->upgrade }
+ 'Koha::Exception',
+ 'Exception throw on invalid protocol';
+
+ $schema->storage->txn_rollback;
+};
+++ /dev/null
-#!/usr/bin/perl
-
-# Copyright 2022 Theke Solutions
-#
-# 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 Test::More tests => 6;
-
-use Test::MockModule;
-use Test::Exception;
-
-use JSON qw(encode_json);
-
-use Koha::Auth::Providers;
-
-use t::lib::TestBuilder;
-use t::lib::Mocks;
-
-my $schema = Koha::Database->new->schema;
-my $builder = t::lib::TestBuilder->new;
-
-subtest 'domains() tests' => sub {
-
- plan tests => 3;
-
- $schema->storage->txn_begin;
-
- my $provider = $builder->build_object( { class => 'Koha::Auth::Providers' } );
- my $domains = $provider->domains;
-
- is( ref($domains), 'Koha::Auth::Provider::Domains', 'Type is correct' );
- is( $domains->count, 0, 'No domains defined' );
-
- $builder->build_object( { class => 'Koha::Auth::Provider::Domains', value => { auth_provider_id => $provider->id } } );
- $builder->build_object( { class => 'Koha::Auth::Provider::Domains', value => { auth_provider_id => $provider->id } } );
-
- is( $provider->domains->count, 2, 'The provider has 2 domains defined' );
-
- $schema->storage->txn_rollback;
-};
-
-subtest 'get_config() tests' => sub {
-
- plan tests => 2;
-
- $schema->storage->txn_begin;
-
- my $provider = $builder->build_object( { class => 'Koha::Auth::Providers', value => { config => '{' } } );
-
- throws_ok { $provider->get_config() }
- 'Koha::Exceptions::Object::BadValue', 'Expected exception thrown on bad JSON';
-
- my $config = { some => 'value', and => 'another' };
- $provider->config( encode_json($config) )->store;
-
- is_deeply( $provider->get_config, $config, 'Config correctly retrieved' );
-
- $schema->storage->txn_rollback;
-};
-
-subtest 'set_config() tests' => sub {
-
- plan tests => 3;
-
- $schema->storage->txn_begin;
-
- subtest 'OIDC protocol 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',
- secret => 'secret',
- };
-
- throws_ok { $provider->set_config($config) }
- 'Koha::Exceptions::MissingParameter', 'Exception thrown on missing parameter';
-
- 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::OIDC', 'Return type is correct' );
-
- is_deeply( $provider->get_config, $config, 'Configuration stored correctly' );
- };
-
- subtest 'OAuth protocol 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',
- secret => 'secret',
- token_url => 'https://koha-community.org/auth/token',
- };
-
- throws_ok { $provider->set_config($config) }
- 'Koha::Exceptions::MissingParameter', 'Exception thrown on missing parameter';
-
- 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::OAuth', 'Return type is correct' );
-
- is_deeply( $provider->get_config, $config, 'Configuration stored correctly' );
- };
-
- subtest 'Unsupported protocol tests' => sub {
-
- plan tests => 2;
-
- my $provider = $builder->build_object( { class => 'Koha::Auth::Providers', value => { protocol => 'CAS' } } );
-
- throws_ok { $provider->set_config() }
- 'Koha::Exception', 'Exception thrown on unsupported protocol';
-
- like( "$@", qr/This method needs to be subclassed/, 'Message is correct' );
- };
-
- $schema->storage->txn_rollback;
-};
-
-subtest 'get_mapping() tests' => sub {
-
- plan tests => 2;
-
- $schema->storage->txn_begin;
-
- my $provider = $builder->build_object( { class => 'Koha::Auth::Providers', value => { config => '{' } } );
-
- throws_ok { $provider->get_mapping() }
- 'Koha::Exceptions::Object::BadValue', 'Expected exception thrown on bad JSON';
-
- my $mapping = { some => 'value', and => 'another' };
- $provider->mapping( encode_json($mapping) )->store;
-
- is_deeply( $provider->get_mapping, $mapping, 'Mapping correctly retrieved' );
-
- $schema->storage->txn_rollback;
-};
-
-subtest 'set_mapping() tests' => sub {
-
- plan tests => 1;
-
- $schema->storage->txn_begin;
-
- my $provider = $builder->build_object( { class => 'Koha::Auth::Providers' } );
-
- my $mapping = { some => 'value', and => 'another' };
- $provider->set_mapping($mapping)->store;
-
- is_deeply( $provider->get_mapping, $mapping, 'Mapping correctly retrieved' );
-
- $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;
-};
--- /dev/null
+#!/usr/bin/perl
+
+# Copyright 2022 Theke Solutions
+#
+# 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::Patrons;
+use Koha::Auth::Identity::Provider::Domains;
+use Koha::Patrons;
+use Try::Tiny;
+
+# Dummy app for testing the plugin
+use Mojolicious::Lite;
+
+plugin 'Koha::REST::Plugin::Auth::IdP';
+
+post '/register_user' => sub {
+ my $c = shift;
+ my $params = $c->req->json;
+ try {
+ my $domain = Koha::Auth::Identity::Provider::Domains->find($params->{domain_id});
+ my $patron = $c->auth->register({
+ data => $params->{data},
+ domain => $domain,
+ interface => $params->{interface}
+ });
+ $c->render(status => 200, json => $patron->to_api);
+ } catch {
+ if ( ref($_) eq 'Koha::Exceptions::Auth::Unauthorized' ) {
+ $c->render(status => 401, json => {message => 'unauthorized'});
+ } else {
+ $c->render(status => 500, json => {message => 'other error'});
+ }
+ }
+};
+
+post '/start_session' => sub {
+ my $c = shift;
+ my $userid = my $params = $c->req->json->{userid};
+
+ try {
+ my $patron = Koha::Patrons->search({userid => $userid});
+ my ($status, $cookie, $session_id) = $c->auth->session($patron->next);
+ $c->render(status => 200, json => {status => $status});
+ } catch {
+ if ( ref($_) eq 'Koha::Exceptions::Auth::CannotCreateSession' ) {
+ $c->render(status => 401, json => {message => 'unauthorized'});
+ } else {
+ $c->render(status => 500, json => {message => 'other error'});
+ }
+ }
+};
+
+use Test::More tests => 2;
+use Test::Mojo;
+
+use t::lib::Mocks;
+use t::lib::TestBuilder;
+use Koha::Database;
+
+my $schema = Koha::Database->new()->schema();
+my $builder = t::lib::TestBuilder->new;
+
+# FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
+# this affects the other REST api tests
+t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
+
+subtest 'auth.register helper' => sub {
+ plan tests => 6;
+
+ $schema->storage->txn_begin;
+
+ # Remove existing patrons
+ Koha::Patrons->delete;
+ my $provider = $builder->build_object( { class => 'Koha::Auth::Identity::Providers', value => { matchpoint => 'email' } } );
+ my $domain_with_register = $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id, domain => 'domain1.com', auto_register => 1 } } );
+ my $domain_without_register = $builder->build_object( { class => 'Koha::Auth::Identity::Provider::Domains', value => { identity_provider_id => $provider->id, domain => 'domain2.com', auto_register => 0 } } );
+ my $library = $builder->build_object({ class => 'Koha::Libraries'});
+ my $category = $builder->build_object( {class => 'Koha::Patron::Categories'});
+ my $user_data = {
+ firstname => 'test',
+ surname => 'test',
+ userid => 'id1',
+ branchcode => $library->branchcode,
+ categorycode => $category->categorycode
+ };
+
+ my $t = Test::Mojo->new;
+
+ $t->post_ok('/register_user' => json => {data => $user_data, domain_id => $domain_with_register->identity_provider_domain_id, interface => 'opac'})
+ ->status_is(200)
+ ->json_has('/firstname', 'test');
+
+ $t->post_ok('/register_user' => json => {data => $user_data, domain_id => $domain_without_register->identity_provider_domain_id, interface => 'opac'})
+ ->status_is(401)
+ ->json_has('/message', 'unauthorized');
+ $schema->storage->txn_rollback;
+};
+
+subtest 'auth.session helper' => sub {
+ plan tests => 3;
+
+ $schema->storage->txn_begin;
+
+ # Remove existing patrons
+ Koha::Patrons->delete;
+ my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
+
+
+ my $t = Test::Mojo->new;
+ $t->post_ok('/start_session' => json => {userid => $patron->userid})
+ ->status_is(200)
+ ->json_has('/status', 'ok');
+
+ $schema->storage->txn_rollback;
+};
+
+1;
\ No newline at end of file
--- /dev/null
+#!/usr/bin/perl
+
+# Copyright 2022 Theke Solutions
+#
+# 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 Test::More tests => 3;
+use Test::Mojo;
+use Test::Warn;
+use Mojo::JWT;
+use Crypt::OpenSSL::RSA;
+
+use t::lib::TestBuilder;
+use t::lib::Mocks;
+
+use Koha::Database;
+use C4::Auth;
+use Koha::Auth::Identity::Providers;
+use Koha::Auth::Identity::Provider::Domains;
+
+my $schema = Koha::Database->new->schema;
+my $builder = t::lib::TestBuilder->new;
+
+# FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
+# this affects the other REST api tests
+t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
+
+my $remote_address = '127.0.0.1';
+
+use t::lib::IdP::ExternalIdP;
+
+my $idp_port = t::lib::IdP::ExternalIdP->start;
+
+
+my $oauth_provider_data = {
+ code => 'oauth_test',
+ description => 'OAuth provider',
+ protocol => 'OAuth',
+ mapping => {
+ email => 'users.0.email',
+ firstname => 'users.0.custom_name',
+ surname => 'users.0.custom_surname',
+ userid => 'users.0.id'
+ },
+ matchpoint => 'email',
+ config => {
+ authorize_url => "http://localhost:$idp_port/idp/test/authorization_endpoint",
+ token_url => "http://localhost:$idp_port/idp/test/token_endpoint/without_id_token",
+ userinfo_url => "http://localhost:$idp_port/idp/test/userinfo_endpoint",
+ key => "client_id",
+ secret => "client_secret"
+ }
+};
+
+my $oidc_with_email_provider_data = {
+ code => 'oidc_email',
+ description => 'OIDC wiht email provider',
+ protocol => 'OIDC',
+ mapping => {
+ email => 'email',
+ firstname => 'given_name',
+ surname => 'family_name',
+ userid => 'sub'
+ },
+ matchpoint => 'email',
+ config => {
+ authorize_url => "http://localhost:$idp_port/idp/test/authorization_endpoint",
+ well_known_url => "http://localhost:$idp_port/idp/test/with_email/.well_known",
+ key => "client_id",
+ secret => "client_secret"
+ }
+};
+
+my $oidc_without_email_provider_data = {
+ code => 'oidc_no_email',
+ description => 'OIDC wihtout email provider',
+ protocol => 'OIDC',
+ mapping => {
+ email => 'users.0.email',
+ firstname => 'given_name',
+ surname => 'family_name',
+ userid => 'sub'
+ },
+ matchpoint => 'email',
+ config => {
+ authorize_url => "http://localhost:$idp_port/idp/test/authorization_endpoint",
+ well_known_url => "http://localhost:$idp_port/idp/test/without_email/.well_known",
+ key => "client_id",
+ secret => "client_secret"
+ }
+};
+
+my $domain_not_matching = {
+ domain => 'gmail.com',
+ auto_register => 0,
+ update_on_auth => 0,
+ default_library_id => undef,
+ default_category_id => undef,
+ allow_opac => 1,
+ allow_staff => 0
+};
+
+my $domain_no_register = {
+ domain => 'some.library.com',
+ auto_register => 0,
+ update_on_auth => 0,
+ default_library_id => undef,
+ default_category_id => undef,
+ allow_opac => 1,
+ allow_staff => 0
+};
+
+my $library = $builder->build_object({class => 'Koha::Libraries'});
+my $category = $builder->build_object({class => 'Koha::Patron::Categories'});
+
+my $domain_register = {
+ domain => 'some.library.com',
+ auto_register => 1,
+ update_on_auth => 0,
+ default_library_id => $library->branchcode,
+ default_category_id => $category->categorycode,
+ allow_opac => 1,
+ allow_staff => 1
+};
+
+my $domain_register_update = {
+ domain => 'some.library.com',
+ auto_register => 1,
+ update_on_auth => 1,
+ default_library_id => $library->branchcode,
+ default_category_id => $category->categorycode,
+ allow_opac => 1,
+ allow_staff => 0
+};
+
+subtest 'provider endpoint tests' => sub {
+ plan tests => 12;
+
+ $schema->storage->txn_begin;
+
+ Koha::Auth::Identity::Provider::Domains->delete;
+ Koha::Auth::Identity::Providers->delete;
+
+ my ( $borrowernumber, $session_id ) = create_user_and_session({ authorized => 1 });
+
+ my $t = Test::Mojo->new('Koha::REST::V1');
+
+ my $tx = $t->ua->build_tx( POST => "/api/v1/auth/identity_providers", json => $oauth_provider_data );
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx)
+ ->status_is(201);
+
+ my $provider = Koha::Auth::Identity::Providers->search({code => 'oauth_test'})->next;
+ is ($provider->code, 'oauth_test', 'Provider was created');
+
+ $tx = $t->ua->build_tx( GET => "/api/v1/auth/identity_providers" );
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx)
+ ->json_has('/0/code', 'oauth_test');
+
+ my %modified_provider_data_hash = %{$oauth_provider_data};
+ my $modified_provider_data = \%modified_provider_data_hash;
+ $modified_provider_data->{code} = 'some_code';
+
+ $tx = $t->ua->build_tx( PUT => "/api/v1/auth/identity_providers/".$provider->identity_provider_id, json => $modified_provider_data);
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx)
+ ->status_is(200);
+
+ $tx = $t->ua->build_tx( GET => "/api/v1/auth/identity_providers/".$provider->identity_provider_id);
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx)
+ ->json_has('/code', 'some_code');
+
+ $tx = $t->ua->build_tx( DELETE => "/api/v1/auth/identity_providers/".$provider->identity_provider_id);
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx)
+ ->status_is(204);
+ # p $t->tx->res;
+
+ $provider = Koha::Auth::Identity::Providers->search->next;
+ is ($provider, undef, 'All providers deleted');
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'domain endpoint tests' => sub {
+ plan tests => 12;
+
+ $schema->storage->txn_begin;
+
+ Koha::Auth::Identity::Provider::Domains->delete;
+ Koha::Auth::Identity::Providers->delete;
+
+ my ( $borrowernumber, $session_id ) = create_user_and_session({ authorized => 1 });
+
+ my $t = Test::Mojo->new('Koha::REST::V1');
+
+ my $provider = $builder->build_object({class => 'Koha::Auth::Identity::Providers'});
+
+ my $tx = $t->ua->build_tx( POST => "/api/v1/auth/identity_providers/".$provider->identity_provider_id."/domains", json => $domain_not_matching );
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx)
+ ->status_is(201);
+
+ my $domain = Koha::Auth::Identity::Provider::Domains->search({domain => 'gmail.com'})->next;
+ is ($domain->domain, 'gmail.com', 'Provider was created');
+
+ $tx = $t->ua->build_tx( GET => "/api/v1/auth/identity_providers/".$provider->identity_provider_id."/domains" );
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx)
+ ->json_has('/0/domain', 'gmail.com');
+
+ my %modified_domain_data_hash = %{$domain_not_matching};
+ my $modified_domain_data = \%modified_domain_data_hash;
+ $modified_domain_data->{domain} = 'some.domain.com';
+
+ $tx = $t->ua->build_tx( PUT => "/api/v1/auth/identity_providers/".$provider->identity_provider_id."/domains/".$domain->identity_provider_domain_id, json => $modified_domain_data);
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx)
+ ->status_is(200);
+
+ $tx = $t->ua->build_tx( GET => "/api/v1/auth/identity_providers/".$provider->identity_provider_id."/domains/".$domain->identity_provider_domain_id);
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx)
+ ->json_has('/domain', 'some.domain.com');
+
+ $tx = $t->ua->build_tx( DELETE => "/api/v1/auth/identity_providers/".$provider->identity_provider_id."/domains/".$domain->identity_provider_domain_id);
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx)
+ ->status_is(204);
+ # p $t->tx->res;
+
+ $domain = Koha::Auth::Identity::Provider::Domains->search->next;
+ is ($domain, undef, 'All domains deleted');
+
+ $schema->storage->txn_rollback;
+};
+
+subtest 'oauth login tests' => sub {
+ plan tests => 4;
+
+ $schema->storage->txn_begin;
+
+ Koha::Auth::Identity::Provider::Domains->delete;
+ Koha::Auth::Identity::Providers->delete;
+
+ my ( $borrowernumber, $session_id ) = create_user_and_session({ authorized => 1 });
+
+ my $t = Test::Mojo->new('Koha::REST::V1');
+
+ # Build provider
+ my $tx = $t->ua->build_tx( POST => "/api/v1/auth/identity_providers", json => $oauth_provider_data );
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx);
+ my $provider_id = $t->tx->res->json->{identity_provider_id};
+
+ # Build domain
+ $tx = $t->ua->build_tx( POST => "/api/v1/auth/identity_providers/$provider_id/domains", json => $domain_not_matching );
+ $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
+ $tx->req->env( { REMOTE_ADDR => $remote_address } );
+
+ $t->request_ok($tx);
+
+ t::lib::Mocks::mock_preference( 'RESTPublicAPI', 1 );
+
+ # Simulate server restart
+ $t = Test::Mojo->new('Koha::REST::V1');
+
+ #$t->ua->max_redirects(10);
+ $t->get_ok("/api/v1/public/oauth/login/oauth_test/opac")
+ ->status_is(302);
+ use Data::Printer colored => 1;
+ p $t->tx->res;
+
+ $schema->storage->txn_rollback;
+};
+
+sub create_user_and_session {
+
+ my $args = shift;
+ my $flags = ( $args->{authorized} ) ? 1 : 0;
+
+ my $user = $builder->build(
+ {
+ source => 'Borrower',
+ value => {
+ flags => $flags
+ }
+ }
+ );
+
+ # Create a session for the authorized user
+ my $session = C4::Auth::get_session('');
+ $session->param( 'number', $user->{borrowernumber} );
+ $session->param( 'id', $user->{userid} );
+ $session->param( 'ip', $remote_address );
+ $session->param( 'lasttime', time() );
+ $session->flush;
+
+ return ( $user->{borrowernumber}, $session->id );
+}
+
+1;
\ No newline at end of file
--- /dev/null
+package t::lib::IdP::ExternalIdP;
+
+use Mojolicious::Lite;
+use Mojo::IOLoop;
+use Mojo::IOLoop::Server;
+use Mojo::Server::Daemon;
+
+print "Configure idp routes\n";
+
+any '/idp/test/authorization_endpoint' => sub {
+ my $c = shift;
+ print "pasa por acá\n";
+ return $c->render(json => {error => 'invalid_request'}, status => 500)
+ unless (3 == grep { $c->param($_) } qw(response_type redirect_uri client_id))
+ && $c->param('response_type') eq 'code';
+
+ my $url = Mojo::URL->new($c->param('redirect_uri'));
+ $url->query({code => 'authorize-code', state => $c->param('state')});
+ return $c->redirect_to($url);
+};
+
+any '/idp/test/token_endpoint/with_id_token/with_email' => sub {
+ my $c = shift;
+ return $c->render(json => {error => 'invalid_request'}, status => 500)
+ unless (4 == grep { $c->param($_) } qw(client_id client_secret redirect_uri code))
+ && $c->param('code') eq 'authorize-code';
+
+ my $claims = {
+ aud => $c->param('client_id'),
+ email => 'test.user@some.library.com',
+ iss => $c->url_for('/idp/test')->to_abs,
+ given_name => 'test',
+ family_name => 'user',
+ preferred_username => 'test.user@some.library.com',
+ sub => 'test.user'
+ };
+
+ my $rsa = Crypt::OpenSSL::RSA->generate_key(2048);
+
+ my $id_token = Mojo::JWT->new(
+ algorithm => 'RS256',
+ secret => $rsa->get_private_key_string,
+ set_iat => 1,
+ claims => $claims,
+ header => {kid => 'TEST_SIGNING_KEY'}
+ );
+
+ $c->render(status => 200, json => {
+ access_token => 'access',
+ expires_in => 3599,
+ ext_expires_in => 3599,
+ id_token => $id_token,
+ refresh_token => 'refresh-token',
+ scope => 'openid',
+ token_type => 'Bearer'
+ });
+};
+
+any '/idp/test/token_endpoint/with_id_token/without_email' => sub {
+ my $c = shift;
+ return $c->render(json => {error => 'invalid_request'}, status => 500)
+ unless (4 == grep { $c->param($_) } qw(client_id client_secret redirect_uri code))
+ && $c->param('code') eq 'authorize-code';
+
+ my $claims = {
+ aud => $c->param('client_id'),
+ iss => $c->url_for('/idp/test')->to_abs,
+ given_name => 'test',
+ family_name => 'user',
+ preferred_username => 'test.user',
+ sub => 'test.user'
+ };
+
+ my $rsa = Crypt::OpenSSL::RSA->generate_key(2048);
+
+ my $id_token = Mojo::JWT->new(
+ algorithm => 'RS256',
+ secret => $rsa->get_private_key_string,
+ set_iat => 1,
+ claims => $claims,
+ header => {kid => 'TEST_SIGNING_KEY'}
+ );
+
+ $c->render(status => 200, json => {
+ access_token => 'access',
+ expires_in => 3599,
+ ext_expires_in => 3599,
+ id_token => $id_token,
+ refresh_token => 'refresh-token',
+ scope => 'openid',
+ token_type => 'Bearer'
+ });
+};
+
+any '/idp/test/token_endpoint/without_id_token' => sub {
+ my $c = shift;
+ return $c->render(json => {error => 'invalid_request'}, status => 500)
+ unless (4 == grep { $c->param($_) } qw(client_id client_secret redirect_uri code))
+ && $c->param('code') eq 'authorize-code';
+
+ $c->render(status => 200, json => {
+ access_token => 'access',
+ expires_in => 3599,
+ ext_expires_in => 3599,
+ refresh_token => 'refresh-token',
+ scope => 'some list of scopes',
+ token_type => 'Bearer'
+ });
+};
+
+any '/idp/test/userinfo_endpoint' => sub {
+ my $c = shift;
+ return $c->render(text => 'Unauthorized', status => 401)
+ unless $c->req->headers->authorization eq 'Bearer access';
+
+ $c->render(status => 200, json => {
+ users => [
+ {
+ email => 'test.user@some.library.com',
+ custom_name => 'test',
+ custom_surname => 'user',
+ id => 'test.user',
+ last_login => 'a long time ago'
+ }
+ ]
+ });
+};
+
+any '/idp/test/with_email/.well_known' => sub {
+ my $c = shift;
+
+ $c->render(status => 200, json => {
+ authorization_endpoint => $c->url_for('/idp/test/authorization_endpoint')->to_abs,
+ token_endpoint => $c->url_for('/idp/test/token_endpoint/with_id_token/with_email')->to_abs,
+ userinfo_endpoint => $c->url_for('/idp/test/userinfo_endpoint')->to_abs,
+ });
+};
+
+any '/idp/test/without_email/.well_known' => sub {
+ my $c = shift;
+
+ $c->render(status => 200, json => {
+ authorization_endpoint => $c->url_for('/idp/test/authorization_endpoint')->to_abs,
+ token_endpoint => $c->url_for('/idp/test/token_endpoint/with_id_token/without_email')->to_abs,
+ userinfo_endpoint => $c->url_for('/idp/test/userinfo_endpoint')->to_abs,
+ });
+};
+
+my $port = Mojo::IOLoop::Server->generate_port;
+my $daemon = Mojo::Server::Daemon->new(
+ app => app,
+ listen => ["http://*:$port"]
+);
+
+sub start {
+ print "Run daemon\n";
+ $daemon->start;
+ Mojo::IOLoop->start unless Mojo::IOLoop->is_running;
+ return $port;
+}
+
+sub stop {
+ $daemon->stop;
+}
+
+1;
\ No newline at end of file