Attributes.pm 117 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

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

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

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

Christophe Maudoux's avatar
Christophe Maudoux committed
13

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

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

27 28 29 30 31
sub types {
    return {

        # Simple text types
        text => {
Clément OUDOT's avatar
Clément OUDOT committed
32
            test    => sub { 1 },
33 34 35
            msgFail => '__malformedValue__',
        },
        password => {
Clément OUDOT's avatar
Clément OUDOT committed
36
            test    => sub { 1 },
37 38 39
            msgFail => '__malformedValue__',
        },
        longtext => {
Clément OUDOT's avatar
Clément OUDOT committed
40
            test => sub { 1 }
41 42 43
        },
        url => {
            form    => 'text',
Yadd's avatar
Yadd committed
44
            test    => $url,
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
            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 {
Clément OUDOT's avatar
Clément OUDOT committed
60
                eval { qr/$_[0]/ };
61 62 63 64 65
                return $@ ? ( 0, "__badRegexp__: $@" ) : (1);
            },
        },
        lmAttrOrMacro => {
            form => 'text',
Yadd's avatar
Yadd committed
66 67
            test => sub {
                my ( $val, $conf ) = @_;
68
                return 1
Clément OUDOT's avatar
Clément OUDOT committed
69
                  if ( defined $conf->{macros}->{$val}
70
                    or $val eq '_timezone' );
71 72
                foreach ( keys %$conf ) {
                    return 1
Clément OUDOT's avatar
Clément OUDOT committed
73
                      if ( $_ =~ /exportedvars$/i
74
                        and defined $conf->{$_}->{$val} );
Yadd's avatar
Yadd committed
75
                }
76
                return ( 1, "__unknownAttrOrMacro__: $val" );
Yadd's avatar
Yadd committed
77
            },
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
        },

        # 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__',
        },
Yadd's avatar
Yadd committed
97 98
        keyTextContainer => {
            test       => qr/./,
Yadd's avatar
Yadd committed
99
            msgFail    => '__emptyValueNotAllowed__',
Yadd's avatar
Yadd committed
100
            keyTest    => qr/^\w[\w\.\-]*$/,
Yadd's avatar
Yadd committed
101
            keyMsgFail => '__badKeyName__',
Yadd's avatar
Yadd committed
102 103 104
        },
        subContainer => {
            keyTest => qr/\w/,
Clément OUDOT's avatar
Clément OUDOT committed
105
            test    => sub { 1 },
Yadd's avatar
Yadd committed
106
        },
Yadd's avatar
Yadd committed
107 108
        select => {
            test => sub {
109
                my $test = grep ( { $_ eq $_[0] }
Yadd's avatar
Yadd committed
110
                    map ( { $_->{k} } @{ $_[2]->{select} } ) );
Yadd's avatar
Yadd committed
111
                return $test
Clément OUDOT's avatar
Clément OUDOT committed
112 113
                  ? 1
                  : ( 1, "Invalid value '$_[0]' for this select" );
Yadd's avatar
Yadd committed
114 115
            },
        },
116 117 118

        # Files type (long text)
        file => {
Clément OUDOT's avatar
Clément OUDOT committed
119
            test => sub { 1 }
120 121
        },
        RSAPublicKey => {
122
            test => sub {
123
                return (
Clément OUDOT's avatar
Clément OUDOT committed
124 125
                    $_[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
126
                    ? (1)
127 128
                    : ( 1, '__badPemEncoding__' )
                );
129
            },
130
        },
131
        'RSAPublicKeyOrCertificate' => {
132
            'test' => sub {
133
                return (
Clément OUDOT's avatar
Clément OUDOT committed
134 135
                    $_[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
136
                    ? (1)
137 138
                    : ( 1, '__badPemEncoding__' )
                );
139
            },
140
        },
141
        RSAPrivateKey => {
142
            test => sub {
143
                return (
Clément OUDOT's avatar
Clément OUDOT committed
144 145
                    $_[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
146
                    ? (1)
147 148
                    : ( 1, '__badPemEncoding__' )
                );
149
            },
150 151 152
        },

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

sub attributes {
    return {

        # Other
Yadd's avatar
Yadd committed
221 222 223
        checkTime => {
            type => 'int',
            documentation =>
Clément OUDOT's avatar
Clément OUDOT committed
224
              'Timeout to check new configuration in local cache',
Yadd's avatar
Yadd committed
225
            default => 600,
226 227 228 229 230 231
            flags   => 'hp',
        },
        mySessionAuthorizedRWKeys => {
            type          => 'array',
            documentation => 'Alterable session keys by user itself',
            default =>
Clément OUDOT's avatar
Clément OUDOT committed
232
              [ '_appsListOrder', '_oidcConnectedRP', '_oidcConsents' ],
Yadd's avatar
Yadd committed
233
        },
Yadd's avatar
Yadd committed
234 235 236 237 238 239 240 241 242 243 244 245
        configStorage => {
            type          => 'text',
            documentation => 'Configuration storage',
            flags         => 'hmp',
        },
        localStorage => {
            type          => 'text',
            documentation => 'Local cache',
            flags         => 'hmp',
        },
        localStorageOptions => {
            type          => 'keyTextContainer',
Yadd's avatar
Yadd committed
246
            documentation => 'Local cache parameters',
Yadd's avatar
Yadd committed
247 248
            flags         => 'hmp',
        },
249 250 251 252 253 254
        cfgNum => {
            type          => 'int',
            default       => 0,
            documentation => 'Enable Cross Domain Authentication',
        },
        cfgAuthor => {
Clément OUDOT's avatar
Clément OUDOT committed
255 256
            type          => 'text',
            documentation => 'Name of the author of the current configuration',
257 258
        },
        cfgAuthorIP => {
Clément OUDOT's avatar
Clément OUDOT committed
259 260
            type          => 'text',
            documentation => 'Uploader IP address of the current configuration',
261 262 263 264 265 266 267 268 269
        },
        cfgDate => {
            type          => 'int',
            documentation => 'Timestamp of the current configuration',
        },
        cfgLog => {
            type          => 'longtext',
            documentation => 'Configuration update log',
        },
270 271 272 273
        cfgVersion => {
            type          => 'text',
            documentation => 'Version of LLNG which build configuration',
        },
Yadd's avatar
Yadd committed
274 275 276 277 278
        status => {
            type          => 'bool',
            documentation => 'Status daemon activation',
            flags         => 'h',
        },
279 280 281
        confirmFormMethod => {
            type => "select",
            select =>
Clément OUDOT's avatar
Clément OUDOT committed
282
              [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ],
283 284 285
            default       => 'post',
            documentation => 'HTTP method for confirm page form',
        },
286 287
        customFunctions => {
            type          => 'text',
Yadd's avatar
Yadd committed
288
            test          => qr/^(?:\w+(?:::\w+)*(?:\s+\w+(?:::\w+)*)*)?$/,
289
            help          => 'customfunctions.html',
290
            msgFail       => "__badCustomFuncName__",
Yadd's avatar
Yadd committed
291 292
            documentation => 'List of custom functions',
            flags         => 'hmp',
293 294
        },
        https => {
295 296 297
            default       => 0,
            type          => 'bool',
            documentation => 'Use HTTPS for redirection from portal',
Yadd's avatar
Yadd committed
298
            flags         => 'h',
299 300 301 302
        },
        infoFormMethod => {
            type => "select",
            select =>
Clément OUDOT's avatar
Clément OUDOT committed
303
              [ { k => 'get', v => 'GET' }, { k => 'post', v => 'POST' }, ],
304 305 306
            default       => 'get',
            documentation => 'HTTP method for info page form',
        },
Yadd's avatar
Yadd committed
307 308 309 310 311
        port => {
            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 => {
Clément OUDOT's avatar
Clément OUDOT committed
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',
Yadd's avatar
Yadd committed
327
            flags         => 'h',
328
        },
Yadd's avatar
Yadd 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',
Yadd's avatar
Yadd committed
334
            msgFail => '__badPerlPackageName__',
Yadd's avatar
Yadd committed
335
            documentation => 'Custom Nginx handler (deprecated)',
Yadd's avatar
Yadd 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',
Yadd's avatar
Yadd committed
346
            flags         => 'hmp',
347 348
            test          => $url,
            msgFail       => '__badUrl__',
349
        },
Yadd's avatar
Yadd committed
350 351 352
        portalStatus => {
            type          => 'bool',
            default       => 0,
Yadd's avatar
Typo  
Yadd committed
353
            help          => 'status.html',
Yadd's avatar
Yadd committed
354 355
            documentation => 'Enable portal status',
        },
356 357 358 359
        portalUserAttr => {
            type    => 'text',
            default => '_user',
            documentation =>
Clément OUDOT's avatar
Clément OUDOT committed
360
              'Session parameter to display connected user in portal',
361 362 363 364
        },
        redirectFormMethod => {
            type => "select",
            select =>
Clément OUDOT's avatar
Clément OUDOT committed
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 => {
Clément OUDOT's avatar
Clément OUDOT committed
376 377 378 379 380
            type          => 'keyTextContainer',
            help          => 'configlocation.html#configuration_reload',
            keyTest       => qr/^$Regexp::Common::URI::RFC2396::host(?::\d+)?$/,
            test          => $url,
            msgFail       => '__badUrl__',
Yadd's avatar
Yadd 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',
        },
Yadd's avatar
Yadd committed
397 398 399 400
        multiValuesSeparator => {
            type          => 'authParamsText',
            default       => '; ',
            documentation => 'Separator for multiple values',
Yadd's avatar
Yadd committed
401
            flags         => 'hmp',
Yadd's avatar
Yadd committed
402
        },
Yadd's avatar
Yadd committed
403
        stayConnected => {
Yadd's avatar
Typo  
Yadd committed
404 405
            type => 'bool',

406
            #help          => 'stayconnected.html',
407
            default       => 0,
Yadd's avatar
Yadd committed
408 409
            documentation => 'Enable StayConnected plugin',
        },
Yadd's avatar
Yadd committed
410
        checkState => {
411
            type          => 'bool',
412
            default       => 0,
Yadd's avatar
Yadd committed
413 414
            documentation => 'Enable CheckState plugin',
        },
415
        checkStateSecret => {
416
            type          => 'text',
Yadd's avatar
Yadd committed
417 418
            documentation => 'Secret token for CheckState plugin',
        },
419
        skipRenewConfirmation => {
420 421
            type    => 'bool',
            default => 0,
422
            documentation =>
Clément OUDOT's avatar
Clément OUDOT committed
423
              'Avoid asking confirmation when an Issuer asks to renew auth',
424
        },
425 426 427 428
        handlerInternalCache => {
            type          => 'int',
            default       => 15,
            documentation => 'Handler internal cache timeout',
Christophe Maudoux's avatar
Christophe Maudoux committed
429
            flags         => 'hp',
430
        },
431

432 433 434 435 436 437 438 439 440
        # Loggers (ini only)
        logLevel => {
            type          => 'text',
            documentation => 'Log level, must be set in .ini',
            flags         => 'hmp',
        },
        logger => {
            type          => 'text',
            documentation => 'technical logger',
Yadd's avatar
Yadd committed
441
            flags         => 'hmp',
442 443 444 445
        },
        userLogger => {
            type          => 'text',
            documentation => 'User actions logger',
Yadd's avatar
Yadd committed
446
            flags         => 'hmp',
447 448 449 450
        },
        log4perlConfFile => {
            type          => 'text',
            documentation => 'Log4Perl logger configuration file',
Yadd's avatar
Yadd committed
451
            flags         => 'hmp',
452 453 454 455
        },
        sentryDsn => {
            type          => 'text',
            documentation => 'Sentry logger DSN',
Yadd's avatar
Yadd committed
456
            flags         => 'hmp',
457 458 459 460
        },
        syslogFacility => {
            type          => 'text',
            documentation => 'Syslog logger technical facility',
Yadd's avatar
Yadd committed
461
            flags         => 'hmp',
462 463 464 465
        },
        userSyslogFacility => {
            type          => 'text',
            documentation => 'Syslog logger user-actions facility',
Yadd's avatar
Yadd committed
466
            flags         => 'hmp',
467 468 469
        },

        # Manager or PSGI protected apps
470
        protection => {
Clément OUDOT's avatar
Clément OUDOT committed
471 472 473
            type          => 'text',
            test          => qr/^(?:none|authenticate|manager|)$/,
            msgFail       => '__authorizedValues__: none authenticate manager',
474
            documentation => 'Manager protection method',
Yadd's avatar
Yadd committed
475
            flags         => 'hm',
476 477 478 479 480 481 482 483 484 485
        },

        # Menu
        activeTimer => {
            type          => 'bool',
            default       => 1,
            documentation => 'Enable timers on portal pages',
        },
        applicationList => {
            type    => 'catAndAppList',
Yadd's avatar
Yadd committed
486
            keyTest => qr/\w/,
487 488
            help    => 'portalmenu.html#categories_and_applications',
            default => {
Clément OUDOT's avatar
Clément OUDOT committed
489
                default => { catname => 'Default category', type => "category" }
490 491 492
            },
            documentation => 'Applications list',
        },
493 494 495 496 497
        portalErrorOnExpiredSession => {
            type          => 'bool',
            default       => 1,
            documentation => 'Show error if session is expired',
        },
498
        portalErrorOnMailNotFound => {
dcoutadeur dcoutadeur's avatar
dcoutadeur dcoutadeur committed
499 500 501
            type    => 'bool',
            default => 0,
            documentation =>
Clément OUDOT's avatar
Clément OUDOT committed
502
              'Show error if mail is not found in password reset process',
503
        },
504 505 506 507 508 509 510 511 512 513 514 515 516 517
        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',
Yadd's avatar
Yadd committed
518
            select        => [ { k => 'bootstrap', v => 'Bootstrap' }, ],
519 520 521 522 523 524
        },
        portalSkinBackground => {
            type          => 'portalskinbackground',
            documentation => 'Background image of portal skin',
            select        => [
                { k => "", v => 'None' },
Clément OUDOT's avatar
Clément OUDOT committed
525 526
                {
                    k => "1280px-Anse_Source_d'Argent_2-La_Digue.jpg",
527 528
                    v => 'Anse'
                },
Clément OUDOT's avatar
Clément OUDOT committed
529 530 531
                {
                    k =>
"1280px-Autumn-clear-water-waterfall-landscape_-_Virginia_-_ForestWander.jpg",
532 533 534
                    v => 'Waterfall'
                },
                { k => "1280px-BrockenSnowedTrees.jpg", v => 'Snowed Trees' },
Clément OUDOT's avatar
Clément OUDOT committed
535 536
                {
                    k => "1280px-Cedar_Breaks_National_Monument_partially.jpg",
537 538
                    v => 'National Monument'
                },
Clément OUDOT's avatar
Clément OUDOT committed
539 540
                {
                    k => "1280px-Parry_Peak_from_Winter_Park.jpg",
541 542
                    v => 'Winter'
                },
Clément OUDOT's avatar
Clément OUDOT committed
543 544
                {
                    k => "Aletschgletscher_mit_Pinus_cembra1.jpg",
545 546
                    v => 'Pinus'
                },
547 548 549
            ],
        },
        portalSkinRules => {
Yadd's avatar
Yadd committed
550 551 552 553 554 555 556
            type          => 'keyTextContainer',
            help          => 'portalcustom.html',
            keyTest       => $perlExpr,
            keyMsgFail    => '__badSkinRule__',
            test          => qr/^\w+$/,
            msgFail       => '__badValue__',
            documentation => 'Rules to choose portal skin',
557 558 559
        },

        # Security
Yadd's avatar
Yadd committed
560
        formTimeout => {
Yadd's avatar
Yadd committed
561 562
            default       => 120,
            type          => 'int',
Yadd's avatar
Yadd committed
563 564 565
            documentation => 'Token timeout for forms',
        },
        requireToken => {
Yadd's avatar
Yadd committed
566 567
            default       => 1,
            type          => 'bool',
Yadd's avatar
Yadd committed
568 569
            documentation => 'Enable token for forms',
        },
570 571 572 573 574
        tokenUseGlobalStorage => {
            default       => 0,
            type          => 'bool',
            documentation => 'Enable global token storage',
        },
575 576 577 578
        cda => {
            default       => 0,
            type          => 'bool',
            documentation => 'Enable Cross Domain Authentication',
Yadd's avatar
Yadd committed
579
            flags         => 'hp',
580 581 582 583 584 585
        },
        checkXSS => {
            default       => 1,
            type          => 'bool',
            documentation => 'Check XSS',
        },
586
        portalForceAuthn => {
587
            default => 0,
588
            help    => 'forcereauthn.html',
589 590
            type    => 'bool',
            documentation =>
Clément OUDOT's avatar
Clément OUDOT committed
591
              'Enable force to authenticate when displaying portal',
592
        },
593 594
        portalForceAuthnInterval => {
            default => 5,
595 596
            type    => 'int',
            documentation =>
Yadd's avatar
Typo  
Yadd committed
597
'Maximum interval in seconds since last authentication to force reauthentication',
598
        },
599
        bruteForceProtection => {
600
            default       => 0,
601
            help          => 'bruteforceprotection.html',
602 603 604 605 606 607 608
            type          => 'bool',
            documentation => 'Enable brute force attack protection',
        },
        bruteForceProtectionTempo => {
            default => 30,
            type    => 'int',
            documentation =>
Clément OUDOT's avatar
Clément OUDOT committed
609
              'Brute force attack protection -> Tempo before try again',
610 611 612 613 614
        },
        bruteForceProtectionMaxAge => {
            default => 300,
            type    => 'int',
            documentation =>
615 616 617 618 619 620 621
              'Brute force attack protection -> Max age between last and first allowed failed login',
        },
        bruteForceProtectionMaxFailed => {
            default => 3,
            type    => 'int',
            documentation =>
              'Brute force attack protection -> Max allowed failed login',
622
        },
623
        grantSessionRules => {
Yadd's avatar
Yadd committed
624 625
            type          => 'grantContainer',
            keyTest       => $perlExpr,
Clément OUDOT's avatar
Clément OUDOT committed
626
            test          => sub { 1 },
Yadd's avatar
Yadd committed
627
            documentation => 'Rules to grant sessions',
628 629 630 631 632 633 634 635 636 637
        },
        hiddenAttributes => {
            type          => 'text',
            default       => '_password',
            documentation => 'Name of attributes to hide in logs',
        },
        key => {
            type          => 'password',
            documentation => 'Secret key',
        },
638 639
        cspDefault => {
            type          => 'text',
Yadd's avatar
Yadd committed
640
            default       => "'self'",
641 642
            documentation => 'Default value for Content-Security-Policy',
        },
643
        cspFormAction => {
644 645 646 647
            type    => 'text',
            default => "'self'",
            documentation =>
              'Form action destination for Content-Security-Policy',
648
        },
649 650
        cspImg => {
            type          => 'text',
651
            default       => "'self' data:",
652 653 654 655 656 657 658 659 660
            documentation => 'Image source for Content-Security-Policy',
        },
        cspScript => {
            type          => 'text',
            default       => "'self'",
            documentation => 'Javascript source for Content-Security-Policy',
        },
        cspStyle => {
            type          => 'text',
Yadd's avatar
Yadd committed
661
            default       => "'self'",
662 663 664 665 666 667
            documentation => 'Style source for Content-Security-Policy',
        },
        cspConnect => {
            type    => 'text',
            default => "'self'",
            documentation =>
Christophe Maudoux's avatar
Typo  
Christophe Maudoux committed
668
              'Authorized Ajax destination for Content-Security-Policy',
669 670 671 672 673 674
        },
        cspFont => {
            type          => 'text',
            default       => "'self'",
            documentation => 'Font source for Content-Security-Policy',
        },
675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
        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',
        },
Yadd's avatar
Yadd committed
690
        trustedDomains =>
Clément OUDOT's avatar
Clément OUDOT committed
691
          { type => 'text', documentation => 'Trusted domains', },
Yadd's avatar
Yadd committed
692
        storePassword => {
693 694 695 696 697 698
            default       => 0,
            type          => 'bool',
            documentation => 'Store password in session',
        },
        timeout => {
            type          => 'int',
Yadd's avatar
Yadd committed
699
            test          => sub { $_[0] > 0 },
700 701 702 703
            default       => 72000,
            documentation => 'Session timeout on server side',
        },
        timeoutActivity => {
704
            type          => 'int',
Yadd's avatar
Yadd committed
705
            test          => sub { $_[0] >= 0 },
706 707 708
            default       => 0,
            documentation => 'Session activity timeout on server side',
        },
709 710 711 712 713 714
        timeoutActivityInterval => {
            type          => 'int',
            test          => sub { $_[0] >= 0 },
            default       => 60,
            documentation => 'Update session timeout interval on server side',
        },
715 716 717 718 719 720 721 722 723 724 725 726 727 728
        trustedProxies => {
            type          => 'text',
            default       => '',
            documentation => 'Trusted proxies',
        },
        userControl => {
            type          => 'pcre',
            default       => '^[\w\.\-@]+$',
            documentation => 'Regular expression to validate login',
        },
        useRedirectOnError => {
            type          => 'bool',
            default       => 1,
            documentation => 'Use 302 redirect code for error (500)',
Yadd's avatar
Yadd committed
729
            flags         => 'h',
730 731 732 733 734 735 736 737 738
        },
        useRedirectOnForbidden => {
            default       => 0,
            type          => 'bool',
            documentation => 'Use 302 redirect code for forbidden (403)',
        },
        useSafeJail => {
            default       => 1,
            type          => 'bool',
Yadd's avatar
Yadd committed
739
            help          => 'safejail.html',
740
            documentation => 'Activate Safe jail',
Yadd's avatar
Yadd committed
741
            flags         => 'hp',
742 743 744 745 746
        },
        whatToTrace => {
            type          => 'lmAttrOrMacro',
            default       => 'uid',
            documentation => 'Session parameter used to fill REMOTE_USER',
Yadd's avatar
Yadd committed
747
            flags         => 'hp',
748
        },
Yadd's avatar
Yadd committed
749
        lwpOpts => {
Yadd's avatar
Yadd committed
750 751 752
            type          => 'keyTextContainer',
            documentation => 'Options given to LWP::UserAgent',
        },
Yadd's avatar
Yadd committed
753 754 755 756
        lwpSslOpts => {
            type          => 'keyTextContainer',
            documentation => 'SSL options given to LWP::UserAgent',
        },
757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801

        # 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 => {
Yadd's avatar
Yadd committed
802
            default       => 0,
803 804 805
            type          => 'bool',
            documentation => 'Display reset password button in portal',
        },
806
        passwordResetAllowedRetries => {
Christophe Maudoux's avatar
Christophe Maudoux committed
807
            default       => 3,
808 809 810
            type          => 'int',
            documentation => 'Maximum number of retries to reset password',
        },
Yadd's avatar
Yadd committed
811 812
        portalDisplayOidcConsents => {
            type          => 'boolOrExpr',
813
            default       => '$_oidcConnectedRP',
Yadd's avatar
Yadd committed
814 815
            documentation => 'Display OIDC consent tab in portal',
        },
816 817

        # Cookies
Yadd's avatar
Yadd committed
818
        cookieExpiration => {
819
            type          => 'int',
Yadd's avatar
Yadd committed
820 821 822
            documentation => 'Cookie expiration',
            flags         => 'hp',
        },
Yadd's avatar
Yadd committed
823
        cookieName => {
824 825 826 827 828
            type          => 'text',
            test          => qr/^[a-zA-Z][a-zA-Z0-9_-]*$/,
            msgFail       => '__badCookieName__',
            default       => 'lemonldap',
            documentation => 'Name of the main cookie',
Yadd's avatar
Yadd committed
829
            flags         => 'hp',
830 831
        },
        domain => {
Clément OUDOT's avatar
Clément OUDOT committed
832 833 834 835
            type          => 'text',
            test          => qr/^(?:$Regexp::Common::URI::RFC2396::hostname)?$/,
            msgFail       => '__badDomainName__',
            default       => 'example.com',
836
            documentation => 'DNS domain',
Yadd's avatar
Yadd committed
837
            flags         => 'hp',
838 839 840 841 842
        },
        httpOnly => {
            default       => 1,
            type          => 'bool',
            documentation => 'Enable httpOnly flag in cookie',
Yadd's avatar
Yadd committed
843
            flags         => 'hp',
844 845 846 847 848 849 850 851 852 853 854
        },
        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',
Yadd's avatar
Yadd committed
855
            flags         => 'hp',
856 857 858
        },

        # Notification
859
        oldNotifFormat => {
Yadd's avatar
Yadd committed
860 861
            type          => 'bool',
            default       => 0,
Yadd's avatar
Yadd committed
862
            documentation => 'Use old XML format for notifications',
863
        },
864 865 866 867 868
        notificationWildcard => {
            type          => 'text',
            default       => 'allusers',
            documentation => 'Notification string to match all users',
        },
Yadd's avatar
Yadd committed
869 870 871 872 873
        notificationXSLTfile => {
            type          => 'text',
            documentation => 'Custom XSLT document for notifications',
        },
        notification => {
874 875 876 877
            default       => 0,
            type          => 'bool',
            documentation => 'Notification activation',
        },
Yadd's avatar
Yadd committed
878 879 880 881 882
        notificationServer => {
            default       => 0,
            type          => 'bool',
            documentation => 'Notification server activation',
        },
883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900
        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 => {
901
            default       => 1,
902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920
            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_]*$/,
Yadd's avatar
Yadd committed
921
            keyMsgFail    => '__badVariableName__',
922 923 924 925 926 927 928 929
            test          => qr/^[_a-zA-Z][a-zA-Z0-9_:\-]*$/,
            msgFail       => '__badValue__',
            default       => { 'UA' => 'HTTP_USER_AGENT' },
            documentation => 'Main exported variables',
        },
        groups => {
            type => 'keyTextContainer',
            help =>
Clément OUDOT's avatar
Clément OUDOT committed
930
              'exportedvars.html#extend_variables_using_macros_and_groups',
931 932 933 934 935 936 937
            test          => $perlExpr,
            default       => {},
            documentation => 'Groups',
        },
        macros => {
            type => 'keyTextContainer',
            help =>
Clément OUDOT's avatar
Clément OUDOT committed
938
              'exportedvars.html#extend_variables_using_macros_and_groups',
939
            keyTest       => qr/^[_a-zA-Z][a-zA-Z0-9_]*$/,
Yadd's avatar
Yadd committed
940
            keyMsgFail    => '__badMacroName__',
941 942 943 944 945 946 947 948 949 950
            test          => $perlExpr,
            default       => {},
            documentation => 'Macros',
        },

        # Storage
        globalStorage => {
            type          => 'PerlModule',
            default       => 'Apache::Session::File',
            documentation => 'Session backend module',
Yadd's avatar
Yadd committed
951
            flags         => 'hp',
952 953 954 955 956 957 958
        },
        globalStorageOptions => {
            type    => 'keyTextContainer',
            default => {
                'Directory'     => '/var/lib/lemonldap-ng/sessions/',
                'LockDirectory' => '/var/lib/lemonldap-ng/sessions/lock/',
                'generateModule' =>
Clément OUDOT's avatar
Clément OUDOT committed
959
                  'Lemonldap::NG::Common::Apache::Session::Generate::SHA256',
Yadd's avatar