65_user_ldap.t 11.5 KB
Newer Older
Francesc Guasch's avatar
Francesc Guasch committed
1
2
3
4
5
use warnings;
use strict;

use Data::Dumper;
use Test::More;
6
use YAML qw(LoadFile DumpFile);
Francesc Guasch's avatar
Francesc Guasch committed
7

8
9
10
no warnings "experimental::signatures";
use feature qw(signatures);

Francesc Guasch's avatar
Francesc Guasch committed
11
12
13
use lib 't/lib';
use Test::Ravada;

Francesc Guasch's avatar
Francesc Guasch committed
14
15
16
use_ok('Ravada');
use_ok('Ravada::Auth::LDAP');

17
my $ADMIN_GROUP = "test.admin.group";
Francesc Guasch's avatar
Francesc Guasch committed
18
my $RAVADA_POSIX_GROUP = "rvd_posix_group";
Francesc Guasch's avatar
Francesc Guasch committed
19

Francesc Guasch's avatar
Francesc Guasch committed
20
my ($LDAP_USER , $LDAP_PASS) = ("cn=Directory Manager","saysomething");
21

Francesc Guasch's avatar
Francesc Guasch committed
22
init();
23
24

my @USERS;
Francesc Guasch's avatar
Francesc Guasch committed
25
26
27
28
29
30
31
32
33

sub test_user_fail {
    my $user_fail;
    eval { $user_fail = Ravada::Auth::LDAP->new(name => 'root',password => 'fail')};
    
    ok(!$user_fail,"User should fail, got ".Dumper($user_fail));
}
    
sub test_user{
34
    my $name = (shift or 'jimmy.mcnulty');
Francesc Guasch's avatar
Francesc Guasch committed
35
    my $with_posix_group = ( shift or 0);
Francesc Guasch's avatar
Francesc Guasch committed
36
37
    my $password = 'jameson';

38
39
40
41
42
43
44
45
    if ( Ravada::Auth::LDAP::search_user($name) ) {
        diag("Removing $name");
        Ravada::Auth::LDAP::remove_user($name)  
    }

    my $user = Ravada::Auth::LDAP::search_user($name);
    ok(!$user,"I shouldn't find user $name in the LDAP server") or return;

Francesc Guasch's avatar
Francesc Guasch committed
46
47
    my $user_db = Ravada::Auth::SQL->new( name => $name);
    $user_db->remove();
48
49
    # check for the user in the SQL db, he shouldn't be  there
    #
Francesc Guasch's avatar
Francesc Guasch committed
50
    my $sth = connector->dbh->prepare("SELECT * FROM users WHERE name=?");
51
52
53
54
55
56
    $sth->execute($name);
    my $row = $sth->fetchrow_hashref;
    $sth->finish;
    ok(!$row->{name},"I shouldn't find $name in the SQL db ".Dumper($row));


Francesc Guasch's avatar
Francesc Guasch committed
57
    eval { Ravada::Auth::LDAP::add_user($name,$password) };
58
59
60
    push @USERS,($name);

    ok(!$@,$@) or return;
Francesc Guasch's avatar
Francesc Guasch committed
61
62
63

    _add_to_posix_group($name);

64
    my $mcnulty;
Francesc Guasch's avatar
Francesc Guasch committed
65
    eval { $mcnulty = Ravada::Auth::LDAP->new(name => $name,password => $password) };
Francesc Guasch's avatar
Francesc Guasch committed
66
    is($@,'', Dumper($Ravada::CONFIG)) or exit;
Francesc Guasch's avatar
Francesc Guasch committed
67

68
    ok($mcnulty,($@ or "ldap login failed for $name")) or return;
69
70
    ok(ref($mcnulty) =~ /Ravada/i,"User must be Ravada::Auth::LDAP , it is '".ref($mcnulty));

Francesc Guasch's avatar
Francesc Guasch committed
71
72
    ok(!$mcnulty->is_admin,"User ".$mcnulty->name." should not be admin "
            .Dumper($mcnulty->{_data}));
73

74
    # try to login
Francesc Guasch's avatar
Francesc Guasch committed
75
    my $mcnulty_login = Ravada::Auth::login($name,$password);
76
77
78
    ok($mcnulty_login,"No login");
    ok(ref $mcnulty_login && ref($mcnulty_login) eq 'Ravada::Auth::LDAP',
            "ref should be Ravada::Auth::LDAP , got ".ref($mcnulty_login));
79
80
    # check for the user in the SQL db
    # 
Francesc Guasch's avatar
Francesc Guasch committed
81
    $sth = connector->dbh->prepare("SELECT * FROM users WHERE name=?");
82
83
84
85
86
    $sth->execute($name);
    $row = $sth->fetchrow_hashref;
    $sth->finish;
    ok($row->{name} && $row->{name} eq $name 
        && $row->{id},"I can't find $name in the users SQL table ".Dumper($row));
87
88
89
90

    my $mcnulty_sql = Ravada::Auth::SQL->new(name => $name);
    ok($mcnulty_sql,"I can't find mcnulty in the SQL db");
    ok($mcnulty_sql->{name} eq $name, "Expecting '$name', got $mcnulty_sql->{name}");
91
92
93
94
    
    # login again to check it doesn't get added twice
 
    my $mcnulty2;
Francesc Guasch's avatar
Francesc Guasch committed
95
    eval { $mcnulty2 = Ravada::Auth::LDAP->new(name => $name,password => $password) };
96
97
    
    ok($mcnulty2,($@ or "ldap login failed for $name")) or return;
Francesc Guasch's avatar
Francesc Guasch committed
98
    $sth = connector->dbh->prepare("SELECT count(*) FROM users WHERE name=?");
99
100
101
102
103
104
    $sth->execute($name);
    my ($count) = $sth->fetchrow;
    $sth->finish;
    
    ok($count == 1,"Found $count $name, expecting 1");

Francesc Guasch's avatar
Francesc Guasch committed
105
106
107
108
109
110
111
112
113
114
115
116
117
118
    my $auth_ok;
    eval { $auth_ok = Ravada::Auth::login($name, $password)};
    is($@,'');
    ok($auth_ok,"Expecting auth_ok: ".Dumper($auth_ok));
    is($auth_ok->is_external,1);

    my $user_sql = Ravada::Auth::SQL->new(name => $name);
    ok($user_sql,"Expecting a SQL user for $name");
    ok($user_sql->is_external,"Expecting is_external");

    $auth_ok = undef;
    eval { $auth_ok = Ravada::Auth::login($name, 'fail','quiet')};
    ok($@,"Expecting fails, got : ".($@ or ''));
    ok(!$auth_ok,"Expecting no auth_ok. got: ".Dumper($auth_ok));
119

120
    return $mcnulty;
Francesc Guasch's avatar
Francesc Guasch committed
121
}
122
123
124
125
126
127
128
129
130
131
132

sub remove_users {
    for my $name (@USERS) {
        my $user = Ravada::Auth::LDAP::search_user($name);
        next if !$user;
        Ravada::Auth::LDAP::remove_user($name);

        $user = Ravada::Auth::LDAP::search_user($name);
        ok(!$user,"I shouldn't find user $name in the LDAP server") or return;
    }
}
133
134
135
136
137

sub test_add_group {

    my $name = "grup.test";

138
    Ravada::Auth::LDAP::remove_group($name)
139
        if Ravada::Auth::LDAP::search_group(name => $name);
140

141
    my $group0 = Ravada::Auth::LDAP::search_group(name => $name);
142
143
    ok(!$group0,"Group $name shouldn't exist") or return;

144
145
    Ravada::Auth::LDAP::add_group($name);

146
    my $group = Ravada::Auth::LDAP::search_group(name => $name);
147
148
149
150
    ok($group,"Group $name not created");

    Ravada::Auth::LDAP::remove_group($name) if $group;

151
    my $group2 = Ravada::Auth::LDAP::search_group(name => $name);
152
153
154
    ok(!$group2,"Group $name not removed");

}
155
156

sub test_manage_group {
Francesc Guasch's avatar
Francesc Guasch committed
157
    my $with_admin = shift;
Francesc Guasch's avatar
Francesc Guasch committed
158
    my $with_posix_group = shift;
159
160
161

    my $name = $ADMIN_GROUP;

Francesc Guasch's avatar
Francesc Guasch committed
162
163
    diag("Testing LDAP admin with group $ADMIN_GROUP enabled= $with_admin");

164
165
166
167
168
169
170
171
172
173
174
175
    Ravada::Auth::LDAP::remove_group($name)
        if Ravada::Auth::LDAP::search_group(name => $name);

    my $group0 = Ravada::Auth::LDAP::search_group(name => $name);
    ok(!$group0,"Group $name shouldn't exist") or return;

    Ravada::Auth::LDAP::add_group($name);

    my $group = Ravada::Auth::LDAP::search_group(name => $name);
    ok($group,"Group $name not created") or return;

    my $uid = 'ragnar.lothbrok';
Francesc Guasch's avatar
Francesc Guasch committed
176
    my $user = test_user($uid, $with_posix_group);
Francesc Guasch's avatar
Francesc Guasch committed
177

178
179
180
181
    my $is_admin;
    eval { $is_admin = $user->is_admin };
    ok(!$@,$@);
    ok(!$is_admin,"User $uid should not be admin");
182
183

    Ravada::Auth::LDAP::add_to_group($uid, $name);
Francesc Guasch's avatar
Francesc Guasch committed
184
185
186
187
188
189
190
191
192
193
194
195
196
197

    if ($with_admin) {

        my $admin_group = $$Ravada::Auth::LDAP::CONFIG->{ldap}->{admin_group};
        SKIP: {
            if (!$admin_group) {
                diag("Missing admin_group in config file , got : \n"
                        .Dumper($$Ravada::Auth::LDAP::CONFIG->{ldap}));
                skip("No admin group defined",1);
            }
            ok($user->is_admin,"User $uid (".(ref $user).") "
                            ."should be admin, he was added to $name  group") or exit;
        };
    }
198
199
200
201
202
203
204
205
206

    Ravada::Auth::LDAP::remove_user($uid);
    Ravada::Auth::LDAP::remove_group($name);

    my $group2 = Ravada::Auth::LDAP::search_group(name => $name);
    ok(!$group2,"Group $name not removed");

}

207
208
sub test_user_bind {
    my $file_config = shift;
Francesc Guasch's avatar
Francesc Guasch committed
209
    my $with_posix_group = shift;
210
211
212
213
214
215
216

    my $config = LoadFile($file_config);
    $config->{ldap}->{auth} = 'bind';

    my $file_config_bind = "/var/tmp/ravada_test_ldap_bind_$$.conf";
    DumpFile($file_config_bind, $config);
    my $ravada = Ravada->new(config => $file_config_bind
Francesc Guasch's avatar
Francesc Guasch committed
217
        , connector => connector);
218
219
220

    Ravada::Auth::LDAP::init();

Francesc Guasch's avatar
Francesc Guasch committed
221
222
    _add_to_posix_group('jimmy.mcnulty') if $with_posix_group;

223
224
225
226
227
228
    my $mcnulty;
    eval { $mcnulty = Ravada::Auth::LDAP->new(name => 'jimmy.mcnulty',password => 'jameson') };
    is($@,'');

    ok($mcnulty,($@ or "ldap login failed ")) or return;

229
230
    is($mcnulty->{_auth}, 'bind');

231
232
233
    unlink $file_config_bind;

    $ravada = Ravada->new(config => $file_config
Francesc Guasch's avatar
Francesc Guasch committed
234
        , connector => connector);
235
236
237
238
239

    Ravada::Auth::LDAP::_init_ldap_admin();

}

240
sub _init_config($file_config, $with_admin, $with_posix_group) {
Francesc Guasch's avatar
Francesc Guasch committed
241
242
    if ( ! -e $file_config) {
        my $config = {
Francesc Guasch's avatar
Francesc Guasch committed
243
244
245
246
        ldap => {
            admin_user => { dn => $LDAP_USER , password => $LDAP_PASS }
            ,base => "dc=example,dc=com"
            ,admin_group => $ADMIN_GROUP
247
            ,auth => 'match'
Francesc Guasch's avatar
Francesc Guasch committed
248
            ,ravada_posix_group => $RAVADA_POSIX_GROUP
Francesc Guasch's avatar
Francesc Guasch committed
249
        }
Francesc Guasch's avatar
Francesc Guasch committed
250
251
252
253
        };
        DumpFile($file_config,$config);
    }
    my $config = LoadFile($file_config);
Francesc Guasch's avatar
Francesc Guasch committed
254
    delete $config->{ldap}->{admin_group}   if !$with_admin;
255
256
257
258
259
260
261
262
263
    if ($with_posix_group) {
        if ( !exists $config->{ldap}->{ravada_posix_group}
                || !$config->{ldap}->{ravada_posix_group}) {
            $config->{ldap}->{ravada_posix_group} = $RAVADA_POSIX_GROUP;
            diag("Adding ravada_posix_group = $RAVADA_POSIX_GROUP in $file_config");
        }
    } else {
        delete $config->{ldap}->{ravada_posix_group};
    }
Francesc Guasch's avatar
Francesc Guasch committed
264

265
    $config->{vm}=['KVM','Void'];
Francesc Guasch's avatar
Francesc Guasch committed
266
267
    delete $config->{ldap}->{ravada_posix_group}   if !$with_posix_group;

Francesc Guasch's avatar
Francesc Guasch committed
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
    my $fly_config = "/var/tmp/$$.config";
    DumpFile($fly_config, $config);
    return $fly_config;
}

sub _add_posix_group {
    my $ldap = Ravada::Auth::LDAP::_init_ldap_admin();

    my $base = "ou=groups,".Ravada::Auth::LDAP::_dc_base();

    my $mesg = $ldap->add(
        cn => $RAVADA_POSIX_GROUP
        ,dn => "cn=$RAVADA_POSIX_GROUP,$base"
        ,attrs => [ cn => $RAVADA_POSIX_GROUP
                    ,objectClass=> [ 'posixGroup' ]
                    ,gidNumber => 999
                ]
    );
    die "Error ".$mesg->code." adding $RAVADA_POSIX_GROUP ".$mesg->error
        if $mesg->code && $mesg->code != 68;

    $mesg = $ldap->search( filter => "cn=$RAVADA_POSIX_GROUP",base => $base );
    my @group = $mesg->entries;
    ok($group[0],"Expecting group $RAVADA_POSIX_GROUP") or return;
    return $group[0];
}

sub _add_to_posix_group {
    my $user_name = shift;
    my $group = _add_posix_group();

    my $ldap = Ravada::Auth::LDAP::_init_ldap_admin();
    $group->add(memberUid => $user_name);
    my $mesg = $group->update($ldap);
    die $mesg->code." ".$mesg->error if $mesg->code && $mesg->code != 20;
}

sub test_posix_group {
    my $with_posix_group = shift;
    my $group = _add_posix_group();

    my ($user_name, $password) = ('mcnulty_'.new_domain_name(), 'jameson');
    my $user = create_ldap_user($user_name, $password);

    my $user_login;
    eval { $user_login= Ravada::Auth::LDAP->new(name => $user_name,password => $password) };
    my $error = $@;
    if ($with_posix_group) {
        ok(!$user_login,"Expecting no login $user_name with posix group ".Dumper($Ravada::CONFIG));
        like($error,qr(Login failed));
    } else {
        ok($user_login);
    }
    _add_to_posix_group($user_name);

    eval { $user_login= Ravada::Auth::LDAP->new(name => $user_name,password => $password) };
    is($@,'');
    ok($user_login);

    my $ldap = Ravada::Auth::LDAP::_init_ldap_admin();
    my $mesg = $ldap->delete($user);
    die $mesg->code." ".$mesg->error if $mesg->code && $mesg->code;

    $mesg = $ldap->delete($group);
    die $mesg->code." ".$mesg->error if $mesg->code && $mesg->code;

Francesc Guasch's avatar
Francesc Guasch committed
334
335
}

Francesc Guasch's avatar
Francesc Guasch committed
336
SKIP: {
Francesc Guasch's avatar
Francesc Guasch committed
337
338
339
    my $file_config = "t/etc/ravada_ldap.conf";
    for my $with_posix_group (0,1) {
    for my $with_admin (0,1) {
340

341
        my $fly_config = _init_config($file_config, $with_admin, $with_posix_group);
Francesc Guasch's avatar
Francesc Guasch committed
342
        my $ravada = Ravada->new(config => $fly_config
Francesc Guasch's avatar
Francesc Guasch committed
343
                        , connector => connector);
Francesc Guasch's avatar
Francesc Guasch committed
344
345
        $ravada->_install();
        Ravada::Auth::LDAP::init();
346
347
348
349
350
351
352

        if ($with_posix_group) {
            ok($Ravada::CONFIG->{ldap}->{ravada_posix_group},
                    "Expecting ravada_posix_group on $fly_config\n"
                        .Dumper($Ravada::CONFIG->{ldap}))
                or exit;
        }
Francesc Guasch's avatar
Francesc Guasch committed
353
        my $ldap;
354

Francesc Guasch's avatar
Francesc Guasch committed
355
        eval { $ldap = Ravada::Auth::LDAP::_init_ldap_admin() };
Francesc Guasch's avatar
Francesc Guasch committed
356

Francesc Guasch's avatar
Francesc Guasch committed
357
358
359
360
361
        if ($@ =~ /Bad credentials/) {
            diag("$@\nFix admin credentials in $file_config");
        } else {
            diag("Skipped LDAP tests ".($@ or '')) if !$ldap;
        }
Francesc Guasch's avatar
Francesc Guasch committed
362

Francesc Guasch's avatar
Francesc Guasch committed
363
        skip( ($@ or "No LDAP server found"),6) if !$ldap && $@ !~ /Bad credentials/;
364

Francesc Guasch's avatar
Francesc Guasch committed
365
        ok($ldap) and do {
Francesc Guasch's avatar
Francesc Guasch committed
366

Francesc Guasch's avatar
Francesc Guasch committed
367
            test_user_fail();
Francesc Guasch's avatar
Francesc Guasch committed
368
            test_user( );
369

Francesc Guasch's avatar
Francesc Guasch committed
370
371
            test_add_group();
            test_manage_group($with_admin);
Francesc Guasch's avatar
Francesc Guasch committed
372
            test_posix_group($with_posix_group);
Francesc Guasch's avatar
Francesc Guasch committed
373

Francesc Guasch's avatar
Francesc Guasch committed
374
            test_user_bind($fly_config, $with_posix_group);
375

Francesc Guasch's avatar
Francesc Guasch committed
376
377
            remove_users();
        };
Francesc Guasch's avatar
Francesc Guasch committed
378
379
        unlink($fly_config) if -e $fly_config;
    }
Francesc Guasch's avatar
Francesc Guasch committed
380
    }
Francesc Guasch's avatar
Francesc Guasch committed
381
};
Francesc Guasch's avatar
Francesc Guasch committed
382

Francesc Guasch's avatar
Francesc Guasch committed
383
done_testing();