Bugzilla – Attachment 30473 Details for
Bug 8148
ldap authentication should FAIL if ldap contains NEW password, and user types the PREVIOUS password
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 8148: (regression tests) C4::Auth_with_ldap needs unit tests
Bug-8148-regression-tests-C4Authwithldap-needs-uni.patch (text/plain), 13.71 KB, created by
Tomás Cohen Arazi (tcohen)
on 2014-08-01 19:29:16 UTC
(
hide
)
Description:
Bug 8148: (regression tests) C4::Auth_with_ldap needs unit tests
Filename:
MIME Type:
Creator:
Tomás Cohen Arazi (tcohen)
Created:
2014-08-01 19:29:16 UTC
Size:
13.71 KB
patch
obsolete
>From 98839946d0b1e134afca9ef9efe639206f52b78d Mon Sep 17 00:00:00 2001 >From: Tomas Cohen Arazi <tomascohen@gmail.com> >Date: Mon, 28 Jul 2014 09:31:52 -0300 >Subject: [PATCH] Bug 8148: (regression tests) C4::Auth_with_ldap needs unit > tests > >This followup provides some unit tests for C4::Auth_with_ldap. It implements >regression tests for this bug's changes too. > >The aim was to cover all use cases for checkpw_ldap from the first line up to >those touched by this bug's patches. It should serve as a start for having >unit tests for the LDAP thing. > >Having said that: no excuses for not providing regression tests for LDAP from now on :-/ > >Regards >To+ > >Sponsored-by: Universidad Nacional de Cordoba >Signed-off-by: Tomas Cohen Arazi <tomascohen@gmail.com> >--- > t/db_dependent/Auth_with_ldap.t | 364 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 364 insertions(+) > create mode 100755 t/db_dependent/Auth_with_ldap.t > >diff --git a/t/db_dependent/Auth_with_ldap.t b/t/db_dependent/Auth_with_ldap.t >new file mode 100755 >index 0000000..169ea0a >--- /dev/null >+++ b/t/db_dependent/Auth_with_ldap.t >@@ -0,0 +1,364 @@ >+#!/usr/bin/perl >+ >+# 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::MockObject; >+use Test::Warn; >+ >+use C4::Context; >+use Data::Printer; >+ >+my $dbh = C4::Context->dbh; >+# Start transaction >+$dbh->{ AutoCommit } = 0; >+$dbh->{ RaiseError } = 1; >+ >+# Variables controlling LDAP server config >+my $update = 0; >+my $replicate = 0; >+my $auth_by_bind = 1; >+my $anonymous_bind = 1; >+# Variables controlling LDAP behaviour >+my $desired_authentication_result = 'success'; >+my $desired_connection_result = 'error'; >+my $desired_bind_result = 'error'; >+my $desired_compare_result = 'error'; >+my $desired_search_result = 'error'; >+my $desired_count_result = 1; >+my $non_anonymous_bind_result = 'error'; >+my $ret; >+ >+# Mock the context module >+my $context = new Test::MockModule( 'C4::Context' ); >+$context->mock( 'config', \&mockedC4Config ); >+ >+# Mock the Net::LDAP module >+my $ldap = new Test::MockModule( 'Net::LDAP' ); >+ >+$ldap->mock( 'new', sub { >+ if ( $desired_connection_result eq 'error' ) { >+ # We were asked to fail the LDAP conexion >+ return; >+ } else { >+ # Return a mocked Net::LDAP object (Test::MockObject) >+ return mock_net_ldap(); >+ } >+}); >+ >+ >+# C4::Auth_with_ldap needs several stuff set first ^^^ >+use_ok( 'C4::Auth_with_ldap' ); >+can_ok( 'C4::Auth_with_ldap', qw/ >+ checkpw_ldap >+ search_method /); >+ >+subtest "checkpw_ldap tests" => sub { >+ >+ plan tests => 4; >+ >+ ## Connection fail tests >+ $desired_connection_result = 'error'; >+ warning_is { $ret = C4::Auth_with_ldap::checkpw_ldap( $dbh, 'hola', password => 'hey' ) } >+ "LDAP connexion failed", >+ "checkpw_ldap prints correct warning if LDAP conexion fails"; >+ is( $ret, 0, "checkpw_ldap returns 0 if LDAP conexion fails"); >+ >+ ## Connection success tests >+ $desired_connection_result = 'success'; >+ >+ subtest "auth_by_bind = 1 tests" => sub { >+ >+ plan tests => 5; >+ >+ $auth_by_bind = 1; >+ >+ $desired_authentication_result = 'success'; >+ $anonymous_bind = 1; >+ $desired_bind_result = 'error'; >+ $desired_search_result = 'error'; >+ reload_ldap_module(); >+ >+ >+ warning_like { $ret = C4::Auth_with_ldap::checkpw_ldap( >+ $dbh, 'hola', password => 'hey' ) } >+ qr/Anonymous LDAP bind failed: LDAP error #1: error_name/, >+ "checkpw_ldap prints correct warning if LDAP anonymous bind fails"; >+ is( $ret, 0, "checkpw_ldap returns 0 if LDAP anonymous bind fails"); >+ >+ $desired_authentication_result = 'success'; >+ $anonymous_bind = 1; >+ $desired_bind_result = 'success'; >+ $desired_search_result = 'success'; >+ $desired_count_result = 0; # user auth problem >+ $non_anonymous_bind_result = 'success'; >+ reload_ldap_module(); >+ is ( C4::Auth_with_ldap::checkpw_ldap( $dbh, 'hola', password => 'hey' ), >+ 0, "checkpw_ldap returns 0 if user lookup returns 0"); >+ >+ $non_anonymous_bind_result = 'error'; >+ reload_ldap_module(); >+ >+ warning_like { $ret = C4::Auth_with_ldap::checkpw_ldap( >+ $dbh, 'hola', password => 'hey' ) } >+ qr/LDAP bind failed as kohauser hola: LDAP error #1: error_name/, >+ "checkpw_ldap prints correct warning if LDAP bind fails"; >+ is ( $ret, -1, "checkpw_ldap returns -1 LDAP bind fails for user (Bug 8148)"); >+ }; >+ >+ subtest "auth_by_bind = 0 tests" => sub { >+ >+ plan tests => 8; >+ >+ $auth_by_bind = 0; >+ >+ # Anonymous bind >+ $anonymous_bind = 1; >+ $desired_bind_result = 'error'; >+ $non_anonymous_bind_result = 'error'; >+ reload_ldap_module(); >+ >+ warning_like { $ret = C4::Auth_with_ldap::checkpw_ldap( >+ $dbh, 'hola', password => 'hey' ) } >+ qr/LDAP bind failed as ldapuser cn=Manager,dc=metavore,dc=com: LDAP error #1: error_name/, >+ "checkpw_ldap prints correct warning if LDAP bind fails"; >+ is ( $ret, 0, "checkpw_ldap returns 0 if bind fails"); >+ >+ $anonymous_bind = 1; >+ $desired_bind_result = 'success'; >+ $non_anonymous_bind_result = 'success'; >+ $desired_compare_result = 'error'; >+ reload_ldap_module(); >+ >+ warning_like { $ret = C4::Auth_with_ldap::checkpw_ldap( >+ $dbh, 'hola', password => 'hey' ) } >+ qr/LDAP Auth rejected : invalid password for user 'hola'. LDAP error #1: error_name/, >+ "checkpw_ldap prints correct warning if LDAP bind fails"; >+ is ( $ret, -1, "checkpw_ldap returns -1 if bind fails (Bug 8148)"); >+ >+ # Non-anonymous bind >+ $anonymous_bind = 0; >+ $desired_bind_result = 'success'; >+ $non_anonymous_bind_result = 'error'; >+ $desired_compare_result = 'dont care'; >+ reload_ldap_module(); >+ >+ warning_like { $ret = C4::Auth_with_ldap::checkpw_ldap( >+ $dbh, 'hola', password => 'hey' ) } >+ qr/LDAP bind failed as ldapuser cn=Manager,dc=metavore,dc=com: LDAP error #1: error_name/, >+ "checkpw_ldap prints correct warning if LDAP bind fails"; >+ is ( $ret, 0, "checkpw_ldap returns 0 if bind fails"); >+ >+ $anonymous_bind = 0; >+ $desired_bind_result = 'success'; >+ $non_anonymous_bind_result = 'success'; >+ $desired_compare_result = 'error'; >+ reload_ldap_module(); >+ >+ warning_like { $ret = C4::Auth_with_ldap::checkpw_ldap( >+ $dbh, 'hola', password => 'hey' ) } >+ qr/LDAP Auth rejected : invalid password for user 'hola'. LDAP error #1: error_name/, >+ "checkpw_ldap prints correct warning if LDAP bind fails"; >+ is ( $ret, -1, "checkpw_ldap returns -1 if bind fails (Bug 8148)"); >+ >+ }; >+}; >+ >+subtest "search_method tests" => sub { >+ >+ plan tests => 5; >+ >+ my $ldap = mock_net_ldap(); >+ >+ # Null params tests >+ is( C4::Auth_with_ldap::search_method( $ldap, undef), undef, >+ "search_method returns undef on undefined userid"); >+ is( C4::Auth_with_ldap::search_method( undef, "undef"), undef, >+ "search_method returns undef on undefined ldap object"); >+ >+ # search ->code and !->code >+ $desired_search_result = 'error'; >+ reload_ldap_module(); >+ eval { $ret = C4::Auth_with_ldap::search_method( $ldap, "undef"); }; >+ like( $@, qr/LDAP search failed to return object : 1/, >+ "search_method prints correct warning when db->search returns error code"); >+ >+ $desired_search_result = 'success'; >+ $desired_count_result = 2; >+ reload_ldap_module(); >+ warning_like { $ret = C4::Auth_with_ldap::search_method( $ldap, '123') } >+ qr/^LDAP Auth rejected \: \(uid\=123\) gets 2 hits/, >+ "search_method prints correct warning when hits count is not 1"; >+ is( $ret, 0, "search_method returns 0 when hits count is not 1" ); >+ >+}; >+ >+# Function that mocks the call to C4::Context->config(param) >+sub mockedC4Config { >+ >+ my $param = shift; >+ >+ my %ldap_mapping = ( >+ firstname => { is => 'givenname' }, >+ surname => { is => 'sn' }, >+ address => { is => 'postaladdress' }, >+ city => { is => 'l' }, >+ zipcode => { is => 'postalcode' }, >+ branchcode => { is => 'branch' }, >+ userid => { is => 'uid' }, >+ password => { is => 'userpassword' }, >+ email => { is => 'mail' }, >+ categorycode => { is => 'employeetype' }, >+ phone => { is => 'telephonenumber' } >+ ); >+ >+ my %ldap_config = ( >+ anonymous_bind => $anonymous_bind, >+ auth_by_bind => $auth_by_bind, >+ base => 'dc=metavore,dc=com', >+ hostname => 'localhost', >+ mapping => \%ldap_mapping, >+ pass => 'metavore', >+ principal_name => '%s@my_domain.com', >+ replicate => $replicate, >+ update => $update, >+ user => 'cn=Manager,dc=metavore,dc=com' >+ ); >+ >+ return \%ldap_config; >+}; >+ >+# Function that mocks the call to Net::LDAP >+sub mock_net_ldap { >+ >+ my $mocked_ldap = Test::MockObject->new(); >+ >+ $mocked_ldap->mock( 'bind', sub { >+ >+ my @args = @_; >+ my $mocked_message; >+ >+ if ( $#args > 1 ) { >+ # Args passed => non-anonymous bind >+ if ( $non_anonymous_bind_result eq 'error' ) { >+ return mock_net_ldap_message(1,1,'error_name','error_text'); >+ } else { >+ return mock_net_ldap_message(0,0,'',''); >+ } >+ } else { >+ $mocked_message = mock_net_ldap_message( >+ ($desired_bind_result eq 'error' ) ? 1 : 0, # code >+ ($desired_bind_result eq 'error' ) ? 1 : 0, # error >+ ($desired_bind_result eq 'error' ) ? 'error_name' : 0, # error_name >+ ($desired_bind_result eq 'error' ) ? 'error_text' : 0 # error_text >+ ); >+ } >+ >+ return $mocked_message; >+ }); >+ >+ $mocked_ldap->mock( 'compare', sub { >+ >+ my $mocked_message; >+ >+ if ( $desired_compare_result eq 'error' ) { >+ $mocked_message = mock_net_ldap_message(1,1,'error_name','error_text'); >+ } else { >+ # we expect return code 6 for success >+ $mocked_message = mock_net_ldap_message(6,0,'',''); >+ } >+ >+ return $mocked_message; >+ }); >+ >+ $mocked_ldap->mock( 'search', sub { >+ >+ return mock_net_ldap_search( >+ ( $desired_count_result ) # count >+ ? $desired_count_result >+ : 1, # default to 1 >+ ( $desired_search_result eq 'error' ) # code >+ ? 1 >+ : 0, # 0 == success >+ ( $desired_search_result eq 'error' ) # error >+ ? 1 >+ : 0, >+ ( $desired_search_result eq 'error' ) # error_text >+ ? 'error_text' >+ : undef, >+ ( $desired_search_result eq 'error' ) # error_name >+ ? 'error_name' >+ : undef, >+ mock_net_ldap_entry( 'sampledn', 1 ) # shift_entry >+ ); >+ >+ }); >+ >+ return $mocked_ldap; >+} >+ >+sub mock_net_ldap_search { >+ my ( $count, $code, $error, $error_text, >+ $error_name, $shift_entry ) = @_; >+ >+ my $mocked_search = Test::MockObject->new(); >+ $mocked_search->mock( 'count', sub { return $count; } ); >+ $mocked_search->mock( 'code', sub { return $code; } ); >+ $mocked_search->mock( 'error', sub { return $error; } ); >+ $mocked_search->mock( 'error_name', sub { return $error_name; } ); >+ $mocked_search->mock( 'error_text', sub { return $error_text; } ); >+ $mocked_search->mock( 'shift_entry', sub { return $shift_entry; } ); >+ >+ return $mocked_search; >+} >+ >+sub mock_net_ldap_message { >+ my ( $code, $error, $error_name, $error_text ) = @_; >+ >+ my $mocked_message = Test::MockObject->new(); >+ $mocked_message->mock( 'code', sub { $code } ); >+ $mocked_message->mock( 'error', sub { $error } ); >+ $mocked_message->mock( 'error_name', sub { $error_name } ); >+ $mocked_message->mock( 'error_text', sub { $error_text } ); >+ >+ return $mocked_message; >+} >+ >+sub mock_net_ldap_entry { >+ my ( $dn, $exists ) = @_; >+ >+ my $mocked_entry = Test::MockObject->new(); >+ $mocked_entry->mock( 'dn', sub { return $dn; } ); >+ $mocked_entry->mock( 'exists', sub { return $exists } ); >+ >+ return $mocked_entry; >+} >+ >+# TODO: Once we remove the global variables in C4::Auth_with_ldap >+# we shouldn't need this... >+# ... Horrible hack >+sub reload_ldap_module { >+ delete $INC{'C4/Auth_with_ldap.pm'}; >+ require C4::Auth_with_ldap; >+ C4::Auth_with_ldap->import; >+} >+ >+$dbh->rollback; >+ >+1; >-- >1.9.1
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 8148
:
25522
|
25523
|
26024
|
26025
|
26147
|
26543
|
29977
|
29978
|
29979
|
30035
|
30036
|
30037
|
30473
|
30524
|
30525
|
30586
|
30587