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   28149 use strict;
  1         3  
  1         39  
9 1     1   560 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.1';
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 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             cda => $boolean,
1544             checkXSS => $boolean,
1545             cookieName => {
1546             test => qr/^[a-zA-Z]\w*$/,
1547             msgFail => 'Bad cookie name',
1548             },
1549             customFunctions => $testNotDefined,
1550             dbiExportedVars => {
1551             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1552             keyMsgFail => 'Bad variable name',
1553             test => qr/^[a-zA-Z][\w:\-]*$/,
1554             msgFail => 'Bad attribute name',
1555             },
1556             demoExportedVars => {
1557             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1558             keyMsgFail => 'Bad variable name',
1559             test => qr/^[a-zA-Z][\w:\-]*$/,
1560             msgFail => 'Bad attribute name',
1561             },
1562             domain => {
1563             test => qr/^\.?[\w\-]+(?:\.[a-zA-Z][\w\-]*)*(?:\.[a-zA-Z]+)$/,
1564             msgFail => 'Bad domain',
1565             },
1566             exportedHeaders => {
1567             keyTest => Lemonldap::NG::Common::Regexp::HOSTNAME(),
1568             keyMsgFail => 'Bad virtual host name',
1569             '*' => {
1570             keyTest => qr/^\w([\w\-]*\w)?$/,
1571             keyMsgFail => 'Bad header name',
1572             test => $perlExpr,
1573             warnTest => $noAssign,
1574             },
1575             },
1576             exportedVars => {
1577             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1578             keyMsgFail => 'Bad variable name',
1579             test => qr/^[a-zA-Z][\w:\-]*$/,
1580             msgFail => 'Bad attribute name',
1581             },
1582             facebookExportedVars => {
1583             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1584             keyMsgFail => 'Bad variable name',
1585             test => qr/^[a-zA-Z][\w:\-]*$/,
1586             msgFail => 'Bad attribute name',
1587             },
1588             failedLoginNumber => $integer,
1589             globalStorage => {
1590             test => qr/^[\w:]+$/,
1591             msgFail => 'Bad module name',
1592             },
1593             globalStorageOptions => {
1594             keyTest => qr/^\w+$/,
1595             keyMsgFail => 'Bad parameter',
1596             },
1597             googleExportedVars => {
1598             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1599             keyMsgFail => 'Bad variable name',
1600             test => qr/^[a-zA-Z][\w:\-]*$/,
1601             msgFail => 'Bad attribute name',
1602             },
1603             grantSessionRules => {
1604             keyTest => $perlExpr,
1605             warnKeyTest => $noAssign,
1606             },
1607             groups => {
1608             keyTest => qr/^\w[\w-]*$/,
1609             keyMsgFail => 'Bad group name',
1610             test => $perlExpr,
1611             warnTest => $noAssign,
1612             },
1613             httpOnly => $boolean,
1614             https => $boolean,
1615             issuerDBSAMLActivation => $boolean,
1616             issuerDBSAMLPath => $testNotDefined,
1617             issuerDBSAMLRule => {
1618             test => $perlExpr,
1619             warnTest => $noAssign,
1620             },
1621             issuerDBCASActivation => $boolean,
1622             issuerDBCASPath => $testNotDefined,
1623             issuerDBCASRule => {
1624             test => $perlExpr,
1625             warnTest => $noAssign,
1626             },
1627             issuerDBOpenIDActivation => $boolean,
1628             issuerDBOpenIDPath => $testNotDefined,
1629             issuerDBOpenIDRule => {
1630             test => $perlExpr,
1631             warnTest => $noAssign,
1632             },
1633             jsRedirect => { test => $perlExpr, },
1634             key => $testNotDefined,
1635             ldapAuthnLevel => $integer,
1636             ldapBase => {
1637             test => qr/^(?:\w+=.*|)$/,
1638             msgFail => 'Bad LDAP base',
1639             },
1640             ldapExportedVars => {
1641             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1642             keyMsgFail => 'Bad variable name',
1643             test => qr/^[a-zA-Z][\w:\-]*$/,
1644             msgFail => 'Bad attribute name',
1645             },
1646             ldapPort => {
1647             test => qr/^\d*$/,
1648             msgFail => 'Bad port number'
1649             },
1650             ldapServer => {
1651             test => sub {
1652             my $l = shift;
1653             my @s = split( /[\s,]+/, $l );
1654             foreach my $s (@s) {
1655             $s =~
1656             m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?::\d{1,5})?/?.*)$}o
1657             or return ( 0, "Bad ldap uri \"$s\"" );
1658             }
1659             return 1;
1660             },
1661             },
1662             ldapPwdEnc => {
1663             test => qr/^\w[\w\-]*\w$/,
1664             msgFail => 'Bad encoding',
1665             },
1666             ldapUsePasswordResetAttribute => $boolean,
1667             ldapPasswordResetAttribute => $testNotDefined,
1668             ldapPasswordResetAttributeValue => $testNotDefined,
1669             ldapPpolicyControl => $boolean,
1670             ldapSetPassword => $boolean,
1671             ldapChangePasswordAsUser => $boolean,
1672             mailLDAPFilter => $testNotDefined,
1673             LDAPFilter => $testNotDefined,
1674             AuthLDAPFilter => $testNotDefined,
1675             ldapGroupRecursive => $boolean,
1676             ldapGroupObjectClass => $testNotDefined,
1677             ldapGroupBase => $testNotDefined,
1678             ldapGroupAttributeName => $testNotDefined,
1679             ldapGroupAttributeNameUser => $testNotDefined,
1680             ldapGroupAttributeNameSearch => $testNotDefined,
1681             ldapGroupAttributeNameGroup => $testNotDefined,
1682             ldapTimeout => $testNotDefined,
1683             ldapVersion => $testNotDefined,
1684             ldapRaw => $testNotDefined,
1685             localSessionStorage => {
1686             test => qr/^[\w:]+$/,
1687             msgFail => 'Bad module name',
1688             },
1689             localSessionStorageOptions => {
1690             keyTest => qr/^\w+$/,
1691             keyMsgFail => 'Bad parameter',
1692             },
1693             locationRules => {
1694             keyTest => Lemonldap::NG::Common::Regexp::HOSTNAME(),
1695             msgFail => 'Bad virtual host name',
1696             '*' => {
1697             keyTest => $pcre,
1698             test => sub {
1699             my $e = shift;
1700             return 1 if ( $e =~ /^(?:accept|deny|unprotect|skip)$/i );
1701             if ( $e =~ s/^logout(?:_(?:app_sso|app|sso))?\s*// ) {
1702             return (
1703             $e eq ''
1704             or $e =~ Lemonldap::NG::Common::Regexp::HTTP_URI()
1705             ? 1
1706             : ( 0, "bad url \"$e\"" )
1707             );
1708             }
1709             return &$perlExpr($e);
1710             },
1711             warnTest => $noAssign,
1712             },
1713             },
1714             loginHistoryEnabled => $boolean,
1715             logoutServices => {
1716             keyTest => qr/^\w+$/,
1717             keyMsgFail => 'Bad name',
1718             },
1719             macros => {
1720             keyTest => qr/^[_a-zA-Z]\w*$/,
1721             keyMsgFail => 'Bad macro name',
1722             test => $perlExpr,
1723             warnTest => $noAssign,
1724             },
1725             mailOnPasswordChange => $boolean,
1726             maintenance => $boolean,
1727             managerDn => {
1728             test => qr/^(?:\w+=.*)?$/,
1729             msgFail => 'Bad LDAP dn',
1730             },
1731             managerPassword => {
1732             test => qr/^\S*$/,
1733             msgFail => 'Bad LDAP password',
1734             },
1735             notification => $boolean,
1736             notificationStorage => {
1737             test => qr/^[\w:]+$/,
1738             msgFail => 'Bad module name',
1739             },
1740             notificationStorageOptions => {
1741             keyTest => qr/^\w+$/,
1742             keyMsgFail => 'Bad parameter',
1743             },
1744             notifyDeleted => $boolean,
1745             notifyOther => $boolean,
1746             openIdExportedVars => {
1747             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1748             keyMsgFail => 'Bad variable name',
1749             test => qr/^[a-zA-Z][\w:\-]*$/,
1750             msgFail => 'Bad attribute name',
1751             },
1752             persistentStorageOptions => {
1753             keyTest => qr/^\w+$/,
1754             keyMsgFail => 'Bad parameter',
1755             },
1756             port => {
1757             test => qr/^\d*$/,
1758             msgFail => 'Bad port number'
1759             },
1760             portal => {
1761             test => qr/^https?:\/\/\S+$/,
1762             msgFail => 'Bad portal value',
1763             },
1764             portalAutocomplete => $boolean,
1765             portalCheckLogins => $boolean,
1766             portalDisplayLoginHistory => { test => $perlExpr, },
1767             portalDisplayAppslist => { test => $perlExpr, },
1768             portalDisplayChangePassword => { test => $perlExpr, },
1769             portalDisplayLogout => { test => $perlExpr, },
1770             portalDisplayRegister => $boolean,
1771             portalDisplayResetPassword => $boolean,
1772             portalForceAuthn => $boolean,
1773             portalOpenLinkInNewWindow => $boolean,
1774             portalAntiFrame => $boolean,
1775             portalParams => $testNotDefined,
1776             portalPingInterval => $integer,
1777             portalRequireOldPassword => $boolean,
1778             hideOldPassword => $boolean,
1779             portalSkin => {
1780             test => qr/\w+$/,
1781             msgFail => 'Bad skin name',
1782             },
1783             portalSkinRules => {
1784             keyTest => $perlExpr,
1785             keyMsgFail => 'Bad skin rule',
1786             test => qr/\w+$/,
1787             msgFail => 'Bad skin name',
1788             },
1789             portalUserAttr => {
1790             test => qr/\w+$/,
1791             msgFail => 'Unvalid session field',
1792             },
1793             post => {
1794             keyTest => Lemonldap::NG::Common::Regexp::HOSTNAME(),
1795             keyMsgFail => 'Bad virtual host name',
1796             '*' => { keyTest => $pcre, },
1797             },
1798             protection => {
1799             keyTest => qr/^(?:none|authentificate|manager|)$/,
1800             msgFail => 'must be one of none authentificate manager',
1801             },
1802             registerConfirmSubject => $testNotDefined,
1803             registerDB => $testNotDefined,
1804             registerDoneSubject => $testNotDefined,
1805             registerTimeout => $integer,
1806             registerUrl => $testNotDefined,
1807             reloadUrls => {
1808             keyTest => $domainNameOrIp,
1809             test => Lemonldap::NG::Common::Regexp::HTTP_URI(),
1810             msgFail => 'Bad url'
1811             },
1812             securedCookie => {
1813             test => qr/^(?:0|1|2|3)$/,
1814             msgFail => 'securedCookie must be 0, 1, 2 or 3',
1815             },
1816             sessionDataToRemember => {
1817             keyTest => qr/^[\w-]+$/,
1818             keyMsgFail => 'Invalid session data',
1819             },
1820             singleSession => $boolean,
1821             singleIP => $boolean,
1822             singleUserByIP => $boolean,
1823             slaveExportedVars => {
1824             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1825             keyMsgFail => 'Bad variable name',
1826             test => qr/^[a-zA-Z][\w:\-]*$/,
1827             msgFail => 'Bad attribute name',
1828             },
1829             slaveMasterIP => {
1830             test =>
1831             qr/^(\s*((\d{1,3}\.){3}\d{1,3}\s+)*(\d{1,3}\.){3}\d{1,3})?\s*$/,
1832             msgFail => 'Bad parameter "master\'s IP" in Slave',
1833             },
1834             Soap => $boolean,
1835             storePassword => $boolean,
1836             successLoginNumber => $integer,
1837             syslog => {
1838             test => qw/^(?:auth|authpriv|daemon|local\d|user)?$/,
1839             msgFail =>
1840             'Only auth|authpriv|daemon|local0-7|user is allowed here',
1841             },
1842             timeout => {
1843             test => qr/^\d*$/,
1844             msgFail => 'Bad number'
1845             },
1846             timeoutActivity => {
1847             test => qr/^\d*$/,
1848             msgFail => 'Bad number',
1849             },
1850             trustedProxies => $testNotDefined,
1851             userControl => {
1852             test => $pcre,
1853             msgFail => 'Bad regular expression',
1854             },
1855             userDB => {
1856             test => sub {
1857             my $e = shift;
1858              
1859             # Do not check syntax for Multi
1860             return 1 if ( $e =~ /^multi/i );
1861              
1862             # Else, check the user module is valid
1863             return ( $e =~ qr/^[a-zA-Z]+$/ );
1864             },
1865             msgFail => 'Bad module name',
1866             },
1867             useRedirectOnError => $boolean,
1868             useRedirectOnForbidden => $boolean,
1869             useSafeJail => $boolean,
1870             variables => $testNotDefined,
1871             vhostOptions => {
1872             keyTest => Lemonldap::NG::Common::Regexp::HOSTNAME(),
1873             keyMsgFail => 'Bad virtual host name',
1874             '*' => {
1875             keyTest => qr/^vhost(Port|Https|Maintenance|Aliases)$/,
1876             keyMsgFail => 'Bad option name',
1877             },
1878             },
1879             webIDExportedVars => {
1880             keyTest => qr/^!?[a-zA-Z][\w-]*$/,
1881             keyMsgFail => 'Bad variable name',
1882             test => qr/^[a-zA-Z][\w:\-]*$/,
1883             msgFail => 'Bad attribute name',
1884             },
1885             whatToTrace => $lmAttrOrMacro,
1886              
1887             ########
1888             # SAML #
1889             ########
1890             saml => $testNotDefined,
1891             samlServiceMetaData => $testNotDefined,
1892             samlIDPMetaDataExportedAttributes => {
1893             keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
1894             keyMsgFail => 'Bad metadata name',
1895             '*' => {
1896             keyTest => qr/^\w([\w\-]*\w)?$/,
1897             keyMsgFail => 'Bad attribute name',
1898             test => sub { return 1; },
1899             },
1900             },
1901             samlIDPMetaDataXML => {
1902             keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
1903             keyMsgFail => 'Bad metadata name',
1904             '*' => {
1905             test => sub { return 1; },
1906             keyTest => sub { return 1; },
1907             },
1908             },
1909             samlIDPMetaDataOptions => {
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             samlSPMetaDataExportedAttributes => {
1918             keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
1919             keyMsgFail => 'Bad metadata name',
1920             '*' => {
1921             keyTest => qr/^\w([\w\-]*\w)?$/,
1922             keyMsgFail => 'Bad attribute name',
1923             test => sub { return 1; },
1924             },
1925             },
1926             samlSPMetaDataXML => {
1927             keyTest => qr/^[a-zA-Z](?:[\w\-\.]*\w)?$/,
1928             keyMsgFail => 'Bad metadata name',
1929             '*' => {
1930             test => sub { return 1; },
1931             keyTest => sub { return 1; },
1932             },
1933             },
1934             samlSPMetaDataOptions => {
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             samlEntityID => $testNotDefined,
1943             samlOrganizationDisplayName => $testNotDefined,
1944             samlOrganizationName => $testNotDefined,
1945             samlOrganizationURL => $testNotDefined,
1946             samlSPSSODescriptorAuthnRequestsSigned => $boolean,
1947             samlSPSSODescriptorWantAssertionsSigned => $boolean,
1948             samlSPSSODescriptorSingleLogoutServiceHTTPRedirect => $testNotDefined,
1949             samlSPSSODescriptorSingleLogoutServiceHTTPPost => $testNotDefined,
1950             samlSPSSODescriptorSingleLogoutServiceSOAP => $testNotDefined,
1951             samlSPSSODescriptorAssertionConsumerServiceHTTPArtifact =>
1952             $testNotDefined,
1953             samlSPSSODescriptorAssertionConsumerServiceHTTPPost => $testNotDefined,
1954             samlSPSSODescriptorArtifactResolutionServiceArtifact => $testNotDefined,
1955             samlIDPSSODescriptorWantAuthnRequestsSigned => $boolean,
1956             samlIDPSSODescriptorSingleSignOnServiceHTTPRedirect => $testNotDefined,
1957             samlIDPSSODescriptorSingleSignOnServiceHTTPPost => $testNotDefined,
1958             samlIDPSSODescriptorSingleSignOnServiceHTTPArtifact => $testNotDefined,
1959             samlIDPSSODescriptorSingleSignOnServiceSOAP => $testNotDefined,
1960             samlIDPSSODescriptorSingleLogoutServiceHTTPRedirect => $testNotDefined,
1961             samlIDPSSODescriptorSingleLogoutServiceHTTPPost => $testNotDefined,
1962             samlIDPSSODescriptorSingleLogoutServiceSOAP => $testNotDefined,
1963             samlIDPSSODescriptorArtifactResolutionServiceArtifact =>
1964             $testNotDefined,
1965             samlNameIDFormatMapEmail => $testNotDefined,
1966             samlNameIDFormatMapX509 => $testNotDefined,
1967             samlNameIDFormatMapWindows => $testNotDefined,
1968             samlNameIDFormatMapKerberos => $testNotDefined,
1969             samlAttributeAuthorityDescriptorAttributeServiceSOAP => $testNotDefined,
1970             samlServicePrivateKeySig => $testNotDefined,
1971             samlServicePrivateKeySigPwd => $testNotDefined,
1972             samlServicePublicKeySig => $testNotDefined,
1973             samlServicePrivateKeyEnc => $testNotDefined,
1974             samlServicePrivateKeyEncPwd => $testNotDefined,
1975             samlServicePublicKeyEnc => $testNotDefined,
1976             samlIdPResolveCookie => $testNotDefined,
1977             samlMetadataForceUTF8 => $boolean,
1978             samlStorage => {
1979             test => qr/^[\w:]*$/,
1980             msgFail => 'Bad module name',
1981             },
1982             samlStorageOptions => {
1983             keyTest => qr/^\w+$/,
1984             keyMsgFail => 'Bad parameter',
1985             },
1986             samlAuthnContextMapPassword => $integer,
1987             samlAuthnContextMapPasswordProtectedTransport => $integer,
1988             samlAuthnContextMapTLSClient => $integer,
1989             samlAuthnContextMapKerberos => $integer,
1990             samlCommonDomainCookieActivation => $boolean,
1991             samlCommonDomainCookieDomain => {
1992             test => Lemonldap::NG::Common::Regexp::HOSTNAME(),
1993             msgFail => 'Bad domain',
1994             },
1995             samlCommonDomainCookieReader => {
1996             test => Lemonldap::NG::Common::Regexp::HTTP_URI(),
1997             msgFail => 'Bad URI',
1998             },
1999             samlCommonDomainCookieWriter => {
2000             test => Lemonldap::NG::Common::Regexp::HTTP_URI(),
2001             msgFail => 'Bad URI',
2002             },
2003             samlRelayStateTimeout => $integer,
2004             samlUseQueryStringSpecific => $boolean,
2005              
2006             # SSL
2007             SSLAuthnLevel => $integer,
2008             SSLVar => $testNotDefined,
2009              
2010             # CAS
2011             CAS_authnLevel => $integer,
2012             CAS_url => {
2013             test => Lemonldap::NG::Common::Regexp::HTTP_URI(),
2014             msgFail => 'Bad CAS url',
2015             },
2016             CAS_CAFile => $testNotDefined,
2017             CAS_renew => $boolean,
2018             CAS_gateway => $boolean,
2019             CAS_pgtFile => $testNotDefined,
2020             CAS_proxiedServices => {
2021             keyTest => qr/^\w+$/,
2022             keyMsgFail => 'Bad CAS proxied service identifier',
2023             },
2024             casAttr => $testNotDefined,
2025             casAccessControlPolicy => $testNotDefined,
2026             casStorage => {
2027             test => qr/^[\w:]*$/,
2028             msgFail => 'Bad module name',
2029             },
2030             casStorageOptions => {
2031             keyTest => qr/^\w+$/,
2032             keyMsgFail => 'Bad parameter',
2033             },
2034              
2035             # Radius
2036             radiusAuthnLevel => $integer,
2037             radiusSecret => $testNotDefined,
2038             radiusServer => $testNotDefined,
2039              
2040             # Remote
2041             remotePortal => $testNotDefined,
2042             remoteGlobalStorage => {
2043             test => qr/^[\w:]+$/,
2044             msgFail => 'Bad module name',
2045             },
2046             remoteGlobalStorageOptions => {
2047             keyTest => qr/^\w+$/,
2048             keyMsgFail => 'Bad parameter',
2049             },
2050              
2051             # Proxy
2052             soapAuthService => $testNotDefined,
2053             remoteCookieName => $testNotDefined,
2054             soapSessionService => $testNotDefined,
2055              
2056             # OpenID
2057             openIdAuthnLevel => $integer,
2058             openIdSecret => $testNotDefined,
2059              
2060             # Google
2061             googleAuthnLevel => $integer,
2062              
2063             # Facebook
2064             facebookAuthnLevel => $integer,
2065             facebookAppId => $testNotDefined,
2066             facebookAppSecret => $testNotDefined,
2067              
2068             # Twitter
2069             twitterAuthnLevel => $integer,
2070             twitterKey => $testNotDefined,
2071             twitterSecret => $testNotDefined,
2072             twitterAppName => $testNotDefined,
2073              
2074             # WebID
2075             webIDAuthnLevel => $integer,
2076             webIDWhitelist => $testNotDefined,
2077              
2078             # DBI
2079             dbiAuthnLevel => $integer,
2080             dbiAuthChain => $testNotDefined,
2081             dbiAuthUser => $testNotDefined,
2082             dbiAuthPassword => $testNotDefined,
2083             dbiUserChain => $testNotDefined,
2084             dbiUserUser => $testNotDefined,
2085             dbiUserPassword => $testNotDefined,
2086             dbiAuthTable => $testNotDefined,
2087             dbiUserTable => $testNotDefined,
2088             dbiAuthLoginCol => $testNotDefined,
2089             dbiAuthPasswordCol => $testNotDefined,
2090             dbiPasswordMailCol => $testNotDefined,
2091             userPivot => $testNotDefined,
2092             dbiAuthPasswordHash => $testNotDefined,
2093              
2094             # Apache
2095             apacheAuthnLevel => $integer,
2096              
2097             # Null
2098             nullAuthnLevel => $integer,
2099              
2100             # Slave
2101             slaveAuthnLevel => $integer,
2102             slaveUserHeader => $testNotDefined,
2103              
2104             # Choice
2105             authChoiceParams => $testNotDefined,
2106             authChoiceModules => {
2107             keyTest => qr/^(\d*)?\w+$/,
2108             keyMsgFail => 'Bad choice key',
2109             },
2110              
2111             # Zimbra
2112             zimbraPreAuthKey => $testNotDefined,
2113             zimbraAccountKey => $testNotDefined,
2114             zimbraBy => $testNotDefined,
2115             zimbraUrl => $testNotDefined,
2116             zimbraSsoUrl => $testNotDefined,
2117              
2118             # Sympa
2119             sympaSecret => $testNotDefined,
2120             sympaMailKey => $testNotDefined,
2121              
2122             # OpenID Issuer
2123             openIdIssuerSecret => $testNotDefined,
2124             openIdAttr => $testNotDefined,
2125             openIdSreg_fullname => $lmAttrOrMacro,
2126             openIdSreg_nickname => $lmAttrOrMacro,
2127             openIdSreg_language => $lmAttrOrMacro,
2128             openIdSreg_postcode => $lmAttrOrMacro,
2129             openIdSreg_timezone => $lmAttrOrMacro,
2130             openIdSreg_country => $lmAttrOrMacro,
2131             openIdSreg_gender => $lmAttrOrMacro,
2132             openIdSreg_email => $lmAttrOrMacro,
2133             openIdSreg_dob => $lmAttrOrMacro,
2134              
2135             # Yubikey
2136             yubikeyAuthnLevel => $integer,
2137             yubikeyClientID => $testNotDefined,
2138             yubikeySecretKey => $testNotDefined,
2139             yubikeyPublicIDSize => $integer,
2140              
2141             # Secure Token
2142             secureTokenMemcachedServers => $testNotDefined,
2143             secureTokenExpiration => $integer,
2144             secureTokenAttribute => $testNotDefined,
2145             secureTokenUrls => $testNotDefined,
2146             secureTokenHeader => $testNotDefined,
2147             secureTokenAllowOnError => $boolean,
2148              
2149             # BrowserID
2150             browserIdAuthnLevel => $integer,
2151             browserIdAutoLogin => $boolean,
2152             browserIdVerificationURL => $testNotDefined,
2153             browserIdSiteName => $testNotDefined,
2154             browserIdSiteLogo => $testNotDefined,
2155             browserIdBackgroundColor => $testNotDefined,
2156             };
2157             }
2158             ## @method hashref subDefaultConf()
2159             # Return the default values of subattributes
2160             # @return hash ref { subattribute name => default value }
2161             sub subDefaultConf {
2162             my ($self) = splice @_;
2163             my $h;
2164              
2165             my $confSubAttributes = Lemonldap::NG::Common::Conf::SubAttributes->new();
2166             my @attributes = $confSubAttributes->meta()->get_attribute_list();
2167              
2168             foreach my $name (@attributes) {
2169             $h->{$name} = $confSubAttributes->$name;
2170             }
2171              
2172             return $h;
2173             }
2174              
2175             ## @method hashref globalTests(hashref conf)
2176             # Return a hash ref where keys are the names of the tests and values
2177             # subroutines to execute.
2178             #
2179             # Subroutines can return one of the followings :
2180             # - (1) : everything is OK
2181             # - (1,message) : OK with a warning
2182             # - (0,message) : NOK
2183             # - (-1,message) : OK, but must be confirmed (ignored if confirm parameter is
2184             # set
2185             #
2186             # Those subroutines can also modify configuration.
2187             #
2188             # @param $conf Configuration to test
2189             # @return hash ref where keys are the names of the tests and values
2190             sub globalTests {
2191             my ( $self, $conf ) = splice @_;
2192             return {
2193              
2194             # 1. CHECKS
2195              
2196             # Check if portal is in domain
2197             portalIsInDomain => sub {
2198             return (
2199             1,
2200             (
2201             index( $conf->{portal}, $conf->{domain} ) > 0
2202             ? ''
2203             : "Portal seems not to be in the domain $conf->{domain}"
2204             )
2205             );
2206             },
2207              
2208             # Check if virtual hosts are in the domain
2209             vhostInDomainOrCDA => sub {
2210             return 1 if ( $conf->{cda} );
2211             my @pb;
2212             foreach my $vh ( keys %{ $conf->{locationRules} } ) {
2213             push @pb, $vh unless ( index( $vh, $conf->{domain} ) >= 0 );
2214             }
2215             return (
2216             1,
2217             (
2218             @pb
2219             ? 'Virtual hosts '
2220             . join( ', ', @pb )
2221             . " are not in $conf->{domain} and cross-domain-authentication is not set"
2222             : undef
2223             )
2224             );
2225             },
2226              
2227             # Check if virtual host do not contain a port
2228             vhostWithPort => sub {
2229             my @pb;
2230             foreach my $vh ( keys %{ $conf->{locationRules} } ) {
2231             push @pb, $vh if ( $vh =~ /:/ );
2232             }
2233             if (@pb) {
2234             return ( 0,
2235             'Virtual hosts '
2236             . join( ', ', @pb )
2237             . " contain a port, this is not allowed" );
2238             }
2239             else { return 1; }
2240             },
2241              
2242             # Force vhost to be lowercase
2243             vhostUpperCase => sub {
2244             my @pb;
2245             foreach my $vh ( keys %{ $conf->{locationRules} } ) {
2246             push @pb, $vh if ( $vh ne lc $vh );
2247             }
2248             if (@pb) {
2249             return ( 0,
2250             'Virtual hosts '
2251             . join( ', ', @pb )
2252             . " must be in lower case" );
2253             }
2254             else { return 1; }
2255             },
2256              
2257             # Check if "userDB" and "authentication" are consistent
2258             authAndUserDBConsistency => sub {
2259             foreach my $type (qw(Facebook Google OpenID SAML WebID)) {
2260             return ( 0,
2261             "\"$type\" can not be used as user database without using \"$type\" for authentication"
2262             )
2263             if ( $conf->{userDB} =~ /$type/
2264             and $conf->{authentication} !~ /$type/ );
2265             }
2266             return 1;
2267             },
2268              
2269             # Check that OpenID macros exists
2270             checkAttrAndMacros => sub {
2271             my @tmp;
2272             foreach my $k ( keys %$conf ) {
2273             if ( $k =~
2274             /^(?:openIdSreg_(?:(?:(?:full|nick)nam|languag|postcod|timezon)e|country|gender|email|dob)|whatToTrace)$/
2275             )
2276             {
2277             my $v = $conf->{$k};
2278             $v =~ s/^$//;
2279             next if ( $v =~ /^_/ );
2280             push @tmp, $k
2281             unless (
2282             defined(
2283             $conf->{exportedVars}->{$v}
2284             or defined( $conf->{macros}->{$v} )
2285             )
2286             );
2287             }
2288             }
2289             return (
2290             1,
2291             (
2292             @tmp
2293             ? 'Values of parameter(s) "'
2294             . join( ', ', @tmp )
2295             . '" are not defined in exported attributes or macros'
2296             : ''
2297             )
2298             );
2299             },
2300              
2301             # Test that variables are exported if Google is used as UserDB
2302             checkUserDBGoogleAXParams => sub {
2303             my @tmp;
2304             if ( $conf->{userDB} =~ /^Google/ ) {
2305             while ( my ( $k, $v ) = each %{ $conf->{exportedVars} } ) {
2306             if ( $v !~ Lemonldap::NG::Common::Regexp::GOOGLEAXATTR() ) {
2307             push @tmp, $v;
2308             }
2309             }
2310             }
2311             return (
2312             1,
2313             (
2314             @tmp
2315             ? 'Values of parameter(s) "'
2316             . join( ', ', @tmp )
2317             . '" are not exported by Google'
2318             : ''
2319             )
2320             );
2321             },
2322              
2323             # Test that variables are exported if OpenID is used as UserDB
2324             checkUserDBOpenIDParams => sub {
2325             my @tmp;
2326             if ( $conf->{userDB} =~ /^OpenID/ ) {
2327             while ( my ( $k, $v ) = each %{ $conf->{exportedVars} } ) {
2328             if ( $v !~ Lemonldap::NG::Common::Regexp::OPENIDSREGATTR() )
2329             {
2330             push @tmp, $v;
2331             }
2332             }
2333             }
2334             return (
2335             1,
2336             (
2337             @tmp
2338             ? 'Values of parameter(s) "'
2339             . join( ', ', @tmp )
2340             . '" are not exported by OpenID SREG'
2341             : ''
2342             )
2343             );
2344             },
2345              
2346             # Try to use Apache::Session module
2347             testApacheSession => sub {
2348             my ( $id, %h );
2349             return 1
2350             if ( $Lemonldap::NG::Handler::_CGI::tsv->{globalStorage} eq
2351             $conf->{globalStorage}
2352             or $conf->{globalStorage} eq
2353             'Lemonldap::NG::Common::Apache::Session::SOAP' );
2354             eval "use $conf->{globalStorage}";
2355             return ( -1, "Unknown package $conf->{globalStorage}" ) if ($@);
2356             eval {
2357             tie %h, $conf->{globalStorage}, undef,
2358             $conf->{globalStorageOptions};
2359             };
2360             return ( -1, "Unable to create a session ($@)" )
2361             if ( $@ or not tied(%h) );
2362             eval {
2363             $h{a} = 1;
2364             $id = $h{_session_id} or return ( -1, 'No _session_id' );
2365             untie(%h);
2366             tie %h, $conf->{globalStorage}, $id,
2367             $conf->{globalStorageOptions};
2368             };
2369             return ( -1, "Unable to insert datas ($@)" ) if ($@);
2370             return ( -1, "Unable to recover data stored" )
2371             unless ( $h{a} == 1 );
2372             eval { tied(%h)->delete; };
2373             return ( -1, "Unable to delete session ($@)" ) if ($@);
2374             my $gc = $Lemonldap::NG::Handler::_CGI::tsv->{globalStorage};
2375             return ( -1,
2376             'All sessions may be lost and you must restart all your Apache servers'
2377             ) if ( $conf->{globalStorage} ne $gc );
2378             return 1;
2379             },
2380              
2381             # Warn if cookie name has changed
2382             cookieNameChanged => sub {
2383             return (
2384             1,
2385             (
2386             $Lemonldap::NG::Handler::_CGI::tsv->{cookieName} ne
2387             $conf->{cookieName}
2388             ? 'Cookie name has changed, you must restart all your Apache servers'
2389             : ()
2390             )
2391             );
2392             },
2393              
2394             # Warn if manager seems to be unprotected
2395             managerProtection => sub {
2396             return (
2397             1,
2398             (
2399             $conf->{cfgAuthor} eq 'anonymous'
2400             ? 'Your manager seems to be unprotected'
2401             : ''
2402             )
2403             );
2404             },
2405              
2406             # Test SMTP connection and authentication
2407             smtpConnectionAuthentication => sub {
2408              
2409             # Skip test if no SMTP configuration
2410             return 1 unless ( $conf->{SMTPServer} );
2411              
2412             # Use SMTP
2413             eval "use Net::SMTP";
2414             return ( 0, "Net::SMTP module is required to use SMTP server" )
2415             if ($@);
2416              
2417             # Create SMTP object
2418             my $smtp = Net::SMTP->new( $conf->{SMTPServer} );
2419             return ( 0,
2420             "SMTP connection to " . $conf->{SMTPServer} . " failed" )
2421             unless ($smtp);
2422              
2423             # Skip other tests if no authentication
2424             return 1
2425             unless ( $conf->{SMTPAuthUser} and $conf->{SMTPAuthPass} );
2426              
2427             # Try authentication
2428             return ( 0, "SMTP authentication failed" )
2429             unless $smtp->auth( $conf->{SMTPAuthUser},
2430             $conf->{SMTPAuthPass} );
2431              
2432             # Return
2433             return 1;
2434             },
2435              
2436             # 2. MODIFICATIONS
2437              
2438             # Remove unused and non-customized parameters
2439             compactModules => sub {
2440             foreach my $k ( keys %$conf ) {
2441              
2442             # No analysis for hash keys
2443             next if ( ref $conf->{$k} );
2444              
2445             # Check federation modules
2446             foreach my $type (qw(CAS OpenID SAML)) {
2447              
2448             # Check authChoice values
2449             my ( $authChoice, $userDBChoice ) = ( undef, undef );
2450             if ( $conf->{authentication} eq 'Choice'
2451             and defined $conf->{authChoiceModules} )
2452             {
2453             foreach ( keys %{ $conf->{authChoiceModules} } ) {
2454             my ( $auth, $userDB, $passwordDB ) =
2455             split( '|', $conf->{authChoiceModules}->{$_} );
2456             $authChoice = 1 if $auth =~ /$type/i;
2457             $userDBChoice = 1 if $userDB =~ /$type/i;
2458             }
2459             }
2460              
2461             if (
2462             (
2463             $k =~ /^$type/i
2464             and not( $conf->{"issuerDB${type}Activation"} )
2465             and not( $conf->{authentication} =~ /$type/i )
2466             and not( $conf->{userDB} =~ /$type/i )
2467             and not( defined $authChoice
2468             or defined $userDBChoice )
2469             )
2470             )
2471             {
2472             my $confAttributes =
2473             Lemonldap::NG::Common::Conf::Attributes->new();
2474             my $v = $confAttributes->$k;
2475             if ( defined($v) and $conf->{$k} eq $v ) {
2476             delete $conf->{$k};
2477             }
2478             }
2479             }
2480             return 1;
2481             }
2482             },
2483             };
2484             }
2485              
2486             1;
2487