Use the stored user credentials to look up roles
[catagits/Catalyst-Authentication-Store-LDAP.git] / t / 10-roles-mock.t
CommitLineData
405489b5 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5use Catalyst::Exception;
6
e385da71 7use Test::More;
405489b5 8use Test::MockObject::Extends;
d94851da 9use Test::Exception;
405489b5 10use Net::LDAP::Entry;
11use lib 't/lib';
12
e385da71 13eval "use Catalyst::Model::LDAP";
14plan skip_all => "Catalyst::Model::LDAP not installed" if $@;
405489b5 15
e385da71 16use_ok("Catalyst::Authentication::Store::LDAP::Backend");
405489b5 17
e385da71 18my (@searches, @binds);
19for my $i (0..1) {
405489b5 20
e385da71 21 my $back = Catalyst::Authentication::Store::LDAP::Backend->new({
22 'ldap_server' => 'ldap://127.0.0.1:555',
23 'binddn' => 'anonymous',
24 'bindpw' => 'dontcarehow',
25 'start_tls' => 0,
26 'user_basedn' => 'ou=foobar',
27 'user_filter' => '(&(objectClass=inetOrgPerson)(uid=%s))',
28 'user_scope' => 'one',
29 'user_field' => 'uid',
30 'use_roles' => 1,
31 'role_basedn' => 'ou=roles',
32 'role_filter' => '(&(objectClass=posixGroup)(memberUid=%s))',
33 'role_scope' => 'one',
34 'role_field' => 'userinrole',
35 'role_value' => 'cn',
36 'role_search_as_user' => $i,
37 });
38 $back = Test::MockObject::Extends->new($back);
39 my $bind_msg = Test::MockObject->new;
40 $bind_msg->mock(is_error => sub {}); # Cause bind call to always succeed
41 my $ldap = Test::MockObject->new;
42 $ldap->mock('bind', sub { shift; push (@binds, [@_]); return $bind_msg});
43 $ldap->mock('unbind' => sub {});
44 $ldap->mock('disconnect' => sub {});
45 my $search_res = Test::MockObject->new();
46 my $search_is_error = 0;
47 $search_res->mock(is_error => sub { $search_is_error });
48 $search_res->mock(entries => sub {
49 return map
50 { my $id = $_;
51 Test::MockObject->new->mock(
52 get_value => sub { "quux$id" }
53 )
54 }
55 qw/one two/
56 });
57 my @user_entries;
58 $search_res->mock(pop_entry => sub { return pop @user_entries });
59 $ldap->mock('search', sub { shift; push(@searches, [@_]); return $search_res; });
60 $back->mock('ldap_connect' => sub { $ldap });
61 my $user_entry = Net::LDAP::Entry->new;
62 push(@user_entries, $user_entry);
63 $user_entry->dn('ou=foobar');
64 $user_entry->add(
65 uid => 'somebody',
66 cn => 'test',
67 );
68 my $user = $back->find_user( { username => 'somebody' } );
69 isa_ok( $user, "Catalyst::Authentication::Store::LDAP::User" );
70 $user->check_password('password');
71 is_deeply( [sort $user->roles],
72 [sort qw/quuxone quuxtwo/],
73 "User has the expected set of roles" );
405489b5 74
e385da71 75 $search_is_error = 1;
76 lives_ok {
77 ok !$back->find_user( { username => 'doesnotexist' } ),
78 'Nonexistent user returns undef';
79 } 'No exception thrown for nonexistent user';
d94851da 80
405489b5 81}
e385da71 82is_deeply(\@searches, [
83 ['base', 'ou=foobar', 'filter', '(&(objectClass=inetOrgPerson)(uid=somebody))', 'scope', 'one'],
84 ['base', 'ou=roles', 'filter', '(&(objectClass=posixGroup)(memberUid=test))', 'scope', 'one', 'attrs', [ 'userinrole' ]],
85 ['base', 'ou=foobar', 'filter', '(&(objectClass=inetOrgPerson)(uid=doesnotexist))', 'scope', 'one'],
86 ['base', 'ou=foobar', 'filter', '(&(objectClass=inetOrgPerson)(uid=somebody))', 'scope', 'one'],
87 ['base', 'ou=roles', 'filter', '(&(objectClass=posixGroup)(memberUid=test))', 'scope', 'one', 'attrs', [ 'userinrole' ]],
88 ['base', 'ou=foobar', 'filter', '(&(objectClass=inetOrgPerson)(uid=doesnotexist))', 'scope', 'one'],
89], 'User searches as expected');
90is_deeply(\@binds, [
91 [ undef ], # First user search
92 [
93 'ou=foobar',
94 'password',
95 'password'
96 ], # Rebind to confirm user
97 [
98 undef
99 ], # Rebind with initial credentials to find roles
100 [ undef ], # Second user search
101 # 2nd pass round main loop
102 [ undef ], # First user search
103 [
104 'ou=foobar',
105 'password',
106 'password'
5a9aba6e 107 ], # Rebind to confirm user
108 [
109 'ou=foobar',
110 'password',
111 'password'
112 ], # Rebind with user credentials to find roles
e385da71 113 [ undef ], # Second user search
114], 'Binds as expected');
115
116done_testing;