_Struct.pm 16.1 KB
Newer Older
Yadd's avatar
Yadd committed
1
2
3
4
5
## @file
# Manager tree structure and tests

## @class
# Manager tree structure and tests
Yadd's avatar
Yadd committed
6
7
8
9
10
package Lemonldap::NG::Manager::_Struct;

use strict;
our $VERSION = '0.1';

Yadd's avatar
Yadd committed
11
12
13
14
15
16
## @method protected hashref cstruct(hashref h,string k)
# Merge $h with the structure produced with $k and return it.
# Used to manage virtual hosts.
#@param $h Result of struct()
#@param $k Name of the virtual host
#@return Tree structure
Yadd's avatar
Yadd committed
17
18
19
20
21
22
23
24
25
26
27
28
sub cstruct {
    shift;
    my ( $h, $k ) = @_;
    %$h = (
        %$h,
        virtualHosts => {
            $k => {
                _nodes => [qw(rules:rules:rules headers)],
                rules  => {
                    _nodes => ["hash:/locationRules/$k:rules:rules"],
                    _js    => 'rulesRoot'
                },
Yadd's avatar
Yadd committed
29
30
31
32
                headers => {
                    _nodes => ["hash:/exportedHeaders/$k"],
                    _js    => 'hashRoot'
                },
Yadd's avatar
Yadd committed
33
34
35
36
37
38
            }
        }
    );
    return $h;
}

Yadd's avatar
Yadd committed
39
40
41
42
43
## @method protected hashref struct(hashref h,string k)
# Returns the tree structure
#@param $h Result of struct()
#@param $k Name of the virtual host
#@return Tree structure
Yadd's avatar
Yadd committed
44
sub struct {
45
    my $self = shift;
Yadd's avatar
Yadd committed
46
47
48
    return {
        _nodes            => [qw(n:generalParameters n:groups n:virtualHosts)],
        _help             => 'default',
49
50
51
52

	######################
	# GENERAL PARAMETERS #
	######################
Yadd's avatar
Yadd committed
53
54
        generalParameters => {
            _nodes => [
55
                qw(portal n:authParams logParams cookieParams cn:exportedVars cn:macros sessionParams n:advancedParams)
Yadd's avatar
Yadd committed
56
57
            ],
            _help      => 'default',
58
59
60
            portal     => 'text:/portal',
	    
	    # AUTHENTICATION AND USERDB PARAMETERS
Yadd's avatar
Yadd committed
61
            authParams => {
62
63
64
65

		# Displayed nodes depend on authentication/userDB modules choosed
                _nodes => sub {
                    my $self = shift;
Yadd's avatar
Yadd committed
66
                    my $auth = $self->conf->{authentication}
67
                      || $self->defaultConf()->{authentication};
Yadd's avatar
Yadd committed
68
                    my $udb = $self->conf->{userDB}
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
                      || $self->defaultConf()->{userDB};
                    $auth = lc($auth);
                    $udb  = lc($udb);
                    my %res = qw(authentication 1 userDB 1 syslog 1);
                    foreach my $mod ( ( $auth, ( $auth ne $udb ? $udb : () ) ) )
                    {
                        my $tmp = {
                            ldap => ['ldapParams'],
                            ssl  => [qw(ldapParams SSLRequired)],
                        }->{$mod};
                        if ($tmp) {
                            $res{$_}++ foreach (@$tmp);
                        }
                    }
                    my @u = keys %res;
                    return \@u;
                },
                _help          => 'authParams',
                authentication => 'text:/authentication:authParams:authParams',
                userDB         => 'text:/userDB:authParams:authParams',
                syslog         => 'text:/syslog',
                ldapParams     => {
                    _nodes => [
                        qw(ldapServer ldapPort ldapBase managerDn managerPassword)
                    ],
                    _help           => 'ldap',
                    ldapServer      => 'text:/ldapServer',
                    ldapPort        => 'int:/ldapPort',
                    ldapBase        => 'text:/ldapBase',
                    managerDn       => 'text:/managerDn',
                    managerPassword => 'text:/managerPassword',
                },
                SSLRequired => 'int:/SSLRequired',
            },

	    # LOGS PARAMETERS
            logParams => {
                _nodes             => [qw(useXForwardedForIP whatToTrace)],
Yadd's avatar
Yadd committed
107
                useXForwardedForIP => 'int:/useXForwardedForIP',
108
                whatToTrace        => 'text:/whatToTrace:whatToTrace:text',
Yadd's avatar
Yadd committed
109
            },
110
111

	    # COOKIE PARAMETERS
Yadd's avatar
Yadd committed
112
            cookieParams => {
Yadd's avatar
Yadd committed
113
114
                _nodes =>
                  [qw(cookieName domain securedCookie cookieExpiration)],
115
                _help      => 'cookies',
Yadd's avatar
Yadd committed
116
117
118
119
                cookieName => 'text:/cookieName:cookieName:text',
                domain     => 'text:/domain:domain:text',
                securedCookie =>
                  'int:/securedCookie:securedCookie:securedCookieValues',
Yadd's avatar
Yadd committed
120
                cookieExpiration => 'text:/cookieExpiration',
Yadd's avatar
Yadd committed
121
            },
122
123

	    # EXPORTED ATTRIBUTES
Yadd's avatar
Yadd committed
124
125
126
127
            exportedVars => {
                _nodes => ['hash:/exportedVars:vars:btext'],
                _js    => 'hashRoot'
            },
128
129

	    # MACROS
Yadd's avatar
Yadd committed
130
131
            macros =>
              { _nodes => ['hash:/macros:macros:btext'], _js => 'hashRoot' },
132
133

	    # SESSIONS PARAMETERS
Yadd's avatar
Yadd committed
134
            sessionParams => {
135
136
137
                _nodes => [
                    qw(sessionStorage singleSession singleIP singleUserByIP timeout storePassword)
                ],
Yadd's avatar
Yadd committed
138
139
140
141
142
143
144
145
146
                _help          => 'storage',
                sessionStorage => {
                    _nodes        => [qw(globalStorage globalStorageOptions)],
                    globalStorage => 'text:/globalStorage',
                    globalStorageOptions => {
                        _nodes => ['hash:/globalStorageOptions'],
                        _js    => 'hashRoot'
                    },
                },
147
148
149
150
151
                singleSession  => 'int:/singleSession',
                singleIP       => 'int:/singleIP',
                singleUserByIP => 'int:/singleUserByIP',
                storePassword => 'int:/storePassword',
                timeout        => 'text:/timeout:timeout:text',
Yadd's avatar
Yadd committed
152
            },
153
154

	    # OTHER PARAMETERS
Yadd's avatar
Yadd committed
155
156
            advancedParams => {
                _nodes => [
157
                    qw(Soap exportedAttr trustedDomains https notifications passwordManagement userControl)
Yadd's avatar
Yadd committed
158
                ],
159
                Soap          => 'int:/Soap',
Yadd's avatar
Yadd committed
160
                https         => 'int:/https',
161
                exportedAttr  => 'text:/exportedAttr',
Yadd's avatar
Yadd committed
162
163
164
165
                notifications => {
                    _nodes => [
                        qw(notification notificationStorage notificationStorageOptions)
                    ],
166
                    _help                      => 'notifications',
Yadd's avatar
Yadd committed
167
                    notification               => 'int:/notification',
168
                    notificationStorage        => 'text:/notificationStorage',
Yadd's avatar
Yadd committed
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
                    notificationStorageOptions => {
                        _nodes => ['hash:/notificationStorageOptions'],
                        _js    => 'hashRoot'
                    },
                },
                passwordManagement => {
                    _nodes => [
                        qw(passwordDB SMTPServer mailFrom mailSubject randomPasswordRegexp mailBody)
                    ],
                    passwordDB           => 'text:/passwordDB',
                    SMTPServer           => 'text:/SMTPServer',
                    mailFrom             => 'text:/mailFrom',
                    mailSubject          => 'text:/mailSubject',
                    randomPasswordRegexp => 'text:/randomPasswordRegexp',
                    mailBody             => 'text:/mailBody',
                },
                trustedDomains => 'text:/trustedDomains',
186
                userControl    => 'text:/userControl:userControl:text',
Yadd's avatar
Yadd committed
187
            }
Yadd's avatar
Yadd committed
188
        },
189
190
191
192

	##########
	# GROUPS #
	##########
193
194
195
196
197
        groups => {
            _nodes => ['hash:/groups:groups:btext'],
            _js    => 'hashRoot',
            _help  => 'default',
        },
198
199
200
201

	#################
	# VIRTUAL HOSTS #
	#################
202
203
204
205
206
        virtualHosts => {
            _nodes  => ['nhash:/locationRules:virtualHosts:none'],
            _upload => ['/exportedHeaders'],
            _help   => 'default',
        },
Yadd's avatar
Yadd committed
207
208
209
    };
}

Yadd's avatar
Yadd committed
210
211
212
## @method protected hashref testStruct()
# Returns the tests to do with the datas uploaded.
# @return hashref
Yadd's avatar
Yadd committed
213
214
215
216
217
218
219
220
221
sub testStruct {
    my $assignTest = qr/(?<=[^=<!>\?])=(?![=~])/;
    my $assignMsg  = 'containsAnAssignment';
    my $perlExpr   = sub {
        my $e = shift;
        eval "use strict;$e";
        return 1 if ( $@ =~ /Global symbol "\$.*requires explicit package/ );
        return ( $@ ? ( 0, $@ ) : 1 );
    };
Yadd's avatar
Yadd committed
222
    my $boolean = { test => qr/^(?:0|1)?$/, msgFail => 'Value must be 0 or 1' };
223
224
225
226
227
228
229
    my $pcre = sub {
        my $r = shift;
        my $q;
        eval { $q = qr/$r/ };
        return ( $@ ? ( 0, $@ ) : 1 );
    };
    my $testNotDefined = { test => sub { 1 }, msgFail => 'Ok' };
230

Yadd's avatar
Yadd committed
231
    return {
232
233
234
235
236
237
238
239
240
241
242
        mailFrom             => $testNotDefined,
        trustedDomains       => $testNotDefined,
        exportedAttr         => $testNotDefined,
        mailSubject          => $testNotDefined,
        randomPasswordRegexp => $testNotDefined,
        passwordDB           => $testNotDefined,
        mailBody             => $testNotDefined,
        SMTPServer           => $testNotDefined,
        cookieExpiration     => $testNotDefined,
        notificationStorage  => $testNotDefined,
        authentication       => {
Yadd's avatar
Yadd committed
243
244
245
            test    => qr/^[a-zA-Z][\w\:]*$/,
            msgFail => 'Bad module name',
        },
246
        cda        => $boolean,
Yadd's avatar
Yadd committed
247
248
249
250
251
252
253
254
        cookieName => {
            test    => qr/^[a-zA-Z]\w*$/,
            msgFail => 'Bad cookie name',
        },
        domain => {
            test    => qr/^\.?\w+(?:\.[a-zA-Z]\w*)*(?:\.[a-zA-Z]+)$/,
            msgFail => 'Bad domain',
        },
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
        exportedHeaders => {
            keyTest    => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
            keyMsgFail => 'Bad virtual host name',
            '*'        => {
                keyTest    => qr/^\w([\w\-]*\w)?$/,
                keyMsgFail => 'Bad header name',
                test       => $perlExpr,
                warnTest   => sub {
                    my $e = shift;
                    return ( 0, $assignMsg ) if ( $e =~ $assignTest );
                    1;
                },
            },
        },
        exportedVars => {
            keyTest    => qr/^[a-zA-Z]\w*$/,
            keyMsgFail => 'Bad variable name',
            test       => qr/^[a-zA-Z]\w*$/,
            msgFail    => 'Bad attribute name',
Yadd's avatar
Yadd committed
274
275
276
277
278
279
280
281
282
        },
        globalStorage => {
            test    => qr/^[\w:]+$/,
            msgFail => 'Bad module name',
        },
        globalStorageOptions => {
            keyTest    => qr/^\w+$/,
            keyMsgFail => 'Bad parameter',
        },
283
284
285
286
287
288
289
290
291
292
293
        groups => {
            keyTest    => qr/^\w[\w-]*$/,
            keyMsgFail => 'Bad group name',
            test       => $perlExpr,
            warnTest   => sub {
                my $e = shift;
                return ( 0, $assignMsg ) if ( $e =~ $assignTest );
                1;
            },
        },
        https    => $boolean,
Yadd's avatar
Yadd committed
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
        ldapBase => {
            test    => qr/^(?:\w+=.*|)$/,
            msgFail => 'Bad LDAP base',
        },
        ldapPort => {
            test    => qr/^\d*$/,
            msgFail => 'Bad port number'
        },
        ldapServer => {
            test => sub {
                my $l = shift;
                my @s = split( /[\s,]+/, $l );
                foreach my $s (@s) {
                    $s =~
/^(?:ldap(?:s|\+tls|i):\/\/)?\w[\w\-\.]+\w(?::\d{0,5})?\/?$/
                      or return ( 0, "Bad ldap uri \"$s\"" );
                }
                return 1;
            },
        },
        locationRules => {
            keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
            msgFail => 'Bad virtual host name',
            '*'     => {
318
319
                keyTest => $pcre,
                test    => sub {
Yadd's avatar
Yadd committed
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
                    my $e = shift;
                    return 1 if ( $e eq 'accept' or $e eq 'deny' );
                    if ( $e =~ s/^logout(?:_(?:app|sso|app_sso))?\s*// ) {
                        return (
                            $e =~ /^(?:https?:\/\/\S+)?$/
                            ? 1
                            : ( 0, "bad url \"$e\"" )
                        );
                    }
                    return &$perlExpr($e);
                },
                warnTest => sub {
                    my $e = shift;
                    return ( 0, $assignMsg )
                      if (  $e =~ $assignTest
                        and $e !~ /^(?:accept|deny|logout)/ );
                    1;
                },
            },
        },
340
341
342
        macros => {
            keyTest    => qr/^[a-zA-Z]\w*$/,
            keyMsgFail => 'Bad macro name',
Yadd's avatar
Yadd committed
343
344
345
346
347
348
349
                test       => $perlExpr,
                warnTest   => sub {
                    my $e = shift;
                    return ( 0, $assignMsg ) if ( $e =~ $assignTest );
                    1;
                },
            },
350
351
352
353
354
        managerDn => {
            test    => qr/^(?:\w+=.*,\w+=.*)?$/,
            msgFail => 'Bad LDAP dn',
        },
        managerPassword => {
Yadd's avatar
Yadd committed
355
            test    => qr/^\S*$/,
356
            msgFail => 'Bad LDAP password',
Yadd's avatar
Yadd committed
357
        },
358
        notification  => $boolean,
359
360
361
362
363
364
365
366
367
368
369
370
        notificationStorage => {
            test    => qr/^[\w:]+$/,
            msgFail => 'Bad module name',
        },
        notificationStorageOptions => {
            keyTest    => qr/^\w+$/,
            keyMsgFail => 'Bad parameter',
        },
        portal => {
            test    => qr/^https?:\/\/\S+$/,
            msgFail => 'Bad portal value',
        },
Yadd's avatar
Yadd committed
371
372
373
374
        protection    => {
            keyTest => qr/^(?:none|authentificate|manager|)$/,
            msgFail => 'must be one of none authentificate manager',
        },
375
376
377
378
        securedCookie => {
            test    => qr/^(?:0|1|2)$/,
            msgFail => 'securedCookie must be 0, 1 or 2',
        },
Yadd's avatar
Yadd committed
379
380
381
        singleSession      => $boolean,
        singleIP           => $boolean,
        singleUserByIP     => $boolean,
382
383
384
385
386
387
388
389
390
391
392
393
        Soap           => $boolean,
        SSLRequired    => $boolean,
        storePassword  => $boolean,
        syslog         => {
            test => qw/^(?:auth|authpriv|daemon|local\d|user)?$/,
            msgFail =>
              'Only auth|authpriv|daemon|local0-7|user is allowed here',
        },
        timeout => {
            test    => qr/^\d*$/,
            msgFail => 'Bad number'
        },
394
395
396
397
        userControl        => {
            test    => $pcre,
            msgFail => 'Bad regular expression',
        },
398
399
400
401
402
403
404
405
406
        userDB => {
            test    => qr/^[a-zA-Z][\w\:]*$/,
            msgFail => 'Bad module name',
        },
        useXForwardedForIP => $boolean,
        whatToTrace        => {
            test    => qr/^\$?[a-zA-Z]\w*$/,
            msgFail => 'Bad value',
        },
Yadd's avatar
Yadd committed
407
408
409
    };
}

Yadd's avatar
Yadd committed
410
411
## @method protected hashref defaultConf()
#@return Hashref of default values
Yadd's avatar
Yadd committed
412
413
sub defaultConf {
    return {
414
        authentication       => 'LDAP',
415
416
417
        cda                  => '0',
        cookieName           => 'lemonldap',
        domain               => 'example.com',
Yadd's avatar
Yadd committed
418
        exportedHeaders => { 'test.example.com' => { 'Auth-User' => '$uid' }, },
419
        exportedVars         => { cn => 'cn', mail => 'mail', uid => 'uid', },
420
        globalStorage        => 'Apache::Session::File',
Yadd's avatar
Yadd committed
421
        globalStorageOptions => {
422
            'Directory'     => '/var/lib/lemonldap-ng/sessions/',
Yadd's avatar
Yadd committed
423
424
            'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock/'
        },
425
426
427
428
        https               => '0',
        ldapBase            => 'dc=example,dc=com',
        ldapPort            => '389',
        ldapServer          => 'localhost',
Yadd's avatar
Yadd committed
429
        locationRules   => { 'test.example.com' => { default => 'accept' }, },
430
431
432
        managerDn           => '',
        managerPassword     => '',
        notification        => '0',
433
        notificationStorage => 'File',
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
        notificationStorageOptions =>
          { dirName => '/var/lib/lemonldap-ng/notifications', },
        portal             => 'http://auth.example.com/',
        protection         => 'none',
        securedCookie      => '0',
        singleSession      => '0',
        singleIP           => '0',
        singleUserByIP     => '0',
        Soap               => '1',
        SSLRequired        => '0',
        storePassword      => '0',
        syslog             => '',
        timeout            => '7200',
        userControl        => '^[\w\.\-@]+$',
        userDB             => 'LDAP',
        useXForwardedForIP => '0',
        whatToTrace        => '$uid',
Yadd's avatar
Yadd committed
451
452
453
    };
}

Yadd's avatar
Yadd committed
454
455
456
457
458
459
460
sub subDefaultConf {
    return {
        locationRules   => { default     => 'deny' },
        exportedHeaders => { 'Auth-User' => '$uid' },
    };
}

Yadd's avatar
Yadd committed
461
1;