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