From 1d0d8d4cfd615fa8537198c5ef183949acaea5d6 Mon Sep 17 00:00:00 2001 From: Alex Arnaud Date: Thu, 1 Mar 2018 08:43:41 +0000 Subject: [PATCH] Bug 20340 - Ability to add and use authentication plugins Plugins must be placed in and enabled with AuthenticationModule system preference. Test plan: - Apply this patch, - set UseKohaPlugins to enabled, - define a pluginsdir in your koha-conf.xml, - put a plugin in this directory. - I.e, take the one provided in tests directory: - t/Koha/Plugin/TestAuth.pm, - login/pass is test/test - You should have: /your/plugins/dir/Koha/Plugin/TestAuth.pm, - test authentication with and without the plugin. --- C4/Auth.pm | 16 +++++++++- Koha/Plugins.pm | 1 + t/Koha/Plugin/TestAuth.pm | 75 +++++++++++++++++++++++++++++++++++++++++++++++ t/db_dependent/Auth.t | 26 +++++++++++++++- 4 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 t/Koha/Plugin/TestAuth.pm diff --git a/C4/Auth.pm b/C4/Auth.pm index c3ba5ba..ebcc978 100644 --- a/C4/Auth.pm +++ b/C4/Auth.pm @@ -40,6 +40,7 @@ use Koha::Library::Groups; use Koha::Libraries; use Koha::Patrons; use Koha::Patron::Consents; +use Koha::Plugins; use POSIX qw/strftime/; use List::MoreUtils qw/ any /; use Encode qw( encode is_utf8); @@ -1774,10 +1775,23 @@ sub checkpw { my ( $dbh, $userid, $password, $query, $type, $no_set_userenv ) = @_; $type = 'opac' unless $type; + if ( C4::Context->preference('UseKohaPlugins') && C4::Context->config("enable_plugins") ) { + my @plugins = Koha::Plugins->new()->GetPlugins({ + method => 'checkpw', + }); + + @plugins = sort { $a->retrieve_data('priority') <=> $b->retrieve_data('priority') } @plugins; + foreach my $plugin ( @plugins ) { + my ( $retval, $retcard, $retuserid ) = $plugin->checkpw(@_); + if ( $retval == 1 ) { + return ( $retval, $retcard, $retuserid ); + } + } + } + # Get shibboleth login attribute my $shib = C4::Context->config('useshibboleth') && shib_ok(); my $shib_login = $shib ? get_login_shib() : undef; - my @return; my $patron = Koha::Patrons->find({ userid => $userid }); my $check_internal_as_fallback = 0; diff --git a/Koha/Plugins.pm b/Koha/Plugins.pm index c0aaa9c..a67c2e3 100644 --- a/Koha/Plugins.pm +++ b/Koha/Plugins.pm @@ -82,6 +82,7 @@ sub GetPlugins { # Limit results by method or metadata next if $method && !$plugin->can($method); my $plugin_metadata = $plugin->get_metadata; + next if $plugin_metadata and %$req_metadata and any { !$plugin_metadata->{$_} || $plugin_metadata->{$_} ne $req_metadata->{$_} } keys %$req_metadata; diff --git a/t/Koha/Plugin/TestAuth.pm b/t/Koha/Plugin/TestAuth.pm new file mode 100644 index 0000000..438213b --- /dev/null +++ b/t/Koha/Plugin/TestAuth.pm @@ -0,0 +1,75 @@ +package Koha::Plugin::TestAuth; + +use Modern::Perl; + +use base 'Koha::Plugins::Base'; + +our $VERSION = '1.0'; +our $metadata = { + name => 'Authentication test plugin', + author => 'Alex Arnaud ', + description => 'Plugin for testing authentication plugin API', + date_authored => '2018-02-28', + date_updated => '2018-02-28', + minimum_version => '17.05', + maximum_version => undef, + type => 'authentication', + version => $VERSION, +}; + +=head1 METHODS + +=head2 new + + Koha::Plugin::TestAuth->new(); + + Create new object + +=cut + +sub new { + my ($class, $args) = @_; + + $args->{metadata} = $metadata; + $args->{metadata}->{class} = $class; + + my $self = $class->SUPER::new($args); + + return $self; +} + +=head2 retrieve_data + +Just return priority. It overrides the one in Koha::Plugin::Base for the test. + +=cut + +sub retrieve_data { + my ( $self, $key ) = @_; + + if ( $key eq 'priority' ) { + return 1; + } + +} + +=head2 checkpw + + ($result, cardnumber, $userid) = + checkpw($self, $dbh, $userid, $password, $query, $type, $no_set_userenv); + + Authenticate a patron using login/password. + +=cut + +sub checkpw { + my ( $self, $dbh, $userid, $password, $query, $type, $no_set_userenv ) = @_; + + if ( $userid = 'test' && $password eq 'test' ) { + return (1, 'test', 'test'); + } + + return (0, '', ''); +} + +1; diff --git a/t/db_dependent/Auth.t b/t/db_dependent/Auth.t index e0b6036..76d601a 100644 --- a/t/db_dependent/Auth.t +++ b/t/db_dependent/Auth.t @@ -10,7 +10,7 @@ use CGI qw ( -utf8 ); use Test::MockObject; use Test::MockModule; use List::MoreUtils qw/all any none/; -use Test::More tests => 20; +use Test::More tests => 26; use Test::Warn; use t::lib::Mocks; use t::lib::TestBuilder; @@ -20,8 +20,11 @@ use C4::Members; use Koha::AuthUtils qw/hash_password/; use Koha::Database; use Koha::Patrons; +use File::Basename; BEGIN { + push( @INC, dirname(__FILE__) . '/..' ); + use_ok('C4::Auth'); } @@ -32,6 +35,7 @@ my $dbh = C4::Context->dbh; # FIXME: SessionStorage defaults to mysql, but it seems to break transaction # handling t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' ); +t::lib::Mocks::mock_preference( 'UseKohaPlugins', 0 ); $schema->storage->txn_begin; @@ -129,6 +133,7 @@ subtest 'no_set_userenv parameter tests' => sub { ok( checkpw( $dbh, $patron->userid, $password, undef, undef, 1 ), 'checkpw returns true' ); is( C4::Context->userenv, undef, 'Userenv should be undef as required' ); C4::Context->_new_userenv('DUMMY SESSION'); +<<<<<<< 41e0ff7cd6240c2c9ba2d1bec816b191ef091eb1 C4::Context->set_userenv(0,0,0,'firstname','surname', $library->branchcode, 'Library 1', 0, '', ''); is( C4::Context->userenv->{branch}, $library->branchcode, 'Userenv gives correct branch' ); ok( checkpw( $dbh, $patron->userid, $password, undef, undef, 1 ), 'checkpw returns true' ); @@ -136,6 +141,25 @@ subtest 'no_set_userenv parameter tests' => sub { ok( checkpw( $dbh, $patron->userid, $password, undef, undef, 0 ), 'checkpw still returns true' ); isnt( C4::Context->userenv->{branch}, $library->branchcode, 'Userenv branch is overwritten if no_set_userenv is false' ); }; +======= + C4::Context->set_userenv(0,0,0,'firstname','surname', $library->{branchcode}, 'Library 1', 0, '', ''); + is( C4::Context->userenv->{branch}, $library->{branchcode}, 'Userenv gives correct branch' ); + ok( checkpw( $dbh, $patron->{userid}, 'password', undef, undef, 1 ), 'checkpw returns true' ); + is( C4::Context->userenv->{branch}, $library->{branchcode}, 'Userenv branch is preserved if no_set_userenv is true' ); + ok( checkpw( $dbh, $patron->{userid}, 'password', undef, undef, 0 ), 'checkpw still returns true' ); + isnt( C4::Context->userenv->{branch}, $library->{branchcode}, 'Userenv branch is overwritten if no_set_userenv is false' ); + + t::lib::Mocks::mock_preference( 'UseKohaPlugins', 1 ); + my @result = checkpw( $dbh, $patron->{userid}, 'wrong_password', undef, undef, 1 ); + is( $result[0], 0, 'With TestAuth plugin, checkpw returns 0' ); + is( $result[1], undef, 'With TestAuth plugin, checkpw returns empty cardnumber' ); + is( $result[2], undef, 'With TestAuth plugin, checkpw returns empty userid' ); + @result = checkpw( $dbh, 'test', 'test', undef, undef, 1 ); + is( $result[0], 1, 'With TestAuth plugin, checkpw returns 1' ); + is( $result[1], 'test', 'With TestAuth plugin, checkpw returns test cardnumber' ); + is( $result[2], 'test', 'With TestAuth plugin, checkpw returns test userid' ); +} +>>>>>>> Bug 20340 - Ability to add and use authentication plugins # get_template_and_user tests -- 2.7.4