Attributes.pm 121 KB
Newer Older
Christophe Maudoux's avatar
Christophe Maudoux committed
1
#  This file contains the description of all configuration parameters
2 3 4
# It may be included only by batch files, never in portal or handler chain
# for performances reasons

Xavier Guimard's avatar
Xavier Guimard committed
5
# DON'T FORGET TO RUN "make json" AFTER EACH CHANGE
6 7 8

package Lemonldap::NG::Manager::Build::Attributes;

Xavier Guimard's avatar
Xavier Guimard committed
9
our $VERSION = '2.0.2';
10 11 12 13
use strict;
use Regexp::Common qw/URI/;

my $perlExpr = sub {
14
    my ( $val, $conf ) = @_;
15
    my $s = '';
16
    Safe->new->reval("BEGIN { warnings->unimport; } $s $val");
17 18 19
    my $err = join( '',
        grep { $_ =~ /Undefined subroutine/ ? () : $_ } split( /\n/, $@ ) );
    return $err ? ( 1, "__badExpression__: $err" ) : (1);
20 21
};

Xavier Guimard's avatar
Xavier Guimard committed
22
my $url = $RE{URI}{HTTP}{ -scheme => "https?" };
Xavier Guimard's avatar
Xavier Guimard committed
23 24 25
$url =~ s/(?<=[^\\])\$/\\\$/g;
$url = qr/$url/;

26 27 28 29 30
sub types {
    return {

        # Simple text types
        text => {
31
            test    => sub { 1 },
32 33 34
            msgFail => '__malformedValue__',
        },
        password => {
35
            test    => sub { 1 },
36 37 38
            msgFail => '__malformedValue__',
        },
        longtext => {
39
            test => sub { 1 }
40 41 42
        },
        url => {
            form    => 'text',
Xavier Guimard's avatar
Xavier Guimard committed
43
            test    => $url,
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
            msgFail => '__badUrl__',
        },
        PerlModule => {
            form    => 'text',
            test    => qr/^[a-zA-Z][a-zA-Z0-9]*(?:::[a-zA-Z][a-zA-Z0-9]*)*$/,
            msgFail => '__badPerlPackageName__',
        },
        hostname => {
            form    => 'text',
            test    => qr/^(?:$Regexp::Common::URI::RFC2396::host)?$/,
            msgFail => '__badHostname__',
        },
        pcre => {
            form => 'text',
            test => sub {
59
                eval { qr/$_[0]/ };
60 61 62 63 64
                return $@ ? ( 0, "__badRegexp__: $@" ) : (1);
            },
        },
        lmAttrOrMacro => {
            form => 'text',
Xavier Guimard's avatar
Xavier Guimard committed
65 66
            test => sub {
                my ( $val, $conf ) = @_;
67
                return 1
68
                  if ( defined $conf->{macros}->{$val}
69
                    or $val eq '_timezone' );
70 71
                foreach ( keys %$conf ) {
                    return 1
72
                      if ( $_ =~ /exportedvars$/i
73
                        and defined $conf->{$_}->{$val} );
Xavier Guimard's avatar
Xavier Guimard committed
74
                }
75
                return ( 1, "__unknownAttrOrMacro__: $val" );
Xavier Guimard's avatar
Xavier Guimard committed
76
            },
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
        },

        # Other types
        int => {
            test    => qr/^\-?\d+$/,
            msgFail => '__notAnInteger__',
        },
        bool => {
            test    => qr/^[01]$/,
            msgFail => '__notABoolean__',
        },
        trool => {
            test    => qr/^(?:-1|0|1)$/,
            msgFail => '__authorizedValues__: -1, 0, 1',
        },
        boolOrExpr => {
            test    => $perlExpr,
            msgFail => '__notAValidPerlExpression__',
        },
Xavier Guimard's avatar
Xavier Guimard committed
96 97
        keyTextContainer => {
            test       => qr/./,
Xavier Guimard's avatar
Xavier Guimard committed
98
            msgFail    => '__emptyValueNotAllowed__',
Xavier Guimard's avatar
Xavier Guimard committed
99
            keyTest    => qr/^\w[\w\.\-]*$/,
Xavier Guimard's avatar
Xavier Guimard committed
100
            keyMsgFail => '__badKeyName__',
Xavier Guimard's avatar
Xavier Guimard committed
101 102 103
        },
        subContainer => {
            keyTest => qr/\w/,
104
            test    => sub { 1 },
Xavier Guimard's avatar
Xavier Guimard committed
105
        },
Xavier Guimard's avatar
Xavier Guimard committed
106 107
        select => {
            test => sub {
108
                my $test = grep ( { $_ eq $_[0] }
Xavier Guimard's avatar
Xavier Guimard committed
109
                    map ( { $_->{k} } @{ $_[2]->{select} } ) );
Xavier Guimard's avatar
Xavier Guimard committed
110
                return $test
111 112
                  ? 1
                  : ( 1, "Invalid value '$_[0]' for this select" );
Xavier Guimard's avatar
Xavier Guimard committed
113 114
            },
        },
115 116 117

        # Files type (long text)
        file => {
118
            test => sub { 1 }
119 120
        },
        RSAPublicKey => {
121
            test => sub {
122
                return (
123 124
                    $_[0] =~
/^(?:(?:\-+\s*BEGIN\s+PUBLIC\s+KEY\s*\-+\r?\n)?[a-zA-Z0-9\/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+PUBLIC\s+KEY\s*\-+)?[\r\n]*)?$/s
125
                    ? (1)
126 127
                    : ( 1, '__badPemEncoding__' )
                );
128
            },
129
        },
130
        'RSAPublicKeyOrCertificate' => {
131
            'test' => sub {
132
                return (
133 134
                    $_[0] =~
/^(?:(?:\-+\s*BEGIN\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+\r?\n)?[a-zA-Z0-9\/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:PUBLIC\s+KEY|CERTIFICATE)\s*\-+)?[\r\n]*)?$/s
135
                    ? (1)
136 137
                    : ( 1, '__badPemEncoding__' )
                );
138
            },
139
        },
140
        RSAPrivateKey => {
141
            test => sub {
142
                return (
143 144
                    $_[0] =~
/^(?:(?:\-+\s*BEGIN\s+(?:RSA\s+)?PRIVATE\s+KEY\s*\-+\r?\n)?(?:Proc-Type:.*\r?\nDEK-Info:.*\r?\n[\r\n]*)?[a-zA-Z0-9\/\+\r\n]+={0,2}(?:\r?\n\-+\s*END\s+(?:RSA\s+)PRIVATE\s+KEY\s*\-+)?[\r\n]*)?$/s
145
                    ? (1)
146 147
                    : ( 1, '__badPemEncoding__' )
                );
148
            },
149 150 151
        },

        authParamsText => {
152
            test => sub { 1 }
153 154
        },
        blackWhiteList => {
155
            test => sub { 1 }
156 157
        },
        catAndAppList => {
158
            test => sub { 1 }
159 160 161
        },
        keyText => {
            keyTest => qr/^[a-zA-Z0-9_]+$/,
Xavier Guimard's avatar
Xavier Guimard committed
162
            test    => qr/^.*$/,
163 164 165
            msgFail => '__badValue__',
        },
        menuApp => {
166
            test => sub { 1 }
167 168
        },
        menuCat => {
169
            test => sub { 1 }
170 171
        },
        oidcOPMetaDataNode => {
172
            test => sub { 1 }
173 174
        },
        oidcRPMetaDataNode => {
175
            test => sub { 1 }
176 177
        },
        oidcmetadatajson => {
178
            test => sub { 1 }
179 180
        },
        oidcmetadatajwks => {
181
            test => sub { 1 }
182 183
        },
        portalskin => {
184
            test => sub { 1 }
185 186
        },
        portalskinbackground => {
187
            test => sub { 1 }
188 189
        },
        post => {
190
            test => sub { 1 }
191 192
        },
        rule => {
193
            test => sub { 1 }
194 195
        },
        samlAssertion => {
196
            test => sub { 1 }
197 198
        },
        samlAttribute => {
199
            test => sub { 1 }
200 201
        },
        samlIDPMetaDataNode => {
202
            test => sub { 1 }
203 204
        },
        samlSPMetaDataNode => {
205
            test => sub { 1 }
206 207
        },
        samlService => {
208
            test => sub { 1 }
209
        },
210
        array => {
211
            test => sub { 1 }
212
        },
213 214 215 216 217 218 219
    };
}

sub attributes {
    return {

        # Other
220 221 222
        checkTime => {
            type => 'int',
            documentation =>
223
              'Timeout to check new configuration in local cache',
224
            default => 600,
225 226 227 228 229 230
            flags   => 'hp',
        },
        mySessionAuthorizedRWKeys => {
            type          => 'array',
            documentation => 'Alterable session keys by user itself',
            default =>
231
              [ '_appsListOrder', '_oidcConnectedRP', '_oidcConsents' ],
232
        },
Xavier Guimard's avatar
Xavier Guimard committed
233 234 235 236 237 238 239 240 241 242 243 244
        configStorage => {
            type          => 'text',
            documentation => 'Configuration storage',
            flags         => 'hmp',
        },
        localStorage => {
            type          => 'text',
            documentation => 'Local cache',
            flags         => 'hmp',
        },
        localStorageOptions => {
            type          => 'keyTextContainer',
Xavier Guimard's avatar
Xavier Guimard committed
245
            documentation => 'Local cache parameters',
Xavier Guimard's avatar
Xavier Guimard committed
246 247
            flags         => 'hmp',
        },
248 249 250 251 252 253
        cfgNum => {
            type          => 'int',
            default       => 0,
            documentation => 'Enable Cross Domain Authentication',
        },
        cfgAuthor => {
254 255
            type          => 'text',
            documentation => 'Name of the author of the current configuration',
256 257
        },
        cfgAuthorIP => {
258 259
            type          => 'text',
            documentation => 'Uploader IP address of the current configuration',
260 261 262 263 264 265 266 267 268
        },
        cfgDate => {
            type          => 'int',
            documentation => 'Timestamp of the current configuration',
        },
        cfgLog => {
            type          => 'longtext',
            documentation => 'Configuration update log',
        },
269 270 271 272
        cfgVersion => {
            type          => 'text',
            documentation => 'Version of LLNG which build configuration',
        },
Xavier Guimard's avatar
Xavier Guimard committed
273 274 275 276 277
        status => {
            type          => 'bool',
            documentation => 'Status daemon activation',
            flags         => 'h',
        },
278 279 280
        confirmFormMethod => {
            type => "select",
            select =>
281
              [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ],
282 283 284
            default       => 'post',
            documentation => 'HTTP method for confirm page form',
        },
285 286
        customFunctions => {
            type          => 'text',
287
            test          => qr/^(?:\w+(?:::\w+)*(?:\s+\w+(?:::\w+)*)*)?$/,
288
            help          => 'customfunctions.html',
289
            msgFail       => "__badCustomFuncName__",
Xavier Guimard's avatar
Xavier Guimard committed
290 291
            documentation => 'List of custom functions',
            flags         => 'hmp',
292 293
        },
        https => {
294 295
            default       => -1,
            type          => 'trool',
296
            documentation => 'Use HTTPS for redirection from portal',
Xavier Guimard's avatar
Xavier Guimard committed
297
            flags         => 'h',
298 299 300 301
        },
        infoFormMethod => {
            type => "select",
            select =>
302
              [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ],
303 304 305
            default       => 'get',
            documentation => 'HTTP method for info page form',
        },
Xavier Guimard's avatar
Xavier Guimard committed
306
        port => {
307
            default       => -1,
Xavier Guimard's avatar
Xavier Guimard committed
308 309 310 311
            type          => 'int',
            documentation => 'Force port in redirection',
            flags         => 'h',
        },
312 313 314 315 316 317
        jsRedirect => {
            type          => 'boolOrExpr',
            default       => 0,
            documentation => 'Use javascript for redirections',
        },
        logoutServices => {
318 319 320 321
            type          => 'keyTextContainer',
            help          => 'logoutforward.html',
            default       => {},
            documentation => 'Send logout trough GET request to these services',
322 323 324 325 326
        },
        maintenance => {
            default       => 0,
            type          => 'bool',
            documentation => 'Maintenance mode for all virtual hosts',
Xavier Guimard's avatar
Xavier Guimard committed
327
            flags         => 'h',
328
        },
Xavier Guimard's avatar
Xavier Guimard committed
329 330 331 332
        nginxCustomHandlers => {
            type    => 'keyTextContainer',
            keyTest => qr/^\w+$/,
            test    => qr/^[a-zA-Z][a-zA-Z0-9]*(?:::[a-zA-Z][a-zA-Z0-9]*)*$/,
333
            help    => 'handlerarch.html',
Xavier Guimard's avatar
Xavier Guimard committed
334
            msgFail => '__badPerlPackageName__',
Xavier Guimard's avatar
Xavier Guimard committed
335
            documentation => 'Custom Nginx handler (deprecated)',
Xavier Guimard's avatar
Xavier Guimard committed
336
        },
337 338 339 340 341
        noAjaxHook => {
            default       => 0,
            type          => 'bool',
            documentation => 'Avoid replacing 302 by 401 for Ajax responses',
        },
342 343 344 345
        portal => {
            type          => 'url',
            default       => 'http://auth.example.com/',
            documentation => 'Portal URL',
Xavier Guimard's avatar
Xavier Guimard committed
346
            flags         => 'hmp',
347 348
            test          => $url,
            msgFail       => '__badUrl__',
349
        },
350 351 352
        portalStatus => {
            type          => 'bool',
            default       => 0,
Xavier Guimard's avatar
Typo  
Xavier Guimard committed
353
            help          => 'status.html',
354 355
            documentation => 'Enable portal status',
        },
356 357 358 359
        portalUserAttr => {
            type    => 'text',
            default => '_user',
            documentation =>
360
              'Session parameter to display connected user in portal',
361 362 363 364
        },
        redirectFormMethod => {
            type => "select",
            select =>
365
              [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ],
366 367 368
            default       => 'get',
            documentation => 'HTTP method for redirect page form',
        },
369 370 371 372 373 374
        reloadTimeout => {
            type          => 'int',
            default       => 5,
            documentation => 'Configuration reload timeout',
            flags         => 'm',
        },
375
        reloadUrls => {
376 377 378 379 380
            type          => 'keyTextContainer',
            help          => 'configlocation.html#configuration_reload',
            keyTest       => qr/^$Regexp::Common::URI::RFC2396::host(?::\d+)?$/,
            test          => $url,
            msgFail       => '__badUrl__',
Xavier Guimard's avatar
Xavier Guimard committed
381
            documentation => 'URL to call on reload',
382
        },
Clément OUDOT's avatar
Clément OUDOT committed
383
        portalMainLogo => {
384 385 386 387
            type          => 'text',
            default       => 'common/logos/logo_llng_400px.png',
            documentation => 'Portal main logo path',
        },
388 389 390 391 392
        showLanguages => {
            type          => 'bool',
            default       => 1,
            documentation => 'Display langs icons',
        },
393 394 395 396
        staticPrefix => {
            type          => 'text',
            documentation => 'Prefix of static files for HTML templates',
        },
397 398 399 400
        multiValuesSeparator => {
            type          => 'authParamsText',
            default       => '; ',
            documentation => 'Separator for multiple values',
Xavier Guimard's avatar
Xavier Guimard committed
401
            flags         => 'hmp',
402
        },
Xavier Guimard's avatar
Xavier Guimard committed
403
        stayConnected => {
Xavier Guimard's avatar
Typo  
Xavier Guimard committed
404 405
            type => 'bool',

406
            #help          => 'stayconnected.html',
407
            default       => 0,
Xavier Guimard's avatar
Xavier Guimard committed
408 409
            documentation => 'Enable StayConnected plugin',
        },
410
        checkState => {
411
            type          => 'bool',
412
            default       => 0,
413 414
            documentation => 'Enable CheckState plugin',
        },
415
        checkStateSecret => {
416
            type          => 'text',
417 418
            documentation => 'Secret token for CheckState plugin',
        },
419 420 421 422 423 424
        checkUser => {
            default       => 0,
            type          => 'bool',
            documentation => 'Enable check user',
            flags         => 'p',
        },
425 426 427 428 429 430
        checkUserIdRule => {
            type          => 'text',
            test          => $perlExpr,
            default       => 1,
            documentation => 'checkUser identities rule',
        },
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448
        checkUserHiddenAttributes => {
            type          => 'text',
            default       => '_2fDevices _loginHistory hGroups',
            documentation => 'Attributes to hide in CheckUser plugin',
            flags         => 'p',
        },
        checkUserDisplayPersistentInfo => {
            default       => 0,
            type          => 'bool',
            documentation => 'Display persistent session info',
            flags         => 'p',
        },
        checkUserDisplayEmptyValues => {
            default       => 0,
            type          => 'bool',
            documentation => 'Display session empty values',
            flags         => 'p',
        },
449
        impersonationMergeSSOgroups => {
450
            default       => 0,
451
            type          => 'bool',
Christophe Maudoux's avatar
Christophe Maudoux committed
452
            documentation => 'Merge spoofed and real SSO groups',
453 454
            flags         => 'p',
        },
455
        impersonationPrefix => {
456 457 458 459 460
            type          => 'text',
            default       => 'real_',
            documentation => 'Prefix to rename real session attributes',
            flags         => 'p',
        },
461
        impersonationRule => {
462
            type          => 'boolOrExpr',
463
            default       => 0,
464
            documentation => 'Impersonation activation rule',
465
        },
466 467 468 469
        impersonationIdRule => {
            type          => 'text',
            test          => $perlExpr,
            default       => 1,
470
            documentation => 'Impersonation identities rule',
471
        },
472
        impersonationHiddenAttributes => {
473 474 475 476 477
            type          => 'text',
            default       => '_2fDevices _loginHistory',
            documentation => 'Attributes to skip',
            flags         => 'p',
        },
478
        impersonationSkipEmptyValues => {
479 480 481
            default       => 1,
            type          => 'bool',
            documentation => 'Skip session empty values',
482 483
            flags         => 'p',
        },
484
        skipRenewConfirmation => {
485 486
            type    => 'bool',
            default => 0,
487
            documentation =>
488
              'Avoid asking confirmation when an Issuer asks to renew auth',
489
        },
490 491 492 493
        handlerInternalCache => {
            type          => 'int',
            default       => 15,
            documentation => 'Handler internal cache timeout',
Christophe Maudoux's avatar
Christophe Maudoux committed
494
            flags         => 'hp',
495
        },
496

497 498 499 500 501 502 503 504 505
        # Loggers (ini only)
        logLevel => {
            type          => 'text',
            documentation => 'Log level, must be set in .ini',
            flags         => 'hmp',
        },
        logger => {
            type          => 'text',
            documentation => 'technical logger',
Xavier Guimard's avatar
Xavier Guimard committed
506
            flags         => 'hmp',
507 508 509 510
        },
        userLogger => {
            type          => 'text',
            documentation => 'User actions logger',
Xavier Guimard's avatar
Xavier Guimard committed
511
            flags         => 'hmp',
512 513 514 515
        },
        log4perlConfFile => {
            type          => 'text',
            documentation => 'Log4Perl logger configuration file',
Xavier Guimard's avatar
Xavier Guimard committed
516
            flags         => 'hmp',
517 518 519 520
        },
        sentryDsn => {
            type          => 'text',
            documentation => 'Sentry logger DSN',
Xavier Guimard's avatar
Xavier Guimard committed
521
            flags         => 'hmp',
522 523 524 525
        },
        syslogFacility => {
            type          => 'text',
            documentation => 'Syslog logger technical facility',
Xavier Guimard's avatar
Xavier Guimard committed
526
            flags         => 'hmp',
527 528 529 530
        },
        userSyslogFacility => {
            type          => 'text',
            documentation => 'Syslog logger user-actions facility',
Xavier Guimard's avatar
Xavier Guimard committed
531
            flags         => 'hmp',
532 533 534
        },

        # Manager or PSGI protected apps
535
        protection => {
536 537 538
            type          => 'text',
            test          => qr/^(?:none|authenticate|manager|)$/,
            msgFail       => '__authorizedValues__: none authenticate manager',
539
            documentation => 'Manager protection method',
Xavier Guimard's avatar
Xavier Guimard committed
540
            flags         => 'hm',
541 542 543 544 545 546 547 548 549 550
        },

        # Menu
        activeTimer => {
            type          => 'bool',
            default       => 1,
            documentation => 'Enable timers on portal pages',
        },
        applicationList => {
            type    => 'catAndAppList',
551
            keyTest => qr/\w/,
552 553
            help    => 'portalmenu.html#categories_and_applications',
            default => {
554
                default => { catname => 'Default category', type => "category" }
555 556 557
            },
            documentation => 'Applications list',
        },
558 559 560 561 562
        portalErrorOnExpiredSession => {
            type          => 'bool',
            default       => 1,
            documentation => 'Show error if session is expired',
        },
563
        portalErrorOnMailNotFound => {
dcoutadeur dcoutadeur's avatar
dcoutadeur dcoutadeur committed
564 565 566
            type    => 'bool',
            default => 0,
            documentation =>
567
              'Show error if mail is not found in password reset process',
568
        },
569 570 571 572 573 574 575 576 577 578 579 580 581 582
        portalOpenLinkInNewWindow => {
            type          => 'bool',
            default       => 0,
            documentation => 'Open applications in new windows',
        },
        portalPingInterval => {
            type          => 'int',
            default       => 60000,
            documentation => 'Interval in ms between portal Ajax pings ',
        },
        portalSkin => {
            type          => 'portalskin',
            default       => 'bootstrap',
            documentation => 'Name of portal skin',
Xavier Guimard's avatar
Xavier Guimard committed
583
            select        => [ { k => 'bootstrap', v => 'Bootstrap' }, ],
584 585 586 587 588 589
        },
        portalSkinBackground => {
            type          => 'portalskinbackground',
            documentation => 'Background image of portal skin',
            select        => [
                { k => "", v => 'None' },
590 591
                {
                    k => "1280px-Anse_Source_d'Argent_2-La_Digue.jpg",
592 593
                    v => 'Anse'
                },
594 595 596
                {
                    k =>
"1280px-Autumn-clear-water-waterfall-landscape_-_Virginia_-_ForestWander.jpg",
597 598 599
                    v => 'Waterfall'
                },
                { k => "1280px-BrockenSnowedTrees.jpg", v => 'Snowed Trees' },
600 601
                {
                    k => "1280px-Cedar_Breaks_National_Monument_partially.jpg",
602 603
                    v => 'National Monument'
                },
604 605
                {
                    k => "1280px-Parry_Peak_from_Winter_Park.jpg",
606 607
                    v => 'Winter'
                },
608 609
                {
                    k => "Aletschgletscher_mit_Pinus_cembra1.jpg",
610 611
                    v => 'Pinus'
                },
612 613 614
            ],
        },
        portalSkinRules => {
Xavier Guimard's avatar
Xavier Guimard committed
615 616 617 618 619 620 621
            type          => 'keyTextContainer',
            help          => 'portalcustom.html',
            keyTest       => $perlExpr,
            keyMsgFail    => '__badSkinRule__',
            test          => qr/^\w+$/,
            msgFail       => '__badValue__',
            documentation => 'Rules to choose portal skin',
622 623 624
        },

        # Security
625
        formTimeout => {
Xavier Guimard's avatar
Xavier Guimard committed
626 627
            default       => 120,
            type          => 'int',
628 629 630
            documentation => 'Token timeout for forms',
        },
        requireToken => {
Xavier Guimard's avatar
Xavier Guimard committed
631 632
            default       => 1,
            type          => 'bool',
633 634
            documentation => 'Enable token for forms',
        },
635 636 637 638 639
        tokenUseGlobalStorage => {
            default       => 0,
            type          => 'bool',
            documentation => 'Enable global token storage',
        },
640 641 642 643
        cda => {
            default       => 0,
            type          => 'bool',
            documentation => 'Enable Cross Domain Authentication',
Xavier Guimard's avatar
Xavier Guimard committed
644
            flags         => 'hp',
645 646 647 648 649 650
        },
        checkXSS => {
            default       => 1,
            type          => 'bool',
            documentation => 'Check XSS',
        },
651
        portalForceAuthn => {
652
            default => 0,
653
            help    => 'forcereauthn.html',
654 655
            type    => 'bool',
            documentation =>
656
              'Enable force to authenticate when displaying portal',
657
        },
658 659
        portalForceAuthnInterval => {
            default => 5,
660 661
            type    => 'int',
            documentation =>
662
'Maximum interval in seconds since last authentication to force reauthentication',
663
        },
664
        bruteForceProtection => {
665
            default       => 0,
666
            help          => 'bruteforceprotection.html',
667 668 669 670 671 672 673
            type          => 'bool',
            documentation => 'Enable brute force attack protection',
        },
        bruteForceProtectionTempo => {
            default => 30,
            type    => 'int',
            documentation =>
674
              'Brute force attack protection -> Tempo before try again',
675 676 677 678 679
        },
        bruteForceProtectionMaxAge => {
            default => 300,
            type    => 'int',
            documentation =>
680
'Brute force attack protection -> Max age between last and first allowed failed login',
681 682 683 684 685
        },
        bruteForceProtectionMaxFailed => {
            default => 3,
            type    => 'int',
            documentation =>
686
              'Brute force attack protection -> Max allowed failed login',
687
        },
688
        grantSessionRules => {
Xavier Guimard's avatar
Xavier Guimard committed
689 690
            type          => 'grantContainer',
            keyTest       => $perlExpr,
691
            test          => sub { 1 },
Xavier Guimard's avatar
Xavier Guimard committed
692
            documentation => 'Rules to grant sessions',
693 694 695 696 697 698 699 700 701 702
        },
        hiddenAttributes => {
            type          => 'text',
            default       => '_password',
            documentation => 'Name of attributes to hide in logs',
        },
        key => {
            type          => 'password',
            documentation => 'Secret key',
        },
703 704
        cspDefault => {
            type          => 'text',
Xavier Guimard's avatar
Xavier Guimard committed
705
            default       => "'self'",
706 707
            documentation => 'Default value for Content-Security-Policy',
        },
708
        cspFormAction => {
709 710 711
            type    => 'text',
            default => "'self'",
            documentation =>
712
              'Form action destination for Content-Security-Policy',
713
        },
714 715
        cspImg => {
            type          => 'text',
716
            default       => "'self' data:",
717 718 719 720 721 722 723 724 725
            documentation => 'Image source for Content-Security-Policy',
        },
        cspScript => {
            type          => 'text',
            default       => "'self'",
            documentation => 'Javascript source for Content-Security-Policy',
        },
        cspStyle => {
            type          => 'text',
726
            default       => "'self'",
727 728 729 730 731 732
            documentation => 'Style source for Content-Security-Policy',
        },
        cspConnect => {
            type    => 'text',
            default => "'self'",
            documentation =>
733
              'Authorized Ajax destination for Content-Security-Policy',
734 735 736 737 738 739
        },
        cspFont => {
            type          => 'text',
            default       => "'self'",
            documentation => 'Font source for Content-Security-Policy',
        },
740 741 742 743 744 745 746 747 748 749 750 751 752 753 754
        portalAntiFrame => {
            default       => 1,
            type          => 'bool',
            documentation => 'Avoid portal to be displayed inside frames',
        },
        portalCheckLogins => {
            default       => 1,
            type          => 'bool',
            documentation => 'Display login history checkbox in portal',
        },
        randomPasswordRegexp => {
            type          => 'pcre',
            default       => '[A-Z]{3}[a-z]{5}.\d{2}',
            documentation => 'Regular expression to create a random password',
        },
Xavier Guimard's avatar
Xavier Guimard committed
755
        trustedDomains =>
756
          { type => 'text', documentation => 'Trusted domains', },
Xavier Guimard's avatar
Xavier Guimard committed
757
        storePassword => {
758 759 760 761 762 763
            default       => 0,
            type          => 'bool',
            documentation => 'Store password in session',
        },
        timeout => {
            type          => 'int',
Xavier Guimard's avatar
Xavier Guimard committed
764
            test          => sub { $_[0] > 0 },
765 766 767 768
            default       => 72000,
            documentation => 'Session timeout on server side',
        },
        timeoutActivity => {
769
            type          => 'int',
Xavier Guimard's avatar
Xavier Guimard committed
770
            test          => sub { $_[0] >= 0 },
771 772 773
            default       => 0,
            documentation => 'Session activity timeout on server side',
        },
774 775 776 777 778 779
        timeoutActivityInterval => {
            type          => 'int',
            test          => sub { $_[0] >= 0 },
            default       => 60,
            documentation => 'Update session timeout interval on server side',
        },
780 781
        userControl => {
            type          => 'pcre',
782
            default       => '^[\w\.\-@]+$',
783 784 785 786 787 788
            documentation => 'Regular expression to validate login',
        },
        useRedirectOnError => {
            type          => 'bool',
            default       => 1,
            documentation => 'Use 302 redirect code for error (500)',
Xavier Guimard's avatar
Xavier Guimard committed
789
            flags         => 'h',
790 791 792 793 794 795 796 797 798
        },
        useRedirectOnForbidden => {
            default       => 0,
            type          => 'bool',
            documentation => 'Use 302 redirect code for forbidden (403)',
        },
        useSafeJail => {
            default       => 1,
            type          => 'bool',
Xavier Guimard's avatar
Xavier Guimard committed
799
            help          => 'safejail.html',
800
            documentation => 'Activate Safe jail',
Xavier Guimard's avatar
Xavier Guimard committed
801
            flags         => 'hp',
802 803 804 805 806
        },
        whatToTrace => {
            type          => 'lmAttrOrMacro',
            default       => 'uid',
            documentation => 'Session parameter used to fill REMOTE_USER',
Xavier Guimard's avatar
Xavier Guimard committed
807
            flags         => 'hp',
808
        },
809
        lwpOpts => {
Xavier Guimard's avatar
Xavier Guimard committed
810 811 812
            type          => 'keyTextContainer',
            documentation => 'Options given to LWP::UserAgent',
        },
813 814 815 816
        lwpSslOpts => {
            type          => 'keyTextContainer',
            documentation => 'SSL options given to LWP::UserAgent',
        },
817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861

        # History
        failedLoginNumber => {
            default       => 5,
            type          => 'int',
            documentation => 'Number of failures stored in login history',
        },
        loginHistoryEnabled => {
            default       => 0,
            type          => 'bool',
            documentation => 'Enable login history',
        },
        portalDisplayLoginHistory => {
            type          => 'boolOrExpr',
            default       => 1,
            documentation => 'Display login history tab in portal',
        },
        successLoginNumber => {
            default       => 5,
            type          => 'int',
            documentation => 'Number of success stored in login history',
        },

        # Other displays
        portalDisplayAppslist => {
            type          => 'boolOrExpr',
            default       => 1,
            documentation => 'Display applications tab in portal',
        },
        portalDisplayChangePassword => {
            type          => 'boolOrExpr',
            default       => '$_auth =~ /^(LDAP|DBI|Demo)$/',
            documentation => 'Display password tab in portal',
        },
        portalDisplayLogout => {
            default       => 1,
            type          => 'boolOrExpr',
            documentation => 'Display logout tab in portal',
        },
        portalDisplayRegister => {
            default       => 1,
            type          => 'bool',
            documentation => 'Display register button in portal',
        },
        portalDisplayResetPassword => {
Xavier Guimard's avatar
Xavier Guimard committed
862
            default       => 0,
863 864 865
            type          => 'bool',
            documentation => 'Display reset password button in portal',
        },
866
        passwordResetAllowedRetries => {
Christophe Maudoux's avatar
Christophe Maudoux committed
867
            default       => 3,
868 869 870
            type          => 'int',
            documentation => 'Maximum number of retries to reset password',
        },
871 872
        portalDisplayOidcConsents => {
            type          => 'boolOrExpr',
873
            default       => '$_oidcConnectedRP',
874 875
            documentation => 'Display OIDC consent tab in portal',
        },
876 877

        # Cookies
Xavier Guimard's avatar
Xavier Guimard committed
878
        cookieExpiration => {
879
            type          => 'int',
Xavier Guimard's avatar
Xavier Guimard committed
880 881 882
            documentation => 'Cookie expiration',
            flags         => 'hp',
        },
Xavier Guimard's avatar
Xavier Guimard committed
883
        cookieName => {
884 885 886 887 888
            type          => 'text',
            test          => qr/^[a-zA-Z][a-zA-Z0-9_-]*$/,
            msgFail       => '__badCookieName__',
            default       => 'lemonldap',
            documentation => 'Name of the main cookie',
Xavier Guimard's avatar
Xavier Guimard committed
889
            flags         => 'hp',
890 891
        },
        domain => {
892 893 894 895
            type          => 'text',
            test          => qr/^(?:$Regexp::Common::URI::RFC2396::hostname)?$/,
            msgFail       => '__badDomainName__',
            default       => 'example.com',
896
            documentation => 'DNS domain',
Xavier Guimard's avatar
Xavier Guimard committed
897
            flags         => 'hp',
898 899 900 901 902
        },
        httpOnly => {
            default       => 1,
            type          => 'bool',
            documentation => 'Enable httpOnly flag in cookie',
Xavier Guimard's avatar
Xavier Guimard committed
903
            flags         => 'hp',
904 905 906 907 908 909 910 911 912 913 914
        },
        securedCookie => {
            type   => 'select',
            select => [
                { k => '0', v => 'unsecuredCookie' },
                { k => '1', v => 'securedCookie' },
                { k => '2', v => 'doubleCookie' },
                { k => '3', v => 'doubleCookieForSingleSession' },
            ],
            default       => 0,
            documentation => 'Cookie securisation method',
Xavier Guimard's avatar
Xavier Guimard committed
915
            flags         => 'hp',
916 917
        },

918 919 920
        # Viewer
        viewerHiddenPK => {
            type          => 'text',
Christophe Maudoux's avatar
Christophe Maudoux committed
921
            default       => 'samlIDPMetaDataNodes samlSPMetaDataNodes',
922 923 924
            documentation => 'ConfTree hidden primary keys',
            flags         => 'm',
        },
Christophe Maudoux's avatar
Christophe Maudoux committed
925
        viewerAllowBrowser => {
926 927 928
            type          => 'bool',
            default       => 0,
            documentation => 'Allow configuration browser',
929
        },
930

931
        # Notification
932
        oldNotifFormat => {
Xavier Guimard's avatar
Xavier Guimard committed
933 934
            type          => 'bool',
            default       => 0,
Xavier Guimard's avatar
Xavier Guimard committed
935
            documentation => 'Use old XML format for notifications',
936
        },
937 938 939 940 941
        notificationWildcard => {
            type          => 'text',
            default       => 'allusers',
            documentation => 'Notification string to match all users',
        },
Xavier Guimard's avatar
Xavier Guimard committed
942 943 944 945 946
        notificationXSLTfile => {
            type          => 'text',
            documentation => 'Custom XSLT document for notifications',
        },
        notification => {
947 948 949 950
            default       => 0,
            type          => 'bool',
            documentation => 'Notification activation',
        },
951 952 953 954 955
        notificationServer => {
            default       => 0,
            type          => 'bool',
            documentation => 'Notification server activation',
        },
956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973
        notificationStorage => {
            type          => 'PerlModule',
            default       => 'File',
            documentation => 'Notification backend',
        },
        notificationStorageOptions => {
            type    => 'keyTextContainer',
            default => { dirName => '/var/lib/lemonldap-ng/notifications', },
            documentation => 'Notification backend options',
        },

        # Captcha
        captcha_login_enabled => {
            default       => 0,
            type          => 'bool',
            documentation => 'Captcha on login page',
        },
        captcha_mail_enabled => {
974
            default       => 1,
975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993
            type          => 'bool',
            documentation => 'Captcha on password reset page',
        },
        captcha_register_enabled => {
            default       => 1,
            type          => 'bool',
            documentation => 'Captcha on account creation page',
        },
        captcha_size => {
            type          => 'int',
            default       => 6,
            documentation => 'Captcha size',
        },

        # Variables
        exportedVars => {
            type          => 'keyTextContainer',
            help          => 'exportedvars.html',
            keyTest       => qr/^!?[_a-zA-Z][a-zA-Z0-9_]*$/,
Xavier Guimard's avatar
Xavier Guimard committed
994
            keyMsgFail    => '__badVariableName__',
995 996 997 998 999 1000 1001 1002
            test          => qr/^[_a-zA-Z][a-zA-Z0-9_:\-]*$/,
            msgFail       => '__badValue__',
            default       => { 'UA' => 'HTTP_USER_AGENT' },
            documentation => 'Main exported variables',
        },
        groups => {
            type => 'keyTextContainer',
            help =>
1003
              'exportedvars.html#extend_variables_using_macros_and_groups',
1004 1005 1006 1007 1008 1009 1010
            test          => $perlExpr,
            default       => {},
            documentation => 'Groups',
        },
        macros => {
            type => 'keyTextContainer',
            help =>
1011
              'exportedvars.html#extend_variables_using_macros_and_groups',
1012
            keyTest       => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,