root/branches/release-41/t/51-objectsync.t @ 2680

Revision 2680, 8.9 kB (checked in by bchoate, 17 months ago)

Test updates to skip when appropriate.

  • Property svn:mime-type set to text/plain
  • Property svn:keywords set to Author Date Id Revision
Line 
1# $Id$
2use strict;
3my $number = 38;
4
5use Test::More;
6
7use lib 't/lib', 'extlib', 'lib', '../lib', '../extlib';
8use MT;
9
10use vars qw( $DB_DIR $T_CFG );
11use MT::Test;
12my $mt = MT->new() or die MT->errstr;
13
14SKIP: {
15if ( ! MT->component('enterprise') ) {
16    plan skip_all => "Enterprise pack is not installed.";
17} else {
18    plan tests => $number;
19}
20
21eval "require Net::LDAP;";
22if ($@) {
23    skip "Net::LDAP is not installed.", $number;
24}
25eval "require MT::LDAP;";
26if ($@) {
27    skip "MT::LDAP is not found.  Did you enable Enterprise Pack?", $number;
28}
29
30require MT::Author;
31require MT::Auth;
32require MT::LDAP;
33MT::Test->import( qw( :db :test ) );
34
35&ldapdelete( name => 'Bob D' );
36&ldapdelete( name => 'Axl Rose' );
37&ldapdelete( name => 'Chuck D' );
38&ldapdelete( name => 'Melody' );
39
40if (!MT->config->LDAPUserIdAttribute) {
41    print "Set LDAPUserIdAttribute directive or this test will fail.\n";
42}
43{
44&ldapadd(
45    name => 'Bob D',
46    email => 'bobd@example.com',
47    displayName => 'Dylan',
48);
49my ($entry) = &ldapsearch(
50                    filter => '(cn=Bob D)',
51                    attrs => [MT->config->LDAPUserIdAttribute]
52                );
53
54my $author = MT::Author->load({ name => 'Bob D' });
55ok($author);
56ok($author->is_active);
57$author->external_id($entry->get_value(MT->config->LDAPUserIdAttribute));
58$author->save;
59
60&ldapadd(
61    name => 'Chuck D',
62    email => 'chuckd@example.com',
63    displayName => 'Chuck',
64);
65my ($entry) = &ldapsearch(
66                    filter => '(cn=Chuck D)',
67                    attrs => [MT->config->LDAPUserIdAttribute]
68                );
69
70my $author0 = MT::Author->load({ name => 'Chuck D' });
71ok($author0);
72ok($author0->is_active);
73$author0->external_id($entry->get_value(MT->config->LDAPUserIdAttribute));
74$author0->save;
75
76&ldapadd(
77    name => 'Melody',
78    email => 'm@example.com',
79    displayName => 'Melody Nelson',
80);
81my ($entry) = &ldapsearch(
82                    filter => '(cn=Melody)',
83                    attrs => [MT->config->LDAPUserIdAttribute]
84                );
85
86my $author00 = MT::Author->load({ name => 'Melody' });
87ok($author00);
88ok($author00->is_active);
89$author00->external_id($entry->get_value(MT->config->LDAPUserIdAttribute));
90$author00->save;
91
92ok(0 == MT::Auth->synchronize); # nobody will be synched-updated at this point
93
94my $author2 = MT::Author->load({ name => 'Bob D' }, {cached_ok=>0});
95is($author->id, $author2->id);
96is($author->name, $author2->name);
97is($author->email, $author2->email);
98is($author->nickname, $author2->nickname);
99is($author->type, $author2->type);
100ok($author2->is_active);
101
102&ldapmodify(
103    name => 'Bob D',
104    newname => 'Axl Rose',
105    newemail => 'axl@example.com',
106    newnick => 'William Axl Rose'
107);
108
109is(MT::Auth->synchronize, 1);
110
111my $authorX = MT::Author->load({ name => 'Bob D' }, {cached_ok=>0});
112ok(!$authorX);
113my $author3 = MT::Author->load({ name => 'Axl Rose' }, {cached_ok=>0});
114ok($author3);
115is($author2->id, $author3->id);
116is('Axl Rose', $author3->name);
117is($author2->email, $author3->email);
118is($author2->nickname, $author3->nickname);
119is($author3->type, $author2->type);
120ok($author3->is_active);
121
122&ldapmodrdn(
123    name => 'Axl Rose',
124    newsuperior => 'ou=MT',
125);
126
127my $cfg = MT->config;
128my $ldapurl = $cfg->LDAPAuthURL;
129
130## typo will not make users inactive
131$cfg->LDAPAuthURL('ldap://trac.sixapart.jp/dc=typo,dc=sixapart,dc=jp');
132
133ok(!MT::Auth->synchronize);
134
135my $author4 = MT::Author->load({ name => 'Axl Rose' }, {cached_ok=>0});
136ok($author4->is_active);
137is($author4->external_id, $author3->external_id);
138
139my $author6 = MT::Author->load({ name => 'Chuck D' }, {cached_ok=>0});
140ok($author6->is_active);
141my $author7 = MT::Author->load({ name => 'Melody' }, {cached_ok=>0});
142ok($author7->is_active);
143
144## typo(but some users do exist in the directory) will not make users inactive
145## unless there is at lease one sysadmin in the (wrong) hierarchy
146my $wrong_url = $ldapurl;
147$wrong_url =~ s!(ldap://.+)/(.+)!$1/ou=MT,$2!;
148$cfg->LDAPAuthURL($wrong_url);
149
150ok(!MT::Auth->synchronize);
151
152my $author8 = MT::Author->load({ name => 'Axl Rose' }, {cached_ok=>0});
153ok($author8->is_active);
154is($author8->external_id, $author3->external_id);
155
156my $author9 = MT::Author->load({ name => 'Chuck D' }, {cached_ok=>0});
157ok($author9->is_active);
158my $author10 = MT::Author->load({ name => 'Melody' }, {cached_ok=>0});
159ok($author10->is_active);
160
161&ldapmodrdn( name => 'Axl Rose' );
162
163$cfg->LDAPAuthURL($ldapurl);
164
165&ldapdelete( name => 'Axl Rose' );
166
167ok(MT::Auth->synchronize);
168
169my $author11 = MT::Author->load({ name => 'Axl Rose' }, {cached_ok=>0});
170ok(!$author11->is_active);
171is($author11->external_id, $author3->external_id);
172
173&ldapadd(
174    name => 'Axl Rose',
175    email => 'axl@example.com',
176    displayName => 'William Axl Rose',
177);
178
179ok(0 == MT::Auth->synchronize);  ## this time it does not sync anyone -- synchronize returns 0
180
181my $author5 = MT::Author->load({ name => 'Axl Rose' }, {cached_ok=>0});
182ok($author5);
183ok(!$author5->is_active);  ## make sure newly created user with the same name does not re-activate an author.
184
185&ldapdelete( name => 'Axl Rose' );
186&ldapdelete( name => 'Chuck D' );
187&ldapdelete( name => 'Melody' );
188}
189
190} # end of SKIP block
191
192sub _ldapbind {
193    my ($auth, $ldap) = @_;
194    my $res;
195    my $base = $auth->{base};
196    my $bind_dn = $auth->{bind_dn};
197    my $bind_password = $auth->{bind_password};
198    my $sasl_mechanism = $auth->{sasl_mechanism};
199    my $uid_attr_name = $auth->{uid_attr_name};
200    my $filter = $auth->{filter};
201    my $scope = $auth->{scope};
202    if (!$bind_dn) {
203        $res = $ldap->bind;
204    } else {
205        if ($sasl_mechanism eq 'PLAIN') {
206            $res = $ldap->bind($bind_dn, password => $bind_password);
207        } else {
208            require Authen::SASL;
209            my $sasl = Authen::SASL->new(
210                mechanism => $sasl_mechanism,
211                callback => {
212                    pass => $bind_password,
213                    user => $bind_dn,
214                },
215            );
216            $res = $ldap->bind($bind_dn, sasl => $sasl);
217        }
218    }
219    1;
220}
221   
222sub ldapadd {
223    my (%opt) = @_;
224    my $auth = MT::LDAP->new;
225    my $ldap = $auth->ldap;
226    _ldapbind($auth, $ldap);
227    my $base = $auth->{base};
228    my $dn = "cn=$opt{name},$base";
229    my $result = $ldap->add( $dn,
230                        attr => [
231                         $auth->{uid_attr_name} => [$opt{name}],
232                         'cn'   => [$opt{name}],
233                         'sn'   => $opt{displayName},                         
234                         MT->config->LDAPUserEmailAttribute => $opt{email},
235                         'objectclass' => ['top', 'person',
236                                           'organizationalPerson',
237                                           'inetOrgPerson' ],
238                       ]
239                     );
240    $result->code && warn "failed to add entry: ", $result->error ;
241    my $mesg = $ldap->unbind;  # take down session
242    1;
243}
244
245sub ldapmodrdn {
246    my (%opt) = @_;
247    my $auth = MT::LDAP->new;
248    my $ldap = $auth->{ldap};
249    _ldapbind($auth, $ldap);
250    my $base = $auth->{base};
251    my $dn = "cn=$opt{name},$base";
252    my %param;
253    $param{newrdn} = "cn=$opt{name}";
254    if (exists $opt{newsuperior}) {
255        $param{newsuperior} = "$opt{newsuperior},$base";
256    } else {
257        my $new = $base;
258        $new =~ s!([^,]+),(.+)!$2!;
259        $param{newsuperior} = $new;
260    }
261    my $result = $ldap->moddn( $dn, %param );
262    $result->code && warn "failed to change rdn of the entry: ", $result->error ;
263    $result = $ldap->unbind;  # take down session
264    1;
265}
266
267sub ldapmodify {
268    my (%opt) = @_;
269    my $auth = MT::LDAP->new;
270    my $ldap = $auth->{ldap};
271    _ldapbind($auth, $ldap);
272    my $base = $auth->{base};
273    my $dn = "cn=$opt{name},$base";
274    my $result = $ldap->moddn( $dn, newrdn => "cn=$opt{newname}", deleteoldrdn => 1 );
275    warn $result->error if $result->code;
276    $dn = "cn=$opt{newname},$base";
277    $result = $ldap->modify( $dn,
278                        changes => [replace => [
279                         $auth->{uid_attr_name} => [$opt{newname}],
280                         'cn'   => $opt{newname},
281                         'sn'   => $opt{newname},                         
282                         MT->config->LDAPUserEmailAttribute => $opt{newemail},
283                        ] ]
284                     );
285    $result->code && warn "failed to modify entry $opt{name} -> $opt{newname}: ", $result->error ;
286    $result = $ldap->unbind;  # take down session
287    1;
288}
289
290sub ldapdelete {
291    my (%opt) = @_;
292    my $auth = MT::LDAP->new;
293    my $ldap = $auth->{ldap};
294    _ldapbind($auth, $ldap);
295    my $base = $auth->{base};
296    my $dn = "cn=$opt{name},$base";
297    my $result = $ldap->delete($dn);
298    $result->code && warn "failed to delete entry: ", $result->error ;
299    my $mesg = $ldap->unbind;  # take down session
300    1;
301}
302
303sub ldapsearch {
304    my (%opt) = @_;
305    my $auth = MT::LDAP->new;
306    my $ldap = $auth->{ldap};
307    _ldapbind($auth, $ldap);
308    my $base = $auth->{base};
309    my $res = $ldap->search(
310        base => $base,
311        filter => $opt{filter},
312        attrs => $opt{attrs},
313    );
314    $res->entries;
315}
316
3171;
Note: See TracBrowser for help on using the browser.