File Coverage

blib/lib/Lemonldap/NG/Manager/_Struct.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             ## @file
2             # Manager tree structure and tests
3              
4             ## @class
5             # Manager tree structure and tests
6             package Lemonldap::NG::Manager::_Struct;
7              
8 1     1   16591 use strict;
  1         1  
  1         30  
9 1     1   202 use Lemonldap::NG::Common::Conf::SAML::Metadata;
  0            
  0            
10             use Lemonldap::NG::Common::Conf::Attributes;
11             use Lemonldap::NG::Common::Conf::SubAttributes;
12             use Lemonldap::NG::Common::Regexp;
13              
14             our $VERSION = '1.4.2';
15              
16             ## @method protected hashref cstruct(hashref h,string k)
17             # Merge $h with the structure produced with $k and return it.
18             # Used to manage virtual hosts, and metadatas (IDP, SP).
19             #@param $h Result of struct()
20             #@param $k Full path of the key
21             #@return Tree structure
22             sub cstruct {
23             shift;
24             my ( $h, $k ) = @_;
25             my @tmp = split( /\//, $k );
26             return $h unless ( scalar(@tmp) > 1 );
27             my $k1 = $tmp[0];
28             my $k2 = $tmp[1];
29             if ( $k1 =~ /^virtualHosts/i ) {
30             %$h = (
31             %$h,
32             virtualHosts => {
33             $k2 => {
34             _nodes => [
35             qw(rules:rules:rules headers post:post:post vhostOptions)
36             ],
37             rules => {
38             _nodes => ["hash:/locationRules/$k2:rules:rules"],
39             _js => 'rulesRoot',
40             _help => 'rules',
41             },
42             headers => {
43             _nodes => ["hash:/exportedHeaders/$k2"],
44             _js => 'hashRoot',
45             _help => 'headers',
46             },
47             post => {
48             _nodes => ["post:/post/$k2:post:post"],
49             _js => 'postRoot',
50             _help => 'post',
51             },
52             vhostOptions => {
53             _nodes => [
54             qw(vhostPort vhostHttps vhostMaintenance vhostAliases)
55             ],
56             vhostPort => "int:/vhostOptions/$k2/vhostPort",
57             vhostHttps => "trool:/vhostOptions/$k2/vhostHttps",
58             vhostMaintenance =>
59             "bool:/vhostOptions/$k2/vhostMaintenance",
60             vhostAliases => "text:/vhostOptions/$k2/vhostAliases",
61             _help => 'vhostOptions',
62             },
63             }
64             }
65             );
66             }
67             elsif ( $k1 =~ /^samlIDPMetaDataNode/i ) {
68             %$h = (
69             %$h,
70             samlIDPMetaDataNode => {
71             $k2 => {
72             _nodes => [
73             qw(samlIDPMetaDataXML samlIDPMetaDataExportedAttributes samlIDPMetaDataOptions)
74             ],
75              
76             samlIDPMetaDataExportedAttributes => {
77             _nodes => [
78             "hash:/samlIDPMetaDataExportedAttributes/$k2"
79             . ":samlIDPMetaDataExportedAttributes:samlAttribute"
80             ],
81             _js => 'samlAttributeRoot',
82             _help => 'samlIDPExportedAttributes',
83             },
84              
85             samlIDPMetaDataXML => "samlmetadata:/samlIDPMetaDataXML/$k2"
86             . ":samlIDPMetaDataXML:filearea",
87              
88             samlIDPMetaDataOptions => {
89             _nodes => [
90             qw(samlIDPMetaDataOptionsResolutionRule samlIDPMetaDataOptionsAuthnRequest samlIDPMetaDataOptionsSession samlIDPMetaDataOptionsSignature samlIDPMetaDataOptionsBinding samlIDPMetaDataOptionsSecurity)
91             ],
92             _help => 'samlIDPOptions',
93              
94             samlIDPMetaDataOptionsResolutionRule =>
95             "textarea:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsResolutionRule",
96              
97             samlIDPMetaDataOptionsAuthnRequest => {
98             _nodes => [
99             qw(samlIDPMetaDataOptionsNameIDFormat samlIDPMetaDataOptionsForceAuthn samlIDPMetaDataOptionsIsPassive samlIDPMetaDataOptionsAllowProxiedAuthn samlIDPMetaDataOptionsAllowLoginFromIDP samlIDPMetaDataOptionsRequestedAuthnContext)
100             ],
101              
102             samlIDPMetaDataOptionsNameIDFormat =>
103             "text:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsNameIDFormat"
104             . ":samlIDPOptions:nameIdFormatParams",
105             samlIDPMetaDataOptionsForceAuthn =>
106             "bool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsForceAuthn",
107             samlIDPMetaDataOptionsIsPassive =>
108             "bool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsIsPassive",
109             samlIDPMetaDataOptionsAllowProxiedAuthn =>
110             "bool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsAllowProxiedAuthn",
111             samlIDPMetaDataOptionsAllowLoginFromIDP =>
112             "bool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsAllowLoginFromIDP",
113             samlIDPMetaDataOptionsRequestedAuthnContext =>
114             "text:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsRequestedAuthnContext"
115             . ":samlIDPOptions:authnContextParams",
116             },
117              
118             samlIDPMetaDataOptionsSession => {
119             _nodes => [
120             qw(samlIDPMetaDataOptionsAdaptSessionUtime samlIDPMetaDataOptionsForceUTF8)
121             ],
122              
123             samlIDPMetaDataOptionsAdaptSessionUtime =>
124             "bool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsAdaptSessionUtime",
125             samlIDPMetaDataOptionsForceUTF8 =>
126             "bool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsForceUTF8",
127              
128             },
129              
130             samlIDPMetaDataOptionsSignature => {
131             _nodes => [
132             qw(samlIDPMetaDataOptionsSignSSOMessage samlIDPMetaDataOptionsCheckSSOMessageSignature samlIDPMetaDataOptionsSignSLOMessage samlIDPMetaDataOptionsCheckSLOMessageSignature)
133             ],
134              
135             samlIDPMetaDataOptionsSignSSOMessage =>
136             "trool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsSignSSOMessage",
137             samlIDPMetaDataOptionsCheckSSOMessageSignature =>
138             "bool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsCheckSSOMessageSignature",
139             samlIDPMetaDataOptionsSignSLOMessage =>
140             "trool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsSignSLOMessage",
141             samlIDPMetaDataOptionsCheckSLOMessageSignature =>
142             "bool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsCheckSLOMessageSignature",
143              
144             },
145              
146             samlIDPMetaDataOptionsBinding => {
147             _nodes => [
148             qw(samlIDPMetaDataOptionsSSOBinding samlIDPMetaDataOptionsSLOBinding)
149             ],
150              
151             samlIDPMetaDataOptionsSSOBinding =>
152             "text:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsSSOBinding"
153             . ":samlIDPOptions:bindingParams",
154             samlIDPMetaDataOptionsSLOBinding =>
155             "text:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsSLOBinding"
156             . ":samlIDPOptions:bindingParams",
157              
158             },
159              
160             samlIDPMetaDataOptionsSecurity => {
161             _nodes => [
162             qw(samlIDPMetaDataOptionsEncryptionMode samlIDPMetaDataOptionsCheckConditions)
163             ],
164              
165             samlIDPMetaDataOptionsEncryptionMode =>
166             "text:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsEncryptionMode:samlIDPOptions:encryptionModeParams",
167             samlIDPMetaDataOptionsCheckConditions =>
168             "bool:/samlIDPMetaDataOptions/$k2/samlIDPMetaDataOptionsCheckConditions",
169              
170             },
171              
172             },
173             }
174             }
175             );
176             }
177             elsif ( $k1 =~ /^samlSPMetaDataNode/i ) {
178             %$h = (
179             %$h,
180             samlSPMetaDataNode => {
181             $k2 => {
182             _nodes => [
183             qw(samlSPMetaDataXML samlSPMetaDataExportedAttributes samlSPMetaDataOptions)
184             ],
185              
186             samlSPMetaDataExportedAttributes => {
187             _nodes => [
188             "hash:/samlSPMetaDataExportedAttributes/$k2"
189             . ":samlSPMetaDataExportedAttributes:samlAttribute"
190             ],
191             _js => 'samlAttributeRoot',
192             _help => 'samlSPExportedAttributes',
193             },
194              
195             samlSPMetaDataXML => "samlmetadata:/samlSPMetaDataXML/$k2"
196             . ":samlSPMetaDataXML:filearea",
197              
198             samlSPMetaDataOptions => {
199             _nodes => [
200             qw(samlSPMetaDataOptionsAuthnResponse samlSPMetaDataOptionsSignature samlSPMetaDataOptionsSecurity)
201             ],
202             _help => 'samlSPOptions',
203              
204             samlSPMetaDataOptionsAuthnResponse => {
205             _nodes => [
206             qw(samlSPMetaDataOptionsNameIDFormat samlSPMetaDataOptionsNameIDSessionKey samlSPMetaDataOptionsOneTimeUse samlSPMetaDataOptionsSessionNotOnOrAfterTimeout samlSPMetaDataOptionsNotOnOrAfterTimeout)
207             ],
208              
209             samlSPMetaDataOptionsNameIDFormat =>
210             "text:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsNameIDFormat"
211             . ":samlSPOptions:nameIdFormatParams",
212             samlSPMetaDataOptionsNameIDSessionKey =>
213             "text:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsNameIDSessionKey",
214             samlSPMetaDataOptionsOneTimeUse =>
215             "bool:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsOneTimeUse",
216             samlSPMetaDataOptionsSessionNotOnOrAfterTimeout =>
217             "int:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsSessionNotOnOrAfterTimeout",
218             samlSPMetaDataOptionsNotOnOrAfterTimeout =>
219             "int:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsNotOnOrAfterTimeout",
220             },
221              
222             samlSPMetaDataOptionsSignature => {
223             _nodes => [
224             qw(samlSPMetaDataOptionsSignSSOMessage samlSPMetaDataOptionsCheckSSOMessageSignature samlSPMetaDataOptionsSignSLOMessage samlSPMetaDataOptionsCheckSLOMessageSignature)
225             ],
226              
227             samlSPMetaDataOptionsSignSSOMessage =>
228             "trool:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsSignSSOMessage",
229             samlSPMetaDataOptionsCheckSSOMessageSignature =>
230             "bool:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsCheckSSOMessageSignature",
231             samlSPMetaDataOptionsSignSLOMessage =>
232             "trool:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsSignSLOMessage",
233             samlSPMetaDataOptionsCheckSLOMessageSignature =>
234             "bool:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsCheckSLOMessageSignature",
235             },
236             samlSPMetaDataOptionsSecurity => {
237              
238             _nodes => [
239             qw(samlSPMetaDataOptionsEncryptionMode samlSPMetaDataOptionsEnableIDPInitiatedURL)
240             ],
241              
242             samlSPMetaDataOptionsEncryptionMode =>
243             "text:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsEncryptionMode:samlSPOptions:encryptionModeParams",
244             samlSPMetaDataOptionsEnableIDPInitiatedURL =>
245             "bool:/samlSPMetaDataOptions/$k2/samlSPMetaDataOptionsEnableIDPInitiatedURL",
246             },
247             },
248             }
249             }
250             );
251             }
252             return $h;
253             }
254              
255             ## @method protected hashref struct(hashref h,string k)
256             # Returns the tree structure
257             #@return Tree structure
258             sub struct {
259             my $self = shift;
260             return {
261             _nodes => [
262             qw(n:generalParameters n:variables n:virtualHosts n:samlServiceMetaData n:samlIDPMetaDataNode n:samlSPMetaDataNode)
263             ],
264             _help => 'default',
265              
266             ######################
267             # GENERAL PARAMETERS #
268             ######################
269             generalParameters => {
270             _nodes => [
271             qw(n:portalParams n:authParams n:issuerParams n:logParams n:cookieParams n:sessionParams cn:reloadUrls n:advancedParams)
272             ],
273             _help => 'default',
274              
275             # PORTAL PARAMETERS
276             portalParams => {
277             _nodes => [
278             qw(portal n:portalMenu n:portalCustomization n:portalCaptcha)
279             ],
280             _help => 'portalParams',
281              
282             portal => 'text:/portal:portal:text',
283              
284             portalMenu => {
285             _nodes => [qw(portalModules applicationList)],
286             _help => 'menu',
287             portalModules => {
288             _nodes => [
289             qw(portalDisplayLogout portalDisplayChangePassword portalDisplayAppslist portalDisplayLoginHistory)
290             ],
291             portalDisplayLogout =>
292             'text:/portalDisplayLogout:menu:boolOrPerlExpr',
293             portalDisplayChangePassword =>
294             'text:/portalDisplayChangePassword:menu:boolOrPerlExpr',
295             portalDisplayAppslist =>
296             'text:/portalDisplayAppslist:menu:boolOrPerlExpr',
297             portalDisplayLoginHistory =>
298             'text:/portalDisplayLoginHistory:menu:boolOrPerlExpr',
299             },
300             applicationList => {
301             _nodes => [
302             'applicationlist:/applicationList:menuCatAndApp:applicationListCategory'
303             ],
304             _js => 'applicationListCategoryRoot',
305             _help => 'menuCatAndApp',
306             },
307             },
308              
309             portalCustomization => {
310             _nodes => [
311             qw(portalSkin cn:portalSkinRules portalButtons passwordManagement portalOther)
312             ],
313             _help => 'portalcustom',
314              
315             portalSkin => 'text:/portalSkin:portalcustom:skinSelect',
316             portalSkinRules => {
317             _nodes => ['hash:/portalSkinRules:portalcustom:btext'],
318             _js => 'hashRoot',
319             _help => 'portalcustom',
320             },
321             portalButtons => {
322             _nodes => [
323             qw/portalCheckLogins portalDisplayResetPassword portalDisplayRegister/
324             ],
325             portalCheckLogins => 'bool:/portalCheckLogins',
326             portalDisplayResetPassword =>
327             'bool:/portalDisplayResetPassword',
328             portalDisplayRegister => 'bool:/portalDisplayRegister',
329             },
330             passwordManagement => {
331             _nodes => [
332             qw(portalRequireOldPassword hideOldPassword mailOnPasswordChange)
333             ],
334              
335             portalRequireOldPassword =>
336             'bool:/portalRequireOldPassword',
337             hideOldPassword => 'bool:/hideOldPassword',
338             mailOnPasswordChange => 'bool:/mailOnPasswordChange',
339             },
340             portalOther => {
341             _nodes => [
342             qw/portalAutocomplete portalUserAttr portalOpenLinkInNewWindow portalAntiFrame portalPingInterval/
343             ],
344              
345             portalAutocomplete => 'bool:/portalAutocomplete',
346             portalUserAttr => 'text:/portalUserAttr',
347             portalOpenLinkInNewWindow =>
348             'bool:/portalOpenLinkInNewWindow',
349             portalAntiFrame => 'bool:/portalAntiFrame',
350             portalPingInterval => 'int:/portalPingInterval',
351             },
352             },
353              
354             portalCaptcha => {
355             _nodes => [
356             qw(captcha_login_enabled captcha_mail_enabled captcha_register_enabled captcha_size captchaStorage cn:captchaStorageOptions)
357             ],
358             _help => 'captcha',
359              
360             captcha_login_enabled => 'bool:/captcha_login_enabled',
361             captcha_mail_enabled => 'bool:/captcha_mail_enabled',
362             captcha_register_enabled =>
363             'bool:/captcha_register_enabled',
364             captcha_size => 'int:/captcha_size',
365             captchaStorage => 'text:/captchaStorage',
366             captchaStorageOptions => {
367             _nodes => ['hash:/captchaStorageOptions:captcha:btext'],
368             _js => 'hashRoot',
369             _help => 'captcha',
370             },
371              
372             },
373             },
374              
375             # AUTHENTICATION / USERDB / PASSWORDDB PARAMETERS
376             authParams => {
377              
378             # Displayed nodes depend on authentication/userDB modules choosed
379             _nodes => sub {
380             my $self = shift;
381             my $auth = $self->conf->{authentication};
382             my $udb = $self->conf->{userDB};
383             my $pdb = $self->conf->{passwordDB};
384             $auth = lc($auth);
385             $auth =~ s/\s.*$//; # For Multi
386             $udb = lc($udb);
387             $pdb = lc($pdb);
388             my %res;
389              
390             foreach my $mod (
391             (
392             $auth,
393             ( $udb ne ( $auth or $pdb ) ? $udb : () ),
394             ( $pdb ne ( $auth or $udb ) ? $pdb : () ),
395             )
396             )
397             {
398             my $tmp = {
399             ad => ['ldapParams'],
400             ldap => ['ldapParams'],
401             ssl => ['sslParams'],
402             cas => ['casParams'],
403             radius => ['radiusParams'],
404             remote => ['remoteParams'],
405             proxy => ['proxyParams'],
406             openid => ['openIdParams'],
407             google => ['googleParams'],
408             facebook => ['facebookParams'],
409             twitter => ['twitterParams'],
410             webid => ['webIDParams'],
411             dbi => ['dbiParams'],
412             apache => ['apacheParams'],
413             null => ['nullParams'],
414             slave => ['slaveParams'],
415             choice => [
416             qw(ldapParams sslParams casParams radiusParams remoteParams proxyParams openIdParams googleParams facebookParams twitterParams webIDParams dbiParams apacheParams nullParams choiceParams slaveParams yubikeyParams browserIdParams demoParams)
417             ],
418             multi => [
419             qw(ldapParams sslParams casParams radiusParams remoteParams proxyParams openIdParams googleParams facebookParams twitterParams webIDParams dbiParams apacheParams nullParams choiceParams slaveParams yubikeyParams browserIdParams demoParams)
420             ],
421             yubikey => ['yubikeyParams'],
422             browserid => ['browserIdParams'],
423             demo => ['demoParams'],
424             }->{$mod};
425             if ($tmp) {
426             $res{$_}++ foreach (@$tmp);
427             }
428             }
429             my @u = keys %res;
430              
431             # Add authentication, userDB, passwordDB and issuerDB nodes at the beginning
432             unshift( @u, "passwordDB" );
433             unshift( @u, "userDB" );
434             unshift( @u, "authentication" );
435              
436             # Return nodes
437             return \@u;
438             },
439              
440             _help => 'authParams',
441              
442             authentication => 'text:/authentication:authParams:authParams',
443             userDB => 'text:/userDB:authParams:userdbParams',
444             passwordDB => 'text:/passwordDB:authParams:passworddbParams',
445              
446             # LDAP
447             ldapParams => {
448             _nodes => [
449             qw(ldapAuthnLevel cn:ldapExportedVars n:ldapConnection n:ldapFilters n:ldapGroups n:ldapPassword)
450             ],
451             _help => 'authLDAP',
452             ldapAuthnLevel => 'int:/ldapAuthnLevel:authLDAPLevel:int',
453             ldapExportedVars => {
454             _nodes => ['hash:/ldapExportedVars:vars:btext'],
455             _js => 'hashRoot',
456             _help => 'authLDAP',
457             },
458             ldapConnection => {
459             _nodes => [
460             qw(ldapServer ldapPort ldapBase managerDn managerPassword ldapTimeout ldapVersion ldapRaw)
461             ],
462             ldapServer => 'text:/ldapServer',
463             ldapPort => 'int:/ldapPort',
464             ldapBase => 'text:/ldapBase',
465             managerDn => 'text:/managerDn',
466             managerPassword => 'text:/managerPassword',
467             ldapTimeout => 'int:/ldapTimeout',
468             ldapVersion => 'int:/ldapVersion',
469             ldapRaw => 'text:/ldapRaw',
470             _help => 'authLDAPConnection',
471             },
472              
473             ldapFilters => {
474             _nodes =>
475             [qw(LDAPFilter AuthLDAPFilter mailLDAPFilter)],
476             LDAPFilter => 'text:/LDAPFilter',
477             AuthLDAPFilter => 'text:/AuthLDAPFilter',
478             mailLDAPFilter => 'text:/mailLDAPFilter',
479             _help => 'authLDAPFilters',
480             },
481              
482             ldapGroups => {
483             _nodes => [
484             qw(ldapGroupBase ldapGroupObjectClass ldapGroupAttributeName ldapGroupAttributeNameUser ldapGroupAttributeNameSearch ldapGroupRecursive ldapGroupAttributeNameGroup)
485             ],
486             ldapGroupBase => 'text:/ldapGroupBase',
487             ldapGroupObjectClass => 'text:/ldapGroupObjectClass',
488             ldapGroupAttributeName =>
489             'text:/ldapGroupAttributeName',
490             ldapGroupAttributeNameUser =>
491             'text:/ldapGroupAttributeNameUser',
492             ldapGroupAttributeNameSearch =>
493             'text:/ldapGroupAttributeNameSearch',
494             ldapGroupRecursive => 'bool:/ldapGroupRecursive',
495             ldapGroupAttributeNameGroup =>
496             'text:/ldapGroupAttributeNameGroup',
497             _help => 'authLDAPGroups',
498             },
499              
500             ldapPassword => {
501             _nodes => [
502             qw(ldapPpolicyControl ldapSetPassword ldapChangePasswordAsUser ldapPwdEnc ldapUsePasswordResetAttribute ldapPasswordResetAttribute ldapPasswordResetAttributeValue)
503             ],
504             ldapPpolicyControl => 'bool:/ldapPpolicyControl',
505             ldapSetPassword => 'bool:/ldapSetPassword',
506             ldapChangePasswordAsUser =>
507             'bool:/ldapChangePasswordAsUser',
508             ldapPwdEnc => 'text:/ldapPwdEnc',
509             ldapUsePasswordResetAttribute =>
510             'bool:/ldapUsePasswordResetAttribute',
511             ldapPasswordResetAttribute =>
512             'text:/ldapPasswordResetAttribute',
513             ldapPasswordResetAttributeValue =>
514             'text:/ldapPasswordResetAttributeValue',
515             _help => 'authLDAPPassword',
516             },
517              
518             },
519              
520             # SSL
521             sslParams => {
522             _nodes => [qw(SSLAuthnLevel SSLVar)],
523             _help => 'authSSL',
524             SSLAuthnLevel => 'int:/SSLAuthnLevel',
525             SSLVar => 'text:/SSLVar',
526             },
527              
528             # CAS
529             casParams => {
530             _nodes => [
531             qw(CAS_authnLevel CAS_url CAS_CAFile CAS_renew CAS_gateway CAS_pgtFile cn:CAS_proxiedServices)
532             ],
533             _help => 'authCAS',
534             CAS_authnLevel => 'int:/CAS_authnLevel',
535             CAS_url => 'text:/CAS_url',
536             CAS_CAFile => 'text:/CAS_CAFile',
537             CAS_renew => 'bool:/CAS_renew',
538             CAS_gateway => 'bool:/CAS_gateway',
539             CAS_pgtFile => 'text:/CAS_pgtFile',
540             CAS_proxiedServices => {
541             _nodes => ['hash:/CAS_proxiedServices:authCAS:btext'],
542             _js => 'hashRoot',
543             _help => 'authCAS',
544             },
545              
546             },
547              
548             # Radius
549             radiusParams => {
550             _nodes => [qw(radiusAuthnLevel radiusSecret radiusServer)],
551             _help => 'authRadius',
552             radiusAuthnLevel => 'int:/radiusAuthnLevel',
553             radiusSecret => 'text:/radiusSecret',
554             radiusServer => 'text:/radiusServer',
555             },
556              
557             # Remote
558             remoteParams => {
559             _nodes => [
560             qw(remotePortal remoteCookieName remoteGlobalStorage cn:remoteGlobalStorageOptions)
561             ],
562             _help => 'authRemote',
563             remotePortal => 'text:/remotePortal',
564             remoteCookieName => 'text:/remoteCookieName',
565             remoteGlobalStorage => 'text:/remoteGlobalStorage',
566             remoteGlobalStorageOptions => {
567             _nodes =>
568             ['hash:/remoteGlobalStorageOptions:authRemote:btext'],
569             _js => 'hashRoot',
570             _help => 'authRemote',
571             },
572             },
573              
574             # Proxy
575             proxyParams => {
576             _nodes =>
577             [qw(soapAuthService remoteCookieName soapSessionService)],
578             _help => 'authProxy',
579             soapAuthService => 'text:/soapAuthService',
580             remoteCookieName => 'text:/remoteCookieName',
581             soapSessionService => 'text:/soapSessionService',
582             },
583              
584             # OpenID
585             openIdParams => {
586             _nodes => [
587             qw(openIdAuthnLevel cn:openIdExportedVars openIdSecret openIdIDPList)
588             ],
589             _help => 'authOpenID',
590             openIdAuthnLevel => 'int:/openIdAuthnLevel',
591             openIdExportedVars => {
592             _nodes => ['hash:/openIdExportedVars:vars:btext'],
593             _js => 'hashRoot',
594             _help => 'authOpenID',
595             },
596             openIdSecret => 'text:/openIdSecret',
597             openIdIDPList =>
598             'text:/openIdIDPList:authOpenID:openididplist',
599             },
600              
601             # Google
602             googleParams => {
603             _nodes => [qw(googleAuthnLevel cn:googleExportedVars)],
604             _help => 'authGoogle',
605             googleAuthnLevel => 'int:/googleAuthnLevel',
606             googleExportedVars => {
607             _nodes => ['hash:/googleExportedVars:vars:btext'],
608             _js => 'hashRoot',
609             _help => 'authGoogle',
610             },
611             },
612              
613             # Facebook
614             facebookParams => {
615             _nodes => [
616             qw(facebookAuthnLevel cn:facebookExportedVars facebookAppId facebookAppSecret)
617             ],
618             _help => 'authFacebook',
619             facebookAuthnLevel => 'int:/facebookAuthnLevel',
620             facebookExportedVars => {
621             _nodes => ['hash:/facebookExportedVars:vars:btext'],
622             _js => 'hashRoot',
623             _help => 'authFacebook',
624             },
625             facebookAppId => 'text:facebookAppId',
626             facebookAppSecret => 'text:facebookAppSecret',
627             },
628              
629             # Twitter
630             twitterParams => {
631             _nodes => [
632             qw(twitterAuthnLevel twitterKey twitterSecret twitterAppName)
633             ],
634             _help => 'authTwitter',
635             twitterAuthnLevel => 'int:/twitterAuthnLevel',
636             twitterKey => 'text:/twitterKey',
637             twitterSecret => 'text:/twitterSecret',
638             twitterAppName => 'text:/twitterAppName',
639             },
640              
641             # WebID
642             webIDParams => {
643             _nodes =>
644             [qw(webIDAuthnLevel cn:webIDExportedVars webIDWhitelist)],
645             _help => 'authWebID',
646             webIDAuthnLevel => 'int:webIDAuthnLevel',
647             webIDExportedVars => {
648             _nodes => ['hash:/webIDExportedVars:vars:btext'],
649             _js => 'hashRoot',
650             _help => 'authWebID',
651             },
652             webIDWhitelist => 'text:/webIDWhitelist',
653             },
654              
655             # DBI
656             dbiParams => {
657             _nodes => [
658             qw(dbiAuthnLevel cn:dbiExportedVars n:dbiConnection n:dbiSchema n:dbiPassword)
659             ],
660             _help => 'authDBI',
661             dbiAuthnLevel => 'int:/dbiAuthnLevel:authDBILevel:int',
662             dbiExportedVars => {
663             _nodes => ['hash:/dbiExportedVars:vars:btext'],
664             _js => 'hashRoot',
665             _help => 'authDBI',
666             },
667             dbiConnection => {
668             _nodes => [qw(n:dbiConnectionAuth n:dbiConnectionUser)],
669             dbiConnectionAuth => {
670             _nodes =>
671             [qw(dbiAuthChain dbiAuthUser dbiAuthPassword)],
672             dbiAuthChain => 'text:/dbiAuthChain',
673             dbiAuthUser => 'text:/dbiAuthUser',
674             dbiAuthPassword => 'text:/dbiAuthPassword',
675             },
676             dbiConnectionUser => {
677             _nodes =>
678             [qw(dbiUserChain dbiUserUser dbiUserPassword)],
679             dbiUserChain => 'text:/dbiUserChain',
680             dbiUserUser => 'text:/dbiUserUser',
681             dbiUserPassword => 'text:/dbiUserPassword',
682             },
683             _help => 'authDBIConnection',
684             },
685              
686             dbiSchema => {
687             _nodes => [
688             qw(dbiAuthTable dbiUserTable dbiAuthLoginCol dbiAuthPasswordCol dbiPasswordMailCol userPivot)
689             ],
690             dbiAuthTable => 'text:/dbiAuthTable',
691             dbiUserTable => 'text:/dbiUserTable',
692             dbiAuthLoginCol => 'text:/dbiAuthLoginCol',
693             dbiAuthPasswordCol => 'text:/dbiAuthPasswordCol',
694             dbiPasswordMailCol => 'text:/dbiPasswordMailCol',
695             userPivot => 'text:/userPivot',
696             _help => 'authDBISchema',
697             },
698              
699             dbiPassword => {
700             _nodes => [qw(dbiAuthPasswordHash)],
701             dbiAuthPasswordHash => 'text:/dbiAuthPasswordHash',
702             _help => 'authDBIPassword',
703             },
704             },
705              
706             # Apache
707             apacheParams => {
708             _nodes => [qw(apacheAuthnLevel)],
709             _help => 'authApache',
710             apacheAuthnLevel => 'int:/apacheAuthnLevel',
711             },
712              
713             # Null
714             nullParams => {
715             _nodes => [qw(nullAuthnLevel)],
716             _help => 'authNull',
717             nullAuthnLevel => 'int:/nullAuthnLevel',
718             },
719              
720             # Slave
721             slaveParams => {
722             _nodes => [
723             qw(slaveAuthnLevel cn:slaveExportedVars slaveUserHeader slaveMasterIP)
724             ],
725             _help => 'authSlave',
726             slaveAuthnLevel => 'int:/slaveAuthnLevel',
727             slaveExportedVars => {
728             _nodes => ['hash:/slaveExportedVars:vars:btext'],
729             _js => 'hashRoot',
730             _help => 'authSlave',
731             },
732             slaveUserHeader => 'text:/slaveUserHeader',
733             slaveMasterIP => 'text:/slaveMasterIP',
734             },
735              
736             # Choice
737             choiceParams => {
738             _nodes => [qw(authChoiceParam n:authChoiceModules)],
739             _help => 'authChoice',
740             authChoiceParam => 'text:/authChoiceParam',
741             authChoiceModules => {
742             _nodes =>
743             ['hash:/authChoiceModules:authChoice:authChoice'],
744             _js => 'authChoiceRoot',
745             _help => 'authChoice',
746             },
747             },
748              
749             # Yubikey
750             yubikeyParams => {
751             _nodes => [
752             qw(yubikeyAuthnLevel yubikeyClientID yubikeySecretKey yubikeyPublicIDSize)
753             ],
754             _help => 'authYubikey',
755             yubikeyAuthnLevel => 'int:/yubikeyAuthnLevel',
756             yubikeyClientID => 'text:/yubikeyClientID',
757             yubikeySecretKey => 'text:/yubikeySecretKey',
758             yubikeyPublicIDSize => 'int:/yubikeyPublicIDSize',
759             },
760              
761             # BrowserID
762             browserIdParams => {
763             _nodes => [
764             qw(browserIdAuthnLevel browserIdAutoLogin browserIdVerificationURL browserIdSiteName browserIdSiteLogo browserIdBackgroundColor)
765             ],
766             _help => 'authBrowserID',
767             browserIdAuthnLevel => 'int:/browserIdAuthnLevel',
768             browserIdAutoLogin => 'bool:/browserIdAutoLogin',
769             browserIdVerificationURL =>
770             'text:/browserIdVerificationURL',
771             browserIdSiteName => 'text:/browserIdSiteName',
772             browserIdSiteLogo => 'text:/browserIdSiteLogo',
773             browserIdBackgroundColor =>
774             'text:/browserIdBackgroundColor',
775             },
776              
777             # Demo
778             demoParams => {
779             _nodes => [qw(cn:demoExportedVars)],
780             _help => 'authDemo',
781             demoExportedVars => {
782             _nodes => ['hash:/demoExportedVars:vars:btext'],
783             _js => 'hashRoot',
784             _help => 'authDemo',
785             },
786             },
787              
788             },
789              
790             # ISSUERDB PARAMETERS
791             issuerParams => {
792             _nodes => [qw(issuerDBSAML issuerDBCAS issuerDBOpenID)],
793             _help => 'issuerdb',
794             issuerDBSAML => {
795             _nodes => [
796             qw(issuerDBSAMLActivation issuerDBSAMLPath issuerDBSAMLRule)
797             ],
798             _help => 'issuerdbSAML',
799             issuerDBSAMLActivation => 'bool:/issuerDBSAMLActivation',
800             issuerDBSAMLPath => 'text:/issuerDBSAMLPath',
801             issuerDBSAMLRule =>
802             'text:/issuerDBSAMLRule:issuerdbSAML:boolOrPerlExpr',
803             },
804             issuerDBCAS => {
805             _nodes => [
806             qw(issuerDBCASActivation issuerDBCASPath issuerDBCASRule issuerDBCASOptions)
807             ],
808             _help => 'issuerdbCAS',
809             issuerDBCASActivation => 'bool:/issuerDBCASActivation',
810             issuerDBCASPath => 'text:/issuerDBCASPath',
811             issuerDBCASRule =>
812             'text:/issuerDBCASRule:issuerdbCAS:boolOrPerlExpr',
813             issuerDBCASOptions => {
814             _nodes => [
815             qw(casAttr casAccessControlPolicy casStorage cn:casStorageOptions)
816             ],
817             casAttr => 'text:/casAttr',
818             casAccessControlPolicy =>
819             'select:/casAccessControlPolicy:issuerdbCAS:casAccessControlPolicyParams',
820             casStorage => 'text:/casStorage',
821             casStorageOptions => {
822             _nodes =>
823             ['hash:/casStorageOptions:issuerDBCAS:btext'],
824             _js => 'hashRoot',
825             _help => 'issuerdbCAS',
826             },
827             },
828             },
829             issuerDBOpenID => {
830             _nodes => [
831             qw(issuerDBOpenIDActivation issuerDBOpenIDPath issuerDBOpenIDRule n:issuerDBOpenIDOptions)
832             ],
833             _help => 'issuerdbOpenID',
834             issuerDBOpenIDActivation =>
835             'bool:/issuerDBOpenIDActivation',
836             issuerDBOpenIDPath => 'text:/issuerDBOpenIDPath',
837             issuerDBOpenIDRule =>
838             'text:/issuerDBOpenIDRule:issuerdbOpenID:boolOrPerlExpr',
839             issuerDBOpenIDOptions => {
840             _nodes => [
841             qw(openIdIssuerSecret openIdAttr openIdSPList n:openIdSreg)
842             ],
843             openIdIssuerSecret => 'text:/openIdIssuerSecret',
844             openIdAttr => 'text:/openIdAttr',
845             openIdSPList =>
846             'text:/openIdSPList:issuerdbOpenID:openididplist',
847             openIdSreg => {
848             _nodes => [
849             qw(openIdSreg_fullname openIdSreg_nickname openIdSreg_language openIdSreg_postcode openIdSreg_timezone openIdSreg_country openIdSreg_gender openIdSreg_email openIdSreg_dob)
850             ],
851             openIdSreg_fullname => 'text:openIdSreg_fullname',
852             openIdSreg_nickname => 'text:openIdSreg_nickname',
853             openIdSreg_language => 'text:openIdSreg_language',
854             openIdSreg_postcode => 'text:openIdSreg_postcode',
855             openIdSreg_timezone => 'text:openIdSreg_timezone',
856             openIdSreg_country => 'text:openIdSreg_country',
857             openIdSreg_gender => 'text:openIdSreg_gender',
858             openIdSreg_email => 'text:openIdSreg_email',
859             openIdSreg_dob => 'text:openIdSreg_dob',
860             },
861             },
862             },
863             },
864              
865             # LOGS PARAMETERS
866             logParams => {
867             _nodes => [qw(syslog trustedProxies whatToTrace)],
868             _help => 'logs',
869             syslog => 'text:/syslog',
870             trustedProxies => 'text:/trustedProxies',
871             whatToTrace => 'text:/whatToTrace',
872             },
873              
874             # COOKIE PARAMETERS
875             cookieParams => {
876             _nodes => [
877             qw(cookieName domain cda securedCookie httpOnly cookieExpiration)
878             ],
879             _help => 'cookies',
880             cookieName => 'text:/cookieName',
881             domain => 'text:/domain',
882             cda => 'bool:/cda',
883             securedCookie =>
884             'select:/securedCookie:cookies:securedCookieValues',
885             httpOnly => 'bool:/httpOnly',
886             cookieExpiration => 'text:/cookieExpiration',
887             },
888              
889             # SESSIONS PARAMETERS
890             sessionParams => {
891             _nodes => [
892             qw(storePassword timeout timeoutActivity cn:grantSessionRules n:sessionStorage n:multipleSessions n:persistentSessions)
893             ],
894             _help => 'sessions',
895              
896             storePassword => 'bool:/storePassword',
897             timeout => 'int:/timeout',
898             timeoutActivity =>
899             'text:/timeoutActivity:sessions:timeoutActivityParams',
900              
901             grantSessionRules => {
902             _nodes => [
903             'hash:/grantSessionRules:grantSessionRules:grantSessionRules'
904             ],
905             _js => 'grantSessionRulesRoot',
906             },
907              
908             sessionStorage => {
909             _nodes => [
910             qw(globalStorage cn:globalStorageOptions localSessionStorage cn:localSessionStorageOptions)
911             ],
912             _help => 'sessionsdb',
913             globalStorage => 'text:/globalStorage',
914             globalStorageOptions => {
915             _nodes =>
916             ['hash:/globalStorageOptions:sessionsdb:btext'],
917             _js => 'hashRoot',
918             _help => 'sessionsdb',
919             },
920             localSessionStorage => 'text:/localSessionStorage',
921             localSessionStorageOptions => {
922             _nodes =>
923             ['hash:/localSessionStorageOptions:sessionsdb:btext'],
924             _js => 'hashRoot',
925             _help => 'sessionsdb',
926             },
927             },
928              
929             multipleSessions => {
930             _nodes => [
931             qw(singleSession singleIP singleUserByIP notifyDeleted notifyOther)
932             ],
933             singleSession => 'bool:/singleSession',
934             singleIP => 'bool:/singleIP',
935             singleUserByIP => 'bool:/singleUserByIP',
936             notifyDeleted => 'bool:/notifyDeleted',
937             notifyOther => 'bool:/notifyOther',
938             },
939              
940             persistentSessions => {
941             _nodes =>
942             [qw(persistentStorage cn:persistentStorageOptions)],
943             _help => 'sessionsdb',
944             persistentStorage => 'text:/persistentStorage',
945             persistentStorageOptions => {
946             _nodes =>
947             ['hash:/persistentStorageOptions:sessionsdb:btext'],
948             _js => 'hashRoot',
949             _help => 'sessionsdb',
950             },
951             },
952              
953             },
954              
955             # RELOAD URLS
956             reloadUrls => {
957             _nodes => ['hash:/reloadUrls:reloadUrls:btext'],
958             _js => 'hashRoot',
959             _help => 'reloadUrls',
960             },
961              
962             # OTHER PARAMETERS
963             advancedParams => {
964             _nodes => [
965             qw(customFunctions n:soap n:loginHistory n:notifications n:passwordManagement n:register n:security n:redirection n:portalRedirection n:specialHandlers cn:logoutServices)
966             ],
967             _help => 'advanced',
968              
969             customFunctions => 'text:/customFunctions:customfunctions:text',
970              
971             soap => {
972             _nodes => [qw(Soap exportedAttr)],
973             Soap => 'bool:/Soap',
974             exportedAttr => 'text:/exportedAttr',
975             },
976              
977             loginHistory => {
978             _nodes => [
979             qw(loginHistoryEnabled successLoginNumber failedLoginNumber cn:sessionDataToRemember)
980             ],
981             _help => 'loginHistory',
982             loginHistoryEnabled => 'bool:/loginHistoryEnabled',
983             successLoginNumber => 'int:/successLoginNumber',
984             failedLoginNumber => 'int:/failedLoginNumber',
985             sessionDataToRemember => {
986             _nodes =>
987             ['hash:/sessionDataToRemember:loginHistory:btext'],
988             _js => 'hashRoot',
989             },
990             },
991              
992             notifications => {
993             _nodes => [
994             qw(notification notificationStorage cn:notificationStorageOptions notificationWildcard notificationXSLTfile)
995             ],
996             _help => 'notifications',
997             notification => 'bool:/notification',
998             notificationStorage => 'text:/notificationStorage',
999             notificationStorageOptions => {
1000             _nodes => [
1001             'hash:/notificationStorageOptions:notifications:btext'
1002             ],
1003             _js => 'hashRoot',
1004             _help => 'notifications',
1005             },
1006             notificationWildcard => 'text:/notificationWildcard',
1007             notificationXSLTfile => 'text:/notificationXSLTfile',
1008             },
1009              
1010             passwordManagement => {
1011             _nodes => [qw(SMTP mailHeaders mailContent mailOther)],
1012             _help => 'password',
1013             SMTP => {
1014             _nodes => [qw(SMTPServer SMTPAuthUser SMTPAuthPass)],
1015             SMTPServer => 'text:/SMTPServer',
1016             SMTPAuthUser => 'text:/SMTPAuthUser',
1017             SMTPAuthPass => 'text:/SMTPAuthPass',
1018             },
1019             mailHeaders => {
1020             _nodes => [qw(mailFrom mailReplyTo mailCharset)],
1021             mailFrom => 'text:/mailFrom',
1022             mailReplyTo => 'text:/mailReplyTo',
1023             mailCharset => 'text:/mailCharset',
1024             },
1025             mailContent => {
1026             _nodes => [
1027             qw(mailSubject mailBody mailConfirmSubject mailConfirmBody)
1028             ],
1029             mailSubject => 'text:/mailSubject',
1030             mailBody => 'textarea:/mailBody',
1031             mailConfirmSubject => 'text:/mailConfirmSubject',
1032             mailConfirmBody => 'textarea:/mailConfirmBody',
1033             },
1034             mailOther => {
1035             _nodes => [
1036             qw(mailUrl randomPasswordRegexp mailTimeout mailSessionKey)
1037             ],
1038             mailUrl => 'text:/mailUrl',
1039             randomPasswordRegexp => 'text:/randomPasswordRegexp',
1040             mailTimeout => 'int:/mailTimeout',
1041             mailSessionKey => 'text:/mailSessionKey',
1042             },
1043             },
1044              
1045             register => {
1046             _nodes => [
1047             qw/registerDB registerUrl registerTimeout registerConfirmSubject registerDoneSubject/
1048             ],
1049             _help => 'register',
1050             registerDB => 'text:/registerDB:register:registerdbParams',
1051             registerUrl => 'text:/registerUrl',
1052             registerTimeout => 'int:/registerTimeout',
1053             registerConfirmSubject => 'text:/registerConfirmSubject',
1054             registerDoneSubject => 'text:/registerDoneSubject',
1055             },
1056              
1057             security => {
1058             _nodes => [
1059             qw(userControl portalForceAuthn key trustedDomains useSafeJail checkXSS)
1060             ],
1061             _help => 'security',
1062             userControl => 'text:/userControl',
1063             portalForceAuthn => 'bool:/portalForceAuthn',
1064             key => 'text:/key',
1065             trustedDomains => 'text:/trustedDomains',
1066             useSafeJail => 'bool:/useSafeJail',
1067             checkXSS => 'bool:/checkXSS',
1068             },
1069              
1070             redirection => {
1071             _nodes => [
1072             qw(https port useRedirectOnForbidden useRedirectOnError maintenance)
1073             ],
1074             _help => 'redirections',
1075             https => 'bool:/https',
1076             port => 'int:/port',
1077             useRedirectOnForbidden => 'bool:/useRedirectOnForbidden',
1078             useRedirectOnError => 'bool:/useRedirectOnError',
1079             maintenance => 'bool:/maintenance',
1080             },
1081              
1082             portalRedirection => {
1083             _nodes => [qw(jsRedirect)],
1084             _help => 'portalRedirections',
1085             jsRedirect =>
1086             'text:/jsRedirect:portalRedirections:boolOrPerlExpr',
1087             },
1088              
1089             specialHandlers => {
1090             _nodes =>
1091             [qw(zimbraHandler sympaHandler secureTokenHandler)],
1092              
1093             # Zimbra
1094             zimbraHandler => {
1095             _nodes => [
1096             qw(zimbraPreAuthKey zimbraAccountKey zimbraBy zimbraUrl zimbraSsoUrl)
1097             ],
1098             _help => 'zimbra',
1099             zimbraPreAuthKey => 'text:/zimbraPreAuthKey',
1100             zimbraAccountKey => 'text:/zimbraAccountKey',
1101             zimbraBy => 'text:/zimbraBy:default:zimbraByParams',
1102             zimbraUrl => 'text:/zimbraUrl',
1103             zimbraSsoUrl => 'text:/zimbraSsoUrl',
1104             },
1105              
1106             # Sympa
1107             sympaHandler => {
1108             _nodes => [qw(sympaSecret sympaMailKey)],
1109             _help => 'sympa',
1110             sympaSecret => 'text:/sympaSecret',
1111             sympaMailKey => 'text:/sympaMailKey',
1112             },
1113              
1114             # Secure Token
1115             secureTokenHandler => {
1116             _nodes => [
1117             qw(secureTokenMemcachedServers secureTokenExpiration secureTokenAttribute secureTokenUrls secureTokenHeader secureTokenAllowOnError)
1118             ],
1119             _help => 'securetoken',
1120             secureTokenMemcachedServers =>
1121             'text:/secureTokenMemcachedServers',
1122             secureTokenExpiration => 'int:/secureTokenExpiration',
1123             secureTokenAttribute => 'text:secureTokenAttribute',
1124             secureTokenUrls => 'text:/secureTokenUrls',
1125             secureTokenHeader => 'text:/secureTokenHeader',
1126             secureTokenAllowOnError =>
1127             'bool:/secureTokenAllowOnError',
1128             },
1129             },
1130              
1131             logoutServices => {
1132             _nodes => ['hash:/logoutServices:logoutforward:btext'],
1133             _js => 'hashRoot',
1134             _help => 'logoutforward',
1135             },
1136              
1137             },
1138             },
1139              
1140             #############
1141             # VARIABLES #
1142             #############
1143              
1144             variables => {
1145             _nodes => [qw(cn:exportedVars cn:macros cn:groups)],
1146             _help => 'default',
1147              
1148             # EXPORTED ATTRIBUTES
1149             exportedVars => {
1150             _nodes => ['hash:/exportedVars:vars:btext'],
1151             _js => 'hashRoot',
1152             _help => 'exportedVars',
1153             },
1154              
1155             # MACROS
1156             macros => {
1157             _nodes => ['hash:/macros:macros:btext'],
1158             _js => 'hashRoot',
1159             _help => 'macrosandgroups',
1160             },
1161              
1162             # GROUPS
1163             groups => {
1164             _nodes => ['hash:/groups:groups:btext'],
1165             _js => 'hashRoot',
1166             _help => 'macrosandgroups',
1167             },
1168             },
1169              
1170             #################
1171             # VIRTUAL HOSTS #
1172             #################
1173             virtualHosts => {
1174             _nodes => ['nhash:/locationRules:virtualHosts:vhost'],
1175             _upload => [qw(/exportedHeaders /post /vhostOptions)],
1176             _help => 'virtualHosts',
1177             _js => 'vhostRoot',
1178             },
1179              
1180             ########
1181             # SAML #
1182             ########
1183             # virtual keys should not begin like configuration keys.
1184             samlIDPMetaDataNode => {
1185             _nodes => [
1186             'nhash:/samlIDPMetaDataExportedAttributes:samlIDPMetaDataNode:samlIdpMetaData'
1187             ],
1188             _upload => [ '/samlIDPMetaDataXML', '/samlIDPMetaDataOptions' ],
1189             _help => 'samlIDP',
1190             _js => 'samlIdpRoot',
1191             },
1192              
1193             samlSPMetaDataNode => {
1194             _nodes => [
1195             'nhash:/samlSPMetaDataExportedAttributes:samlSPMetaDataNode:samlSpMetaData'
1196             ],
1197             _upload => [ '/samlSPMetaDataXML', '/samlSPMetaDataOptions' ],
1198             _help => 'samlSP',
1199             _js => 'samlSpRoot',
1200             },
1201              
1202             samlServiceMetaData => {
1203             _nodes => [
1204             qw(samlEntityID
1205             n:samlServiceSecurity
1206             n:samlNameIDFormatMap
1207             n:samlAuthnContextMap
1208             n:samlOrganization
1209             n:samlSPSSODescriptor
1210             n:samlIDPSSODescriptor
1211             n:samlAttributeAuthorityDescriptor
1212             n:samlAdvanced)
1213             ],
1214             _help => 'samlService',
1215              
1216             # GLOBAL INFORMATIONS
1217             samlEntityID => 'text:/samlEntityID:samlServiceEntityID:text',
1218              
1219             # SECURITY NODE
1220             samlServiceSecurity => {
1221             _nodes =>
1222             [qw(n:samlServiceSecuritySig n:samlServiceSecurityEnc)],
1223             _help => 'samlServiceSecurity',
1224             samlServiceSecuritySig => {
1225             _nodes => [
1226             qw(samlServicePrivateKeySig
1227             samlServicePrivateKeySigPwd
1228             samlServicePublicKeySig)
1229             ],
1230             samlServicePrivateKeySig =>
1231             'filearea:/samlServicePrivateKeySig',
1232             samlServicePrivateKeySigPwd =>
1233             'text:/samlServicePrivateKeySigPwd',
1234             samlServicePublicKeySig =>
1235             'filearea:/samlServicePublicKeySig',
1236             },
1237             samlServiceSecurityEnc => {
1238             _nodes => [
1239             qw(samlServicePrivateKeyEnc
1240             samlServicePrivateKeyEncPwd
1241             samlServicePublicKeyEnc)
1242             ],
1243             samlServicePrivateKeyEnc =>
1244             'filearea:/samlServicePrivateKeyEnc',
1245             samlServicePrivateKeyEncPwd =>
1246             'text:/samlServicePrivateKeyEncPwd',
1247             samlServicePublicKeyEnc =>
1248             'filearea:/samlServicePublicKeyEnc',
1249             },
1250             },
1251              
1252             # NAMEID FORMAT MAP
1253             samlNameIDFormatMap => {
1254             _nodes => [
1255             qw(samlNameIDFormatMapEmail samlNameIDFormatMapX509 samlNameIDFormatMapWindows samlNameIDFormatMapKerberos)
1256             ],
1257             _help => 'samlServiceNameIDFormats',
1258             samlNameIDFormatMapEmail => 'text:/samlNameIDFormatMapEmail',
1259             samlNameIDFormatMapX509 => 'text:/samlNameIDFormatMapX509',
1260             samlNameIDFormatMapWindows =>
1261             'text:/samlNameIDFormatMapWindows',
1262             samlNameIDFormatMapKerberos =>
1263             'text:/samlNameIDFormatMapKerberos',
1264             },
1265              
1266             # AUTHN CONTEXT MAP
1267             samlAuthnContextMap => {
1268             _nodes => [
1269             qw(samlAuthnContextMapPassword samlAuthnContextMapPasswordProtectedTransport samlAuthnContextMapTLSClient samlAuthnContextMapKerberos)
1270             ],
1271             _help => 'samlServiceAuthnContexts',
1272             samlAuthnContextMapPassword =>
1273             'int:/samlAuthnContextMapPassword',
1274             samlAuthnContextMapPasswordProtectedTransport =>
1275             'int:/samlAuthnContextMapPasswordProtectedTransport',
1276             samlAuthnContextMapTLSClient =>
1277             'int:/samlAuthnContextMapTLSClient',
1278             samlAuthnContextMapKerberos =>
1279             'int:/samlAuthnContextMapKerberos',
1280             },
1281              
1282             # ORGANIZATION
1283             samlOrganization => {
1284             _nodes => [
1285             qw(samlOrganizationDisplayName
1286             samlOrganizationName
1287             samlOrganizationURL)
1288             ],
1289             _help => 'samlServiceOrganization',
1290             samlOrganizationDisplayName =>
1291             'text:/samlOrganizationDisplayName',
1292             samlOrganizationURL => 'text:/samlOrganizationURL',
1293             samlOrganizationName => 'text:/samlOrganizationName',
1294             },
1295              
1296             # SERVICE PROVIDER
1297             'samlSPSSODescriptor' => {
1298             _nodes => [
1299             qw(samlSPSSODescriptorAuthnRequestsSigned
1300             samlSPSSODescriptorWantAssertionsSigned
1301             n:samlSPSSODescriptorSingleLogoutService
1302             n:samlSPSSODescriptorAssertionConsumerService
1303             n:samlSPSSODescriptorArtifactResolutionService
1304             )
1305             ],
1306             _help => 'samlServiceSP',
1307              
1308             samlSPSSODescriptorAuthnRequestsSigned =>
1309             'bool:/samlSPSSODescriptorAuthnRequestsSigned',
1310             samlSPSSODescriptorWantAssertionsSigned =>
1311             'bool:/samlSPSSODescriptorWantAssertionsSigned',
1312              
1313             samlSPSSODescriptorSingleLogoutService => {
1314             _nodes => [
1315             qw(samlSPSSODescriptorSingleLogoutServiceHTTPRedirect
1316             samlSPSSODescriptorSingleLogoutServiceHTTPPost
1317             samlSPSSODescriptorSingleLogoutServiceSOAP)
1318             ],
1319             samlSPSSODescriptorSingleLogoutServiceHTTPRedirect =>
1320             'samlService:/samlSPSSODescriptorSingleLogoutServiceHTTPRedirect',
1321             samlSPSSODescriptorSingleLogoutServiceHTTPPost =>
1322             'samlService:/samlSPSSODescriptorSingleLogoutServiceHTTPPost',
1323             samlSPSSODescriptorSingleLogoutServiceSOAP =>
1324             'samlService:/samlSPSSODescriptorSingleLogoutServiceSOAP',
1325             },
1326              
1327             samlSPSSODescriptorAssertionConsumerService => {
1328             _nodes => [
1329             qw(samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact
1330             samlSPSSODescriptorAssertionConsumerServiceHTTPPost)
1331             ],
1332             samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact =>
1333             'samlAssertion:/samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact',
1334             samlSPSSODescriptorAssertionConsumerServiceHTTPPost =>
1335             'samlAssertion:/samlSPSSODescriptorAssertionConsumerServiceHTTPPost',
1336             },
1337              
1338             samlSPSSODescriptorArtifactResolutionService => {
1339             _nodes => [
1340             qw(samlSPSSODescriptorArtifactResolutionServiceArtifact)
1341             ],
1342             samlSPSSODescriptorArtifactResolutionServiceArtifact =>
1343             'samlAssertion:/samlSPSSODescriptorArtifactResolutionServiceArtifact',
1344             },
1345             },
1346              
1347             # IDENTITY PROVIDER
1348             samlIDPSSODescriptor => {
1349             _nodes => [
1350             qw(samlIDPSSODescriptorWantAuthnRequestsSigned
1351             n:samlIDPSSODescriptorSingleSignOnService
1352             n:samlIDPSSODescriptorSingleLogoutService
1353             n:samlIDPSSODescriptorArtifactResolutionService)
1354             ],
1355             _help => 'samlServiceIDP',
1356              
1357             samlIDPSSODescriptorWantAuthnRequestsSigned =>
1358             'bool:/samlIDPSSODescriptorWantAuthnRequestsSigned',
1359              
1360             samlIDPSSODescriptorSingleSignOnService => {
1361             _nodes => [
1362             qw(samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect
1363             samlIDPSSODescriptorSingleSignOnServiceHTTPPost
1364             samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact
1365             samlIDPSSODescriptorSingleSignOnServiceSOAP)
1366             ],
1367             samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect =>
1368             'samlService:/samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect',
1369             samlIDPSSODescriptorSingleSignOnServiceHTTPPost =>
1370             'samlService:/samlIDPSSODescriptorSingleSignOnServiceHTTPPost',
1371             samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact =>
1372             'samlService:/samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact',
1373             samlIDPSSODescriptorSingleSignOnServiceSOAP =>
1374             'samlService:/samlIDPSSODescriptorSingleSignOnServiceSOAP',
1375             },
1376              
1377             samlIDPSSODescriptorSingleLogoutService => {
1378             _nodes => [
1379             qw(samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect
1380             samlIDPSSODescriptorSingleLogoutServiceHTTPPost
1381             samlIDPSSODescriptorSingleLogoutServiceSOAP)
1382             ],
1383             samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect =>
1384             'samlService:/samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect',
1385             samlIDPSSODescriptorSingleLogoutServiceHTTPPost =>
1386             'samlService:/samlIDPSSODescriptorSingleLogoutServiceHTTPPost',
1387             samlIDPSSODescriptorSingleLogoutServiceSOAP =>
1388             'samlService:/samlIDPSSODescriptorSingleLogoutServiceSOAP',
1389             },
1390              
1391             samlIDPSSODescriptorArtifactResolutionService => {
1392             _nodes => [
1393             qw(samlIDPSSODescriptorArtifactResolutionServiceArtifact)
1394             ],
1395             samlIDPSSODescriptorArtifactResolutionServiceArtifact =>
1396             'samlAssertion:/samlIDPSSODescriptorArtifactResolutionServiceArtifact',
1397             },
1398              
1399             },
1400              
1401             # ATTRIBUTE AUTHORITY
1402             samlAttributeAuthorityDescriptor => {
1403             _nodes =>
1404             [qw(n:samlAttributeAuthorityDescriptorAttributeService)],
1405             _help => 'samlServiceAA',
1406              
1407             samlAttributeAuthorityDescriptorAttributeService => {
1408             _nodes => [
1409             qw(samlAttributeAuthorityDescriptorAttributeServiceSOAP)
1410             ],
1411             samlAttributeAuthorityDescriptorAttributeServiceSOAP =>
1412             'samlService:/samlAttributeAuthorityDescriptorAttributeServiceSOAP',
1413             },
1414             },
1415              
1416             # ADVANCED SAML PARAMETERS
1417             samlAdvanced => {
1418             _nodes => [
1419             qw(samlIdPResolveCookie samlMetadataForceUTF8 samlStorage cn:samlStorageOptions samlRelayStateTimeout samlUseQueryStringSpecific n:samlCommonDomainCookie)
1420             ],
1421             _help => 'samlServiceAdvanced',
1422              
1423             samlIdPResolveCookie => 'text:/samlIdPResolveCookie',
1424             samlMetadataForceUTF8 => 'bool:/samlMetadataForceUTF8',
1425             samlStorage => 'text:/samlStorage',
1426             samlStorageOptions => {
1427             _nodes =>
1428             ['hash:/samlStorageOptions:samlServiceAdvanced:btext'],
1429             _js => 'hashRoot',
1430             _help => 'samlServiceAdvanced',
1431             },
1432             samlRelayStateTimeout => 'int:/samlRelayStateTimeout',
1433             samlUseQueryStringSpecific =>
1434             'bool:/samlUseQueryStringSpecific',
1435             samlCommonDomainCookie => {
1436             _nodes => [
1437             qw(samlCommonDomainCookieActivation samlCommonDomainCookieDomain samlCommonDomainCookieReader samlCommonDomainCookieWriter)
1438             ],
1439             samlCommonDomainCookieActivation =>
1440             'bool:/samlCommonDomainCookieActivation',
1441             samlCommonDomainCookieDomain =>
1442             'text:/samlCommonDomainCookieDomain',
1443             samlCommonDomainCookieReader =>
1444             'text:/samlCommonDomainCookieReader',
1445             samlCommonDomainCookieWriter =>
1446             'text:/samlCommonDomainCookieWriter',
1447             },
1448              
1449             },
1450              
1451             },
1452             };
1453             }
1454              
1455             ## @method protected hashref testStruct()
1456             # Returns the tests to do with the datas uploaded.
1457             # @return hashref
1458             sub testStruct {
1459             my $safe = Safe->new();
1460             my $perlExpr = sub {
1461             my $e = shift;
1462             $safe->reval( $e, 1 );
1463             return 1 unless ($@);
1464             return 1
1465             if ( $@ =~ /Global symbol "\$.*requires explicit package/ );
1466             return ( 1,
1467             "Function \"$1$2\" must be declared in customFunctions" )
1468             if ( $@ =~
1469             /(?:Bareword "(\w+)" not allowed while "strict subs"|Undefined subroutine &(?:.*?::)?(\w+))/
1470             );
1471             return ( 0, $@ );
1472             };
1473             my $noAssign = sub {
1474             my $e = shift;
1475             my $assignTest = qr/(?<=[^=\|\?])=(?![=~])/;
1476             return $e =~ $assignTest ? ( 0, "contains an assignment" ) : 1;
1477             };
1478             my $boolean = { test => qr/^(?:0|1)?$/, msgFail => 'Value must be 0 or 1' };
1479             my $integer =
1480             { test => qr/^(?:\d)+$/, msgFail => 'Value must be an integer' };
1481             my $pcre = sub {
1482             my $r = shift;
1483             my $q;
1484             eval { $q = qr/$r/ };
1485             return ( $@ ? ( 0, $@ ) : 1 );
1486             };
1487             my $domainNameOrIp = sub {
1488             my $n = shift;
1489             return
1490             $n =~ /^(\d{1,3}\.){3}\d{1,3}$/
1491             || $n =~ Lemonldap::NG::Common::Regexp::HOSTNAME()
1492             || ( 0, 'Bad server name or IP' );
1493             };
1494             my $testNotDefined = { test => sub { 1 }, msgFail => 'Ok' };
1495             my $lmAttrOrMacro = {
1496             test => qr/^\$?[a-zA-Z_]\w*$/,
1497             msgFail => 'Value must be in the form $attr'
1498             };
1499             return {
1500             applicationList => {
1501             keyTest => qr/^(\d*)?\w+$/,
1502             keyMsgFail => 'Bad category ID',
1503             },
1504             mailCharset => $testNotDefined,
1505             mailFrom => $testNotDefined,
1506             mailReplyTo => $testNotDefined,
1507             trustedDomains => $testNotDefined,
1508             exportedAttr => $testNotDefined,
1509             mailSubject => $testNotDefined,
1510             randomPasswordRegexp => $testNotDefined,
1511             passwordDB => $testNotDefined,
1512             mailBody => $testNotDefined,
1513             SMTPServer => $testNotDefined,
1514             SMTPAuthUser => $testNotDefined,
1515             SMTPAuthPass => $testNotDefined,
1516             cookieExpiration => $testNotDefined,
1517             notificationStorage => $testNotDefined,
1518             notificationWildcard => $testNotDefined,
1519             notificationXSLTfile => $testNotDefined,
1520             mailUrl => $testNotDefined,
1521             mailTimeout => $integer,
1522             mailSessionKey => $testNotDefined,
1523             mailConfirmSubject => $testNotDefined,
1524             mailConfirmBody => $testNotDefined,
1525             authentication => {
1526             test => sub {
1527             my $e = shift;
1528              
1529             # Do not check syntax for Multi
1530             return 1 if ( $e =~ /^multi/i );
1531              
1532             # Else, check the authentication module is valid
1533             return ( $e =~ qr/^[a-zA-Z]+$/ );
1534             },
1535             msgFail => 'Bad module name',
1536             },
1537             captcha_login_enabled => $boolean,
1538             captcha_mail_enabled => $boolean,
1539             captcha_register_enabled => $boolean,
1540             captcha_size => $integer,
1541             captcha_data => $testNotDefined,
1542             captcha_output => $testNotDefined,
1543             captchaStorage => {
1544             test => qr/^[\w:]+$/,
1545             msgFail => 'Bad module name',
1546             },
1547             captchaStorageOptions => {
1548             keyTest => qr/^\w+$/,
1549             keyMsgFail => 'Bad parameter',
1550             },
1551             cda => $boolean,
1552             checkXSS => $boolean,
1553             cookieName => {
1554             test => qr/^[a-zA-Z]\w*$/,
1555             msgFail => 'Bad cookie name',
1556             },
1557             customFunctions => $testNotDefined,
1558             dbiExportedVars => {
1559             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1560             keyMsgFail => 'Bad variable name',
1561             test => qr/^[a-zA-Z][\w:\-]*$/,
1562             msgFail => 'Bad attribute name',
1563             },
1564             demoExportedVars => {
1565             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1566             keyMsgFail => 'Bad variable name',
1567             test => qr/^[a-zA-Z][\w:\-]*$/,
1568             msgFail => 'Bad attribute name',
1569             },
1570             domain => {
1571             test => qr/^\.?[\w\-]+(?:\.[a-zA-Z][\w\-]*)*(?:\.[a-zA-Z]+)$/,
1572             msgFail => 'Bad domain',
1573             },
1574             exportedHeaders => {
1575             keyTest => Lemonldap::NG::Common::Regexp::HOSTNAME(),
1576             keyMsgFail => 'Bad virtual host name',
1577             '*' => {
1578             keyTest => qr/^\w([\w\-]*\w)?$/,
1579             keyMsgFail => 'Bad header name',
1580             test => $perlExpr,
1581             warnTest => $noAssign,
1582             },
1583             },
1584             exportedVars => {
1585             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1586             keyMsgFail => 'Bad variable name',
1587             test => qr/^[a-zA-Z][\w:\-]*$/,
1588             msgFail => 'Bad attribute name',
1589             },
1590             facebookExportedVars => {
1591             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1592             keyMsgFail => 'Bad variable name',
1593             test => qr/^[a-zA-Z][\w:\-]*$/,
1594             msgFail => 'Bad attribute name',
1595             },
1596             failedLoginNumber => $integer,
1597             globalStorage => {
1598             test => qr/^[\w:]+$/,
1599             msgFail => 'Bad module name',
1600             },
1601             globalStorageOptions => {
1602             keyTest => qr/^\w+$/,
1603             keyMsgFail => 'Bad parameter',
1604             },
1605             googleExportedVars => {
1606             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1607             keyMsgFail => 'Bad variable name',
1608             test => qr/^[a-zA-Z][\w:\-]*$/,
1609             msgFail => 'Bad attribute name',
1610             },
1611             grantSessionRules => {
1612             keyTest => $perlExpr,
1613             warnKeyTest => $noAssign,
1614             },
1615             groups => {
1616             keyTest => qr/^\w[\w-]*$/,
1617             keyMsgFail => 'Bad group name',
1618             test => $perlExpr,
1619             warnTest => $noAssign,
1620             },
1621             httpOnly => $boolean,
1622             https => $boolean,
1623             issuerDBSAMLActivation => $boolean,
1624             issuerDBSAMLPath => $testNotDefined,
1625             issuerDBSAMLRule => {
1626             test => $perlExpr,
1627             warnTest => $noAssign,
1628             },
1629             issuerDBCASActivation => $boolean,
1630             issuerDBCASPath => $testNotDefined,
1631             issuerDBCASRule => {
1632             test => $perlExpr,
1633             warnTest => $noAssign,
1634             },
1635             issuerDBOpenIDActivation => $boolean,
1636             issuerDBOpenIDPath => $testNotDefined,
1637             issuerDBOpenIDRule => {
1638             test => $perlExpr,
1639             warnTest => $noAssign,
1640             },
1641             jsRedirect => { test => $perlExpr, },
1642             key => $testNotDefined,
1643             ldapAuthnLevel => $integer,
1644             ldapBase => {
1645             test => qr/^(?:\w+=.*|)$/,
1646             msgFail => 'Bad LDAP base',
1647             },
1648             ldapExportedVars => {
1649             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1650             keyMsgFail => 'Bad variable name',
1651             test => qr/^[a-zA-Z][\w:\-]*$/,
1652             msgFail => 'Bad attribute name',
1653             },
1654             ldapPort => {
1655             test => qr/^\d*$/,
1656             msgFail => 'Bad port number'
1657             },
1658             ldapServer => {
1659             test => sub {
1660             my $l = shift;
1661             my @s = split( /[\s,]+/, $l );
1662             foreach my $s (@s) {
1663             $s =~
1664             m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?::\d{1,5})?/?.*)$}o
1665             or return ( 0, "Bad ldap uri \"$s\"" );
1666             }
1667             return 1;
1668             },
1669             },
1670             ldapPwdEnc => {
1671             test => qr/^\w[\w\-]*\w$/,
1672             msgFail => 'Bad encoding',
1673             },
1674             ldapUsePasswordResetAttribute => $boolean,
1675             ldapPasswordResetAttribute => $testNotDefined,
1676             ldapPasswordResetAttributeValue => $testNotDefined,
1677             ldapPpolicyControl => $boolean,
1678             ldapSetPassword => $boolean,
1679             ldapChangePasswordAsUser => $boolean,
1680             mailLDAPFilter => $testNotDefined,
1681             LDAPFilter => $testNotDefined,
1682             AuthLDAPFilter => $testNotDefined,
1683             ldapGroupRecursive => $boolean,
1684             ldapGroupObjectClass => $testNotDefined,
1685             ldapGroupBase => $testNotDefined,
1686             ldapGroupAttributeName => $testNotDefined,
1687             ldapGroupAttributeNameUser => $testNotDefined,
1688             ldapGroupAttributeNameSearch => $testNotDefined,
1689             ldapGroupAttributeNameGroup => $testNotDefined,
1690             ldapTimeout => $testNotDefined,
1691             ldapVersion => $testNotDefined,
1692             ldapRaw => $testNotDefined,
1693             localSessionStorage => {
1694             test => qr/^[\w:]+$/,
1695             msgFail => 'Bad module name',
1696             },
1697             localSessionStorageOptions => {
1698             keyTest => qr/^\w+$/,
1699             keyMsgFail => 'Bad parameter',
1700             },
1701             locationRules => {
1702             keyTest => Lemonldap::NG::Common::Regexp::HOSTNAME(),
1703             msgFail => 'Bad virtual host name',
1704             '*' => {
1705             keyTest => $pcre,
1706             test => sub {
1707             my $e = shift;
1708             return 1 if ( $e =~ /^(?:accept|deny|unprotect|skip)$/i );
1709             if ( $e =~ s/^logout(?:_(?:app_sso|app|sso))?\s*// ) {
1710             return (
1711             $e eq ''
1712             or $e =~ Lemonldap::NG::Common::Regexp::HTTP_URI()
1713             ? 1
1714             : ( 0, "bad url \"$e\"" )
1715             );
1716             }
1717             return &$perlExpr($e);
1718             },
1719             warnTest => $noAssign,
1720             },
1721             },
1722             loginHistoryEnabled => $boolean,
1723             logoutServices => {
1724             keyTest => qr/^\w+$/,
1725             keyMsgFail => 'Bad name',
1726             },
1727             macros => {
1728             keyTest => qr/^[_a-zA-Z]\w*$/,
1729             keyMsgFail => 'Bad macro name',
1730             test => $perlExpr,
1731             warnTest => $noAssign,
1732             },
1733             mailOnPasswordChange => $boolean,
1734             maintenance => $boolean,
1735             managerDn => {
1736             test => qr/^(?:\w+=.*)?$/,
1737             msgFail => 'Bad LDAP dn',
1738             },
1739             managerPassword => {
1740             test => qr/^\S*$/,
1741             msgFail => 'Bad LDAP password',
1742             },
1743             notification => $boolean,
1744             notificationStorage => {
1745             test => qr/^[\w:]+$/,
1746             msgFail => 'Bad module name',
1747             },
1748             notificationStorageOptions => {
1749             keyTest => qr/^\w+$/,
1750             keyMsgFail => 'Bad parameter',
1751             },
1752             notifyDeleted => $boolean,
1753             notifyOther => $boolean,
1754             openIdExportedVars => {
1755             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1756             keyMsgFail => 'Bad variable name',
1757             test => qr/^[a-zA-Z][\w:\-]*$/,
1758             msgFail => 'Bad attribute name',
1759             },
1760             persistentStorageOptions => {
1761             keyTest => qr/^\w+$/,
1762             keyMsgFail => 'Bad parameter',
1763             },
1764             port => {
1765             test => qr/^\d*$/,
1766             msgFail => 'Bad port number'
1767             },
1768             portal => {
1769             test => qr/^https?:\/\/\S+$/,
1770             msgFail => 'Bad portal value',
1771             },
1772             portalAutocomplete => $boolean,
1773             portalCheckLogins => $boolean,
1774             portalDisplayLoginHistory => { test => $perlExpr, },
1775             portalDisplayAppslist => { test => $perlExpr, },
1776             portalDisplayChangePassword => { test => $perlExpr, },
1777             portalDisplayLogout => { test => $perlExpr, },
1778             portalDisplayRegister => $boolean,
1779             portalDisplayResetPassword => $boolean,
1780             portalForceAuthn => $boolean,
1781             portalOpenLinkInNewWindow => $boolean,
1782             portalAntiFrame => $boolean,
1783             portalParams => $testNotDefined,
1784             portalPingInterval => $integer,
1785             portalRequireOldPassword => $boolean,
1786             hideOldPassword => $boolean,
1787             portalSkin => {
1788             test => qr/\w+$/,
1789             msgFail => 'Bad skin name',
1790             },
1791             portalSkinRules => {
1792             keyTest => $perlExpr,
1793             keyMsgFail => 'Bad skin rule',
1794             test => qr/\w+$/,
1795             msgFail => 'Bad skin name',
1796             },
1797             portalUserAttr => {
1798             test => qr/\w+$/,
1799             msgFail => 'Unvalid session field',
1800             },
1801             post => {
1802             keyTest => Lemonldap::NG::Common::Regexp::HOSTNAME(),
1803             keyMsgFail => 'Bad virtual host name',
1804             '*' => { keyTest => $pcre, },
1805             },
1806             protection => {
1807             keyTest => qr/^(?:none|authentificate|manager|)$/,
1808             msgFail => 'must be one of none authentificate manager',
1809             },
1810             registerConfirmSubject => $testNotDefined,
1811             registerDB => $testNotDefined,
1812             registerDoneSubject => $testNotDefined,
1813             registerTimeout => $integer,
1814             registerUrl => $testNotDefined,
1815             reloadUrls => {
1816             keyTest => $domainNameOrIp,
1817             test => Lemonldap::NG::Common::Regexp::HTTP_URI(),
1818             msgFail => 'Bad url'
1819             },
1820             securedCookie => {
1821             test => qr/^(?:0|1|2|3)$/,
1822             msgFail => 'securedCookie must be 0, 1, 2 or 3',
1823             },
1824             sessionDataToRemember => {
1825             keyTest => qr/^[\w-]+$/,
1826             keyMsgFail => 'Invalid session data',
1827             },
1828             singleSession => $boolean,
1829             singleIP => $boolean,
1830             singleUserByIP => $boolean,
1831             slaveExportedVars => {
1832             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1833             keyMsgFail => 'Bad variable name',
1834             test => qr/^[a-zA-Z][\w:\-]*$/,
1835             msgFail => 'Bad attribute name',
1836             },
1837             slaveMasterIP => {
1838             test =>
1839             qr/^(\s*((\d{1,3}\.){3}\d{1,3}\s+)*(\d{1,3}\.){3}\d{1,3})?\s*$/,
1840             msgFail => 'Bad parameter "master\'s IP" in Slave',
1841             },
1842             Soap => $boolean,
1843             storePassword => $boolean,
1844             successLoginNumber => $integer,
1845             syslog => {
1846             test => qw/^(?:auth|authpriv|daemon|local\d|user)?$/,
1847             msgFail =>
1848             'Only auth|authpriv|daemon|local0-7|user is allowed here',
1849             },
1850             timeout => {
1851             test => qr/^\d*$/,
1852             msgFail => 'Bad number'
1853             },
1854             timeoutActivity => {
1855             test => qr/^\d*$/,
1856             msgFail => 'Bad number',
1857             },
1858             trustedProxies => $testNotDefined,
1859             userControl => {
1860             test => $pcre,
1861             msgFail => 'Bad regular expression',
1862             },
1863             userDB => {
1864             test => sub {
1865             my $e = shift;
1866              
1867             # Do not check syntax for Multi
1868             return 1 if ( $e =~ /^multi/i );
1869              
1870             # Else, check the user module is valid
1871             return ( $e =~ qr/^[a-zA-Z]+$/ );
1872             },
1873             msgFail => 'Bad module name',
1874             },
1875             useRedirectOnError => $boolean,
1876             useRedirectOnForbidden => $boolean,
1877             useSafeJail => $boolean,
1878             variables => $testNotDefined,
1879             vhostOptions => {
1880             keyTest => Lemonldap::NG::Common::Regexp::HOSTNAME(),
1881             keyMsgFail => 'Bad virtual host name',
1882             '*' => {
1883             keyTest => qr/^vhost(Port|Https|Maintenance|Aliases)$/,
1884             keyMsgFail => 'Bad option name',
1885             },
1886             },
1887             webIDExportedVars => {
1888             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1889             keyMsgFail => 'Bad variable name',
1890             test => qr/^[a-zA-Z][\w:\-]*$/,
1891             msgFail => 'Bad attribute name',
1892             },
1893             whatToTrace => $lmAttrOrMacro,
1894              
1895             ########
1896             # SAML #
1897             ########
1898             saml => $testNotDefined,
1899             samlServiceMetaData => $testNotDefined,
1900             samlIDPMetaDataExportedAttributes => {
1901             keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
1902             keyMsgFail => 'Bad metadata name',
1903             '*' => {
1904             keyTest => qr/^\w([\w\-]*\w)?$/,
1905             keyMsgFail => 'Bad attribute name',
1906             test => sub { return 1; },
1907             },
1908             },
1909             samlIDPMetaDataXML => {
1910             keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
1911             keyMsgFail => 'Bad metadata name',
1912             '*' => {
1913             test => sub { return 1; },
1914             keyTest => sub { return 1; },
1915             },
1916             },
1917             samlIDPMetaDataOptions => {
1918             keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
1919             keyMsgFail => 'Bad metadata name',
1920             '*' => {
1921             test => sub { return 1; },
1922             keyTest => sub { return 1; },
1923             },
1924             },
1925             samlSPMetaDataExportedAttributes => {
1926             keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
1927             keyMsgFail => 'Bad metadata name',
1928             '*' => {
1929             keyTest => qr/^\w([\w\-]*\w)?$/,
1930             keyMsgFail => 'Bad attribute name',
1931             test => sub { return 1; },
1932             },
1933             },
1934             samlSPMetaDataXML => {
1935             keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
1936             keyMsgFail => 'Bad metadata name',
1937             '*' => {
1938             test => sub { return 1; },
1939             keyTest => sub { return 1; },
1940             },
1941             },
1942             samlSPMetaDataOptions => {
1943             keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
1944             keyMsgFail => 'Bad metadata name',
1945             '*' => {
1946             test => sub { return 1; },
1947             keyTest => sub { return 1; },
1948             },
1949             },
1950             samlEntityID => $testNotDefined,
1951             samlOrganizationDisplayName => $testNotDefined,
1952             samlOrganizationName => $testNotDefined,
1953             samlOrganizationURL => $testNotDefined,
1954             samlSPSSODescriptorAuthnRequestsSigned => $boolean,
1955             samlSPSSODescriptorWantAssertionsSigned => $boolean,
1956             samlSPSSODescriptorSingleLogoutServiceHTTPRedirect => $testNotDefined,
1957             samlSPSSODescriptorSingleLogoutServiceHTTPPost => $testNotDefined,
1958             samlSPSSODescriptorSingleLogoutServiceSOAP => $testNotDefined,
1959             samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact =>
1960             $testNotDefined,
1961             samlSPSSODescriptorAssertionConsumerServiceHTTPPost => $testNotDefined,
1962             samlSPSSODescriptorArtifactResolutionServiceArtifact => $testNotDefined,
1963             samlIDPSSODescriptorWantAuthnRequestsSigned => $boolean,
1964             samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect => $testNotDefined,
1965             samlIDPSSODescriptorSingleSignOnServiceHTTPPost => $testNotDefined,
1966             samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact => $testNotDefined,
1967             samlIDPSSODescriptorSingleSignOnServiceSOAP => $testNotDefined,
1968             samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect => $testNotDefined,
1969             samlIDPSSODescriptorSingleLogoutServiceHTTPPost => $testNotDefined,
1970             samlIDPSSODescriptorSingleLogoutServiceSOAP => $testNotDefined,
1971             samlIDPSSODescriptorArtifactResolutionServiceArtifact =>
1972             $testNotDefined,
1973             samlNameIDFormatMapEmail => $testNotDefined,
1974             samlNameIDFormatMapX509 => $testNotDefined,
1975             samlNameIDFormatMapWindows => $testNotDefined,
1976             samlNameIDFormatMapKerberos => $testNotDefined,
1977             samlAttributeAuthorityDescriptorAttributeServiceSOAP => $testNotDefined,
1978             samlServicePrivateKeySig => $testNotDefined,
1979             samlServicePrivateKeySigPwd => $testNotDefined,
1980             samlServicePublicKeySig => $testNotDefined,
1981             samlServicePrivateKeyEnc => $testNotDefined,
1982             samlServicePrivateKeyEncPwd => $testNotDefined,
1983             samlServicePublicKeyEnc => $testNotDefined,
1984             samlIdPResolveCookie => $testNotDefined,
1985             samlMetadataForceUTF8 => $boolean,
1986             samlStorage => {
1987             test => qr/^[\w:]*$/,
1988             msgFail => 'Bad module name',
1989             },
1990             samlStorageOptions => {
1991             keyTest => qr/^\w+$/,
1992             keyMsgFail => 'Bad parameter',
1993             },
1994             samlAuthnContextMapPassword => $integer,
1995             samlAuthnContextMapPasswordProtectedTransport => $integer,
1996             samlAuthnContextMapTLSClient => $integer,
1997             samlAuthnContextMapKerberos => $integer,
1998             samlCommonDomainCookieActivation => $boolean,
1999             samlCommonDomainCookieDomain => {
2000             test => Lemonldap::NG::Common::Regexp::HOSTNAME(),
2001             msgFail => 'Bad domain',
2002             },
2003             samlCommonDomainCookieReader => {
2004             test => Lemonldap::NG::Common::Regexp::HTTP_URI(),
2005             msgFail => 'Bad URI',
2006             },
2007             samlCommonDomainCookieWriter => {
2008             test => Lemonldap::NG::Common::Regexp::HTTP_URI(),
2009             msgFail => 'Bad URI',
2010             },
2011             samlRelayStateTimeout => $integer,
2012             samlUseQueryStringSpecific => $boolean,
2013              
2014             # SSL
2015             SSLAuthnLevel => $integer,
2016             SSLVar => $testNotDefined,
2017              
2018             # CAS
2019             CAS_authnLevel => $integer,
2020             CAS_url => {
2021             test => Lemonldap::NG::Common::Regexp::HTTP_URI(),
2022             msgFail => 'Bad CAS url',
2023             },
2024             CAS_CAFile => $testNotDefined,
2025             CAS_renew => $boolean,
2026             CAS_gateway => $boolean,
2027             CAS_pgtFile => $testNotDefined,
2028             CAS_proxiedServices => {
2029             keyTest => qr/^\w+$/,
2030             keyMsgFail => 'Bad CAS proxied service identifier',
2031             },
2032             casAttr => $testNotDefined,
2033             casAccessControlPolicy => $testNotDefined,
2034             casStorage => {
2035             test => qr/^[\w:]*$/,
2036             msgFail => 'Bad module name',
2037             },
2038             casStorageOptions => {
2039             keyTest => qr/^\w+$/,
2040             keyMsgFail => 'Bad parameter',
2041             },
2042              
2043             # Radius
2044             radiusAuthnLevel => $integer,
2045             radiusSecret => $testNotDefined,
2046             radiusServer => $testNotDefined,
2047              
2048             # Remote
2049             remotePortal => $testNotDefined,
2050             remoteGlobalStorage => {
2051             test => qr/^[\w:]+$/,
2052             msgFail => 'Bad module name',
2053             },
2054             remoteGlobalStorageOptions => {
2055             keyTest => qr/^\w+$/,
2056             keyMsgFail => 'Bad parameter',
2057             },
2058              
2059             # Proxy
2060             soapAuthService => $testNotDefined,
2061             remoteCookieName => $testNotDefined,
2062             soapSessionService => $testNotDefined,
2063              
2064             # OpenID
2065             openIdAuthnLevel => $integer,
2066             openIdSecret => $testNotDefined,
2067              
2068             # Google
2069             googleAuthnLevel => $integer,
2070              
2071             # Facebook
2072             facebookAuthnLevel => $integer,
2073             facebookAppId => $testNotDefined,
2074             facebookAppSecret => $testNotDefined,
2075              
2076             # Twitter
2077             twitterAuthnLevel => $integer,
2078             twitterKey => $testNotDefined,
2079             twitterSecret => $testNotDefined,
2080             twitterAppName => $testNotDefined,
2081              
2082             # WebID
2083             webIDAuthnLevel => $integer,
2084             webIDWhitelist => $testNotDefined,
2085              
2086             # DBI
2087             dbiAuthnLevel => $integer,
2088             dbiAuthChain => $testNotDefined,
2089             dbiAuthUser => $testNotDefined,
2090             dbiAuthPassword => $testNotDefined,
2091             dbiUserChain => $testNotDefined,
2092             dbiUserUser => $testNotDefined,
2093             dbiUserPassword => $testNotDefined,
2094             dbiAuthTable => $testNotDefined,
2095             dbiUserTable => $testNotDefined,
2096             dbiAuthLoginCol => $testNotDefined,
2097             dbiAuthPasswordCol => $testNotDefined,
2098             dbiPasswordMailCol => $testNotDefined,
2099             userPivot => $testNotDefined,
2100             dbiAuthPasswordHash => $testNotDefined,
2101              
2102             # Apache
2103             apacheAuthnLevel => $integer,
2104              
2105             # Null
2106             nullAuthnLevel => $integer,
2107              
2108             # Slave
2109             slaveAuthnLevel => $integer,
2110             slaveUserHeader => $testNotDefined,
2111              
2112             # Choice
2113             authChoiceParams => $testNotDefined,
2114             authChoiceModules => {
2115             keyTest => qr/^(\d*)?\w+$/,
2116             keyMsgFail => 'Bad choice key',
2117             },
2118              
2119             # Zimbra
2120             zimbraPreAuthKey => $testNotDefined,
2121             zimbraAccountKey => $testNotDefined,
2122             zimbraBy => $testNotDefined,
2123             zimbraUrl => $testNotDefined,
2124             zimbraSsoUrl => $testNotDefined,
2125              
2126             # Sympa
2127             sympaSecret => $testNotDefined,
2128             sympaMailKey => $testNotDefined,
2129              
2130             # OpenID Issuer
2131             openIdIssuerSecret => $testNotDefined,
2132             openIdAttr => $testNotDefined,
2133             openIdSreg_fullname => $lmAttrOrMacro,
2134             openIdSreg_nickname => $lmAttrOrMacro,
2135             openIdSreg_language => $lmAttrOrMacro,
2136             openIdSreg_postcode => $lmAttrOrMacro,
2137             openIdSreg_timezone => $lmAttrOrMacro,
2138             openIdSreg_country => $lmAttrOrMacro,
2139             openIdSreg_gender => $lmAttrOrMacro,
2140             openIdSreg_email => $lmAttrOrMacro,
2141             openIdSreg_dob => $lmAttrOrMacro,
2142              
2143             # Yubikey
2144             yubikeyAuthnLevel => $integer,
2145             yubikeyClientID => $testNotDefined,
2146             yubikeySecretKey => $testNotDefined,
2147             yubikeyPublicIDSize => $integer,
2148              
2149             # Secure Token
2150             secureTokenMemcachedServers => $testNotDefined,
2151             secureTokenExpiration => $integer,
2152             secureTokenAttribute => $testNotDefined,
2153             secureTokenUrls => $testNotDefined,
2154             secureTokenHeader => $testNotDefined,
2155             secureTokenAllowOnError => $boolean,
2156              
2157             # BrowserID
2158             browserIdAuthnLevel => $integer,
2159             browserIdAutoLogin => $boolean,
2160             browserIdVerificationURL => $testNotDefined,
2161             browserIdSiteName => $testNotDefined,
2162             browserIdSiteLogo => $testNotDefined,
2163             browserIdBackgroundColor => $testNotDefined,
2164             };
2165             }
2166             ## @method hashref subDefaultConf()
2167             # Return the default values of subattributes
2168             # @return hash ref { subattribute name => default value }
2169             sub subDefaultConf {
2170             my ($self) = splice @_;
2171             my $h;
2172              
2173             my $confSubAttributes = Lemonldap::NG::Common::Conf::SubAttributes->new();
2174             my @attributes = $confSubAttributes->meta()->get_attribute_list();
2175              
2176             foreach my $name (@attributes) {
2177             $h->{$name} = $confSubAttributes->$name;
2178             }
2179              
2180             return $h;
2181             }
2182              
2183             ## @method hashref globalTests(hashref conf)
2184             # Return a hash ref where keys are the names of the tests and values
2185             # subroutines to execute.
2186             #
2187             # Subroutines can return one of the followings :
2188             # - (1) : everything is OK
2189             # - (1,message) : OK with a warning
2190             # - (0,message) : NOK
2191             # - (-1,message) : OK, but must be confirmed (ignored if confirm parameter is
2192             # set
2193             #
2194             # Those subroutines can also modify configuration.
2195             #
2196             # @param $conf Configuration to test
2197             # @return hash ref where keys are the names of the tests and values
2198             sub globalTests {
2199             my ( $self, $conf ) = splice @_;
2200             return {
2201              
2202             # 1. CHECKS
2203              
2204             # Check if portal is in domain
2205             portalIsInDomain => sub {
2206             return (
2207             1,
2208             (
2209             index( $conf->{portal}, $conf->{domain} ) > 0
2210             ? ''
2211             : "Portal seems not to be in the domain $conf->{domain}"
2212             )
2213             );
2214             },
2215              
2216             # Check if virtual hosts are in the domain
2217             vhostInDomainOrCDA => sub {
2218             return 1 if ( $conf->{cda} );
2219             my @pb;
2220             foreach my $vh ( keys %{ $conf->{locationRules} } ) {
2221             push @pb, $vh unless ( index( $vh, $conf->{domain} ) >= 0 );
2222             }
2223             return (
2224             1,
2225             (
2226             @pb
2227             ? 'Virtual hosts '
2228             . join( ', ', @pb )
2229             . " are not in $conf->{domain} and cross-domain-authentication is not set"
2230             : undef
2231             )
2232             );
2233             },
2234              
2235             # Check if virtual host do not contain a port
2236             vhostWithPort => sub {
2237             my @pb;
2238             foreach my $vh ( keys %{ $conf->{locationRules} } ) {
2239             push @pb, $vh if ( $vh =~ /:/ );
2240             }
2241             if (@pb) {
2242             return ( 0,
2243             'Virtual hosts '
2244             . join( ', ', @pb )
2245             . " contain a port, this is not allowed" );
2246             }
2247             else { return 1; }
2248             },
2249              
2250             # Force vhost to be lowercase
2251             vhostUpperCase => sub {
2252             my @pb;
2253             foreach my $vh ( keys %{ $conf->{locationRules} } ) {
2254             push @pb, $vh if ( $vh ne lc $vh );
2255             }
2256             if (@pb) {
2257             return ( 0,
2258             'Virtual hosts '
2259             . join( ', ', @pb )
2260             . " must be in lower case" );
2261             }
2262             else { return 1; }
2263             },
2264              
2265             # Check if "userDB" and "authentication" are consistent
2266             authAndUserDBConsistency => sub {
2267             foreach my $type (qw(Facebook Google OpenID SAML WebID)) {
2268             return ( 0,
2269             "\"$type\" can not be used as user database without using \"$type\" for authentication"
2270             )
2271             if ( $conf->{userDB} =~ /$type/
2272             and $conf->{authentication} !~ /$type/ );
2273             }
2274             return 1;
2275             },
2276              
2277             # Check that OpenID macros exists
2278             checkAttrAndMacros => sub {
2279             my @tmp;
2280             foreach my $k ( keys %$conf ) {
2281             if ( $k =~
2282             /^(?:openIdSreg_(?:(?:(?:full|nick)nam|languag|postcod|timezon)e|country|gender|email|dob)|whatToTrace)$/
2283             )
2284             {
2285             my $v = $conf->{$k};
2286             $v =~ s/^$//;
2287             next if ( $v =~ /^_/ );
2288             push @tmp, $k
2289             unless (
2290             defined(
2291             $conf->{exportedVars}->{$v}
2292             or defined( $conf->{macros}->{$v} )
2293             )
2294             );
2295             }
2296             }
2297             return (
2298             1,
2299             (
2300             @tmp
2301             ? 'Values of parameter(s) "'
2302             . join( ', ', @tmp )
2303             . '" are not defined in exported attributes or macros'
2304             : ''
2305             )
2306             );
2307             },
2308              
2309             # Test that variables are exported if Google is used as UserDB
2310             checkUserDBGoogleAXParams => sub {
2311             my @tmp;
2312             if ( $conf->{userDB} =~ /^Google/ ) {
2313             while ( my ( $k, $v ) = each %{ $conf->{exportedVars} } ) {
2314             if ( $v !~ Lemonldap::NG::Common::Regexp::GOOGLEAXATTR() ) {
2315             push @tmp, $v;
2316             }
2317             }
2318             }
2319             return (
2320             1,
2321             (
2322             @tmp
2323             ? 'Values of parameter(s) "'
2324             . join( ', ', @tmp )
2325             . '" are not exported by Google'
2326             : ''
2327             )
2328             );
2329             },
2330              
2331             # Test that variables are exported if OpenID is used as UserDB
2332             checkUserDBOpenIDParams => sub {
2333             my @tmp;
2334             if ( $conf->{userDB} =~ /^OpenID/ ) {
2335             while ( my ( $k, $v ) = each %{ $conf->{exportedVars} } ) {
2336             if ( $v !~ Lemonldap::NG::Common::Regexp::OPENIDSREGATTR() )
2337             {
2338             push @tmp, $v;
2339             }
2340             }
2341             }
2342             return (
2343             1,
2344             (
2345             @tmp
2346             ? 'Values of parameter(s) "'
2347             . join( ', ', @tmp )
2348             . '" are not exported by OpenID SREG'
2349             : ''
2350             )
2351             );
2352             },
2353              
2354             # Try to use Apache::Session module
2355             testApacheSession => sub {
2356             my ( $id, %h );
2357             return 1
2358             if ( $Lemonldap::NG::Handler::_CGI::tsv->{globalStorage} eq
2359             $conf->{globalStorage}
2360             or $conf->{globalStorage} eq
2361             'Lemonldap::NG::Common::Apache::Session::SOAP' );
2362             eval "use $conf->{globalStorage}";
2363             return ( -1, "Unknown package $conf->{globalStorage}" ) if ($@);
2364             eval {
2365             tie %h, $conf->{globalStorage}, undef,
2366             $conf->{globalStorageOptions};
2367             };
2368             return ( -1, "Unable to create a session ($@)" )
2369             if ( $@ or not tied(%h) );
2370             eval {
2371             $h{a} = 1;
2372             $id = $h{_session_id} or return ( -1, 'No _session_id' );
2373             untie(%h);
2374             tie %h, $conf->{globalStorage}, $id,
2375             $conf->{globalStorageOptions};
2376             };
2377             return ( -1, "Unable to insert datas ($@)" ) if ($@);
2378             return ( -1, "Unable to recover data stored" )
2379             unless ( $h{a} == 1 );
2380             eval { tied(%h)->delete; };
2381             return ( -1, "Unable to delete session ($@)" ) if ($@);
2382             my $gc = $Lemonldap::NG::Handler::_CGI::tsv->{globalStorage};
2383             return ( -1,
2384             'All sessions may be lost and you must restart all your Apache servers'
2385             ) if ( $conf->{globalStorage} ne $gc );
2386             return 1;
2387             },
2388              
2389             # Warn if cookie name has changed
2390             cookieNameChanged => sub {
2391             return (
2392             1,
2393             (
2394             $Lemonldap::NG::Handler::_CGI::tsv->{cookieName} ne
2395             $conf->{cookieName}
2396             ? 'Cookie name has changed, you must restart all your Apache servers'
2397             : ()
2398             )
2399             );
2400             },
2401              
2402             # Warn if manager seems to be unprotected
2403             managerProtection => sub {
2404             return (
2405             1,
2406             (
2407             $conf->{cfgAuthor} eq 'anonymous'
2408             ? 'Your manager seems to be unprotected'
2409             : ''
2410             )
2411             );
2412             },
2413              
2414             # Test SMTP connection and authentication
2415             smtpConnectionAuthentication => sub {
2416              
2417             # Skip test if no SMTP configuration
2418             return 1 unless ( $conf->{SMTPServer} );
2419              
2420             # Use SMTP
2421             eval "use Net::SMTP";
2422             return ( 0, "Net::SMTP module is required to use SMTP server" )
2423             if ($@);
2424              
2425             # Create SMTP object
2426             my $smtp = Net::SMTP->new( $conf->{SMTPServer} );
2427             return ( 0,
2428             "SMTP connection to " . $conf->{SMTPServer} . " failed" )
2429             unless ($smtp);
2430              
2431             # Skip other tests if no authentication
2432             return 1
2433             unless ( $conf->{SMTPAuthUser} and $conf->{SMTPAuthPass} );
2434              
2435             # Try authentication
2436             return ( 0, "SMTP authentication failed" )
2437             unless $smtp->auth( $conf->{SMTPAuthUser},
2438             $conf->{SMTPAuthPass} );
2439              
2440             # Return
2441             return 1;
2442             },
2443              
2444             # 2. MODIFICATIONS
2445              
2446             # Remove unused and non-customized parameters
2447             compactModules => sub {
2448             foreach my $k ( keys %$conf ) {
2449              
2450             # No analysis for hash keys
2451             next if ( ref $conf->{$k} );
2452              
2453             # Check federation modules
2454             foreach my $type (qw(CAS OpenID SAML)) {
2455              
2456             # Check authChoice values
2457             my ( $authChoice, $userDBChoice ) = ( undef, undef );
2458             if ( $conf->{authentication} eq 'Choice'
2459             and defined $conf->{authChoiceModules} )
2460             {
2461             foreach ( keys %{ $conf->{authChoiceModules} } ) {
2462             my ( $auth, $userDB, $passwordDB ) =
2463             split( '|', $conf->{authChoiceModules}->{$_} );
2464             $authChoice = 1 if $auth =~ /$type/i;
2465             $userDBChoice = 1 if $userDB =~ /$type/i;
2466             }
2467             }
2468              
2469             if (
2470             (
2471             $k =~ /^$type/i
2472             and not( $conf->{"issuerDB${type}Activation"} )
2473             and not( $conf->{authentication} =~ /$type/i )
2474             and not( $conf->{userDB} =~ /$type/i )
2475             and not( defined $authChoice
2476             or defined $userDBChoice )
2477             )
2478             )
2479             {
2480             my $confAttributes =
2481             Lemonldap::NG::Common::Conf::Attributes->new();
2482             my $v = $confAttributes->$k;
2483             if ( defined($v) and $conf->{$k} eq $v ) {
2484             delete $conf->{$k};
2485             }
2486             }
2487             }
2488             return 1;
2489             }
2490             },
2491             };
2492             }
2493              
2494             1;
2495