3 # Copyright 2022 Theke Solutions
5 # This file is part of Koha
7 # Koha is free software; you can redistribute it and/or modify it
8 # under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
12 # Koha is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with Koha; if not, see <http://www.gnu.org/licenses>.
22 use Test::More tests => 2;
26 use Crypt::OpenSSL::RSA;
28 use t::lib::TestBuilder;
33 use Koha::Auth::Identity::Providers;
34 use Koha::Auth::Identity::Provider::Domains;
36 my $schema = Koha::Database->new->schema;
37 my $builder = t::lib::TestBuilder->new;
39 # FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
40 # this affects the other REST api tests
41 t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
43 my $remote_address = '127.0.0.1';
45 # use t::lib::IdP::ExternalIdP;
47 # my $idp_port = t::lib::IdP::ExternalIdP->start;
50 my $oauth_provider_data = {
52 description => 'OAuth provider',
55 email => 'users.0.email',
56 firstname => 'users.0.custom_name',
57 surname => 'users.0.custom_surname',
58 userid => 'users.0.id'
60 matchpoint => 'email',
62 authorize_url => "/idp/test/authorization_endpoint",
63 token_url => "/idp/test/token_endpoint/without_id_token",
64 userinfo_url => "/idp/test/userinfo_endpoint",
66 secret => "client_secret"
70 my $oidc_with_email_provider_data = {
72 description => 'OIDC with email provider',
76 firstname => 'given_name',
77 surname => 'family_name',
80 matchpoint => 'email',
82 authorize_url => "/idp/test/authorization_endpoint",
83 well_known_url => "/idp/test/with_email/.well_known",
85 secret => "client_secret"
89 my $oidc_without_email_provider_data = {
90 code => 'oidc_no_email',
91 description => 'OIDC without email provider',
94 email => 'users.0.email',
95 firstname => 'given_name',
96 surname => 'family_name',
99 matchpoint => 'email',
101 authorize_url => "/idp/test/authorization_endpoint",
102 well_known_url => "/idp/test/without_email/.well_known",
104 secret => "client_secret"
108 my $domain_not_matching = {
109 domain => 'gmail.com',
112 default_library_id => undef,
113 default_category_id => undef,
118 my $domain_no_register = {
119 domain => 'some.library.com',
122 default_library_id => undef,
123 default_category_id => undef,
128 my $library = $builder->build_object({class => 'Koha::Libraries'});
129 my $category = $builder->build_object({class => 'Koha::Patron::Categories'});
131 my $domain_register = {
132 domain => 'some.library.com',
135 default_library_id => $library->branchcode,
136 default_category_id => $category->categorycode,
141 my $domain_register_update = {
142 domain => 'some.library.com',
145 default_library_id => $library->branchcode,
146 default_category_id => $category->categorycode,
151 subtest 'provider endpoint tests' => sub {
154 $schema->storage->txn_begin;
156 Koha::Auth::Identity::Provider::Domains->delete;
157 Koha::Auth::Identity::Providers->delete;
159 my ( $borrowernumber, $session_id ) = create_user_and_session({ authorized => 1 });
161 my $t = Test::Mojo->new('Koha::REST::V1');
163 my $tx = $t->ua->build_tx( POST => "/api/v1/auth/identity_providers", json => $oauth_provider_data );
164 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
165 $tx->req->env( { REMOTE_ADDR => $remote_address } );
170 my $provider = Koha::Auth::Identity::Providers->search({code => 'oauth_test'})->next;
171 is ($provider->code, 'oauth_test', 'Provider was created');
173 $tx = $t->ua->build_tx( GET => "/api/v1/auth/identity_providers" );
174 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
175 $tx->req->env( { REMOTE_ADDR => $remote_address } );
178 ->json_has('/0/code', 'oauth_test');
180 my %modified_provider_data_hash = %{$oauth_provider_data};
181 my $modified_provider_data = \%modified_provider_data_hash;
182 $modified_provider_data->{code} = 'some_code';
184 $tx = $t->ua->build_tx( PUT => "/api/v1/auth/identity_providers/".$provider->identity_provider_id, json => $modified_provider_data);
185 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
186 $tx->req->env( { REMOTE_ADDR => $remote_address } );
191 $tx = $t->ua->build_tx( GET => "/api/v1/auth/identity_providers/".$provider->identity_provider_id);
192 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
193 $tx->req->env( { REMOTE_ADDR => $remote_address } );
196 ->json_has('/code', 'some_code');
198 $tx = $t->ua->build_tx( DELETE => "/api/v1/auth/identity_providers/".$provider->identity_provider_id);
199 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
200 $tx->req->env( { REMOTE_ADDR => $remote_address } );
206 $provider = Koha::Auth::Identity::Providers->search->next;
207 is ($provider, undef, 'All providers deleted');
209 $schema->storage->txn_rollback;
212 subtest 'domain endpoint tests' => sub {
215 $schema->storage->txn_begin;
217 Koha::Auth::Identity::Provider::Domains->delete;
218 Koha::Auth::Identity::Providers->delete;
220 my ( $borrowernumber, $session_id ) = create_user_and_session({ authorized => 1 });
222 my $t = Test::Mojo->new('Koha::REST::V1');
224 my $provider = $builder->build_object({class => 'Koha::Auth::Identity::Providers'});
226 my $tx = $t->ua->build_tx( POST => "/api/v1/auth/identity_providers/".$provider->identity_provider_id."/domains", json => $domain_not_matching );
227 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
228 $tx->req->env( { REMOTE_ADDR => $remote_address } );
233 my $domain = Koha::Auth::Identity::Provider::Domains->search({domain => 'gmail.com'})->next;
234 is ($domain->domain, 'gmail.com', 'Provider was created');
236 $tx = $t->ua->build_tx( GET => "/api/v1/auth/identity_providers/".$provider->identity_provider_id."/domains" );
237 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
238 $tx->req->env( { REMOTE_ADDR => $remote_address } );
241 ->json_has('/0/domain', 'gmail.com');
243 my %modified_domain_data_hash = %{$domain_not_matching};
244 my $modified_domain_data = \%modified_domain_data_hash;
245 $modified_domain_data->{domain} = 'some.domain.com';
247 $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);
248 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
249 $tx->req->env( { REMOTE_ADDR => $remote_address } );
254 $tx = $t->ua->build_tx( GET => "/api/v1/auth/identity_providers/".$provider->identity_provider_id."/domains/".$domain->identity_provider_domain_id);
255 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
256 $tx->req->env( { REMOTE_ADDR => $remote_address } );
259 ->json_has('/domain', 'some.domain.com');
261 $tx = $t->ua->build_tx( DELETE => "/api/v1/auth/identity_providers/".$provider->identity_provider_id."/domains/".$domain->identity_provider_domain_id);
262 $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
263 $tx->req->env( { REMOTE_ADDR => $remote_address } );
269 $domain = Koha::Auth::Identity::Provider::Domains->search->next;
270 is ($domain, undef, 'All domains deleted');
272 $schema->storage->txn_rollback;
275 # subtest 'oauth login tests' => sub {
278 # $schema->storage->txn_begin;
280 # Koha::Auth::Identity::Provider::Domains->delete;
281 # Koha::Auth::Identity::Providers->delete;
283 # my ( $borrowernumber, $session_id ) = create_user_and_session({ authorized => 1 });
285 # my $t = Test::Mojo->new('Koha::REST::V1');
288 # my $tx = $t->ua->build_tx( POST => "/api/v1/auth/identity_providers", json => $oauth_provider_data );
289 # $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
290 # $tx->req->env( { REMOTE_ADDR => $remote_address } );
292 # $t->request_ok($tx);
293 # my $provider_id = $t->tx->res->json->{identity_provider_id};
296 # $tx = $t->ua->build_tx( POST => "/api/v1/auth/identity_providers/$provider_id/domains", json => $domain_not_matching );
297 # $tx->req->cookies( { name => 'CGISESSID', value => $session_id } );
298 # $tx->req->env( { REMOTE_ADDR => $remote_address } );
300 # $t->request_ok($tx);
302 # t::lib::Mocks::mock_preference( 'RESTPublicAPI', 1 );
304 # # Simulate server restart
305 # $t = Test::Mojo->new('Koha::REST::V1');
307 # #$t->ua->max_redirects(10);
308 # $t->get_ok("/api/v1/public/oauth/login/oauth_test/opac")
310 # $schema->storage->txn_rollback;
313 sub create_user_and_session {
316 my $flags = ( $args->{authorized} ) ? 1 : 0;
318 my $user = $builder->build(
320 source => 'Borrower',
327 # Create a session for the authorized user
328 my $session = C4::Auth::get_session('');
329 $session->param( 'number', $user->{borrowernumber} );
330 $session->param( 'id', $user->{userid} );
331 $session->param( 'ip', $remote_address );
332 $session->param( 'lasttime', time() );
335 return ( $user->{borrowernumber}, $session->id );