store the persist_in_session setting in the session
[catagits/Catalyst-Authentication-Store-LDAP.git] / t / 10-roles-mock.t
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5 use Catalyst::Exception;
6
7 use Test::More;
8 use Test::MockObject::Extends;
9 use Test::Exception;
10 use Net::LDAP::Entry;
11 use lib 't/lib';
12
13 eval "use Catalyst::Model::LDAP";
14 plan skip_all => "Catalyst::Model::LDAP not installed" if $@;
15
16 use_ok("Catalyst::Authentication::Store::LDAP::Backend");
17
18 my (@searches, @binds);
19 for my $i (0..1) {
20
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" );
74
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';
80
81 }
82 is_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');
90 is_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'
107     ], # Rebind to confirm user
108     [
109         'ou=foobar',
110         'password',
111         'password'
112     ], # Rebind with user credentials to find roles
113     [ undef ], # Second user search
114 ], 'Binds as expected');
115
116 done_testing;