root/branches/boomer/t/51-objectsync.t @ 1098

Revision 1098, 8.8 kB (checked in by hachi, 2 years ago)

Branching for boomer from release-19, rev 62318

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