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