Fix unit test
This commit is contained in:
commit
b1232739a0
|
@ -27,6 +27,9 @@ theses :
|
||||||
* **OAUTH2_USERINFO_ENDPOINT**: ``oauth2/userinfo``
|
* **OAUTH2_USERINFO_ENDPOINT**: ``oauth2/userinfo``
|
||||||
* **OAUTH2_TOKEN_ENDPOINT**: ``oauth2/token``
|
* **OAUTH2_TOKEN_ENDPOINT**: ``oauth2/token``
|
||||||
* **OAUTH2_ID_MAP**: ``sub``
|
* **OAUTH2_ID_MAP**: ``sub``
|
||||||
|
* **OAUTH2_USERNAME_MAP**: ``sub``
|
||||||
|
* **OAUTH2_FULLNAME_MAP**: ``name``
|
||||||
|
* **OAUTH2_EMAIL_MAP**: ``email``
|
||||||
|
|
||||||
|
|
||||||
.. danger::
|
.. danger::
|
||||||
|
|
|
@ -246,7 +246,8 @@ Here are some recommended configurations:
|
||||||
_whatToTrace varchar(64),
|
_whatToTrace varchar(64),
|
||||||
_session_kind varchar(15),
|
_session_kind varchar(15),
|
||||||
user text,
|
user text,
|
||||||
_utime bigint
|
_utime bigint,
|
||||||
|
ipAddr varchar(64)
|
||||||
);
|
);
|
||||||
CREATE INDEX uid1 ON sessions (_whatToTrace) USING BTREE;
|
CREATE INDEX uid1 ON sessions (_whatToTrace) USING BTREE;
|
||||||
CREATE INDEX _s1 ON sessions (_session_kind);
|
CREATE INDEX _s1 ON sessions (_session_kind);
|
||||||
|
|
|
@ -18,7 +18,7 @@ Just enable it in the manager (section “plugins”).
|
||||||
displayed (by example: ``!$anonymous``)
|
displayed (by example: ``!$anonymous``)
|
||||||
- **Unrestricted users rule**: Rule to define which users can check
|
- **Unrestricted users rule**: Rule to define which users can check
|
||||||
ALL users. ``Identities use rule`` is bypassed.
|
ALL users. ``Identities use rule`` is bypassed.
|
||||||
- **Hidden attributes**: Attributes not displayed
|
- **Hidden attributes**: Session attributes not displayed
|
||||||
- **Attributes used for searching sessions**: User's attributes used
|
- **Attributes used for searching sessions**: User's attributes used
|
||||||
for searching sessions in backend if ``whatToTrace`` fails. Useful
|
for searching sessions in backend if ``whatToTrace`` fails. Useful
|
||||||
to look for sessions by mail or givenName. Let it blank to search
|
to look for sessions by mail or givenName. Let it blank to search
|
||||||
|
@ -31,11 +31,27 @@ Just enable it in the manager (section “plugins”).
|
||||||
even empty ones
|
even empty ones
|
||||||
- **Display persistent session data**: Rule to define which users can display
|
- **Display persistent session data**: Rule to define which users can display
|
||||||
persistent session data
|
persistent session data
|
||||||
|
- **Hidden headers**: Sent headers whose value is masked except for unrestricted users.
|
||||||
|
Key is a Virtualhost name and value represents a headers list.
|
||||||
|
A blank value obfuscates ALL relative Virtualhost sent headers.
|
||||||
|
Note that just valued hearders are masked.
|
||||||
|
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
By examples :
|
By example:
|
||||||
|
|
||||||
|
\* test1.example.com => ``Auth-User mail``
|
||||||
|
Just 'Auth-User' and 'mail' headers are masked if valued.
|
||||||
|
|
||||||
|
\* test2.example.com => '' ALL valued headers are masked.
|
||||||
|
|
||||||
|
Unrestricted users can see the masked headers.
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
By example:
|
||||||
|
|
||||||
\* Search attributes => ``mail uid givenName``
|
\* Search attributes => ``mail uid givenName``
|
||||||
|
|
||||||
|
|
|
@ -503,6 +503,9 @@ Some options are available:
|
||||||
- Maintenance mode: reject all requests with a maintenance message
|
- Maintenance mode: reject all requests with a maintenance message
|
||||||
- Aliases: list of aliases for this virtual host *(avoid to rewrite
|
- Aliases: list of aliases for this virtual host *(avoid to rewrite
|
||||||
rules,...)*
|
rules,...)*
|
||||||
|
- Access to trace: can be used for overwriting REMOTE_CUSTOM with a custom function.
|
||||||
|
Provide a comma separated parameters list with custom function path and args.
|
||||||
|
By example: My::accessToTrace, Doctor, Who
|
||||||
- Type: handler type (normal,
|
- Type: handler type (normal,
|
||||||
:doc:`ServiceToken Handler<servertoserver>`,
|
:doc:`ServiceToken Handler<servertoserver>`,
|
||||||
:doc:`DevOps Handler<devopshandler>`,...)
|
:doc:`DevOps Handler<devopshandler>`,...)
|
||||||
|
@ -515,6 +518,30 @@ Some options are available:
|
||||||
seconds. This TTL can be customized for each virtual host.
|
seconds. This TTL can be customized for each virtual host.
|
||||||
|
|
||||||
|
|
||||||
|
.. attention::
|
||||||
|
|
||||||
|
A hash reference containing $req, $session, $vhost, $custom and an array reference
|
||||||
|
with provided parameters is passed to the custom function.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
package My;
|
||||||
|
|
||||||
|
sub accessToTrace {
|
||||||
|
my $hash = shift;
|
||||||
|
my $custom = $hash->{custom};
|
||||||
|
my $req = $hash->{req};
|
||||||
|
my $vhost = $hash->{vhost};
|
||||||
|
my $custom = $hash->{custom};
|
||||||
|
my $params = $hash->{params};
|
||||||
|
my $session = $hash->{session};
|
||||||
|
|
||||||
|
return "$custom alias $params->[0]_$params->[1]:$session->{groups}";
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
|
||||||
.. danger::
|
.. danger::
|
||||||
|
|
||||||
A same virtual host can serve many locations. Each
|
A same virtual host can serve many locations. Each
|
||||||
|
|
|
@ -10,7 +10,7 @@ extracted from the users database by the
|
||||||
:ref:`users module<start-authentication-users-and-password-databases>`.
|
:ref:`users module<start-authentication-users-and-password-databases>`.
|
||||||
|
|
||||||
To create a variable, you've just to map a user attributes in LL::NG
|
To create a variable, you've just to map a user attributes in LL::NG
|
||||||
using ``Variables`` » ``Exported variables``. For each variable, The
|
using ``Variables`` » ``Exported variables``. For each variable, the
|
||||||
first field is the name which will be used in rules, macros or headers
|
first field is the name which will be used in rules, macros or headers
|
||||||
and the second field is the name of the user database field.
|
and the second field is the name of the user database field.
|
||||||
|
|
||||||
|
|
|
@ -25,19 +25,20 @@ Inside this jail, you can access to:
|
||||||
* Information about current request
|
* Information about current request
|
||||||
* Extended functions:
|
* Extended functions:
|
||||||
|
|
||||||
* date_
|
|
||||||
* checkLogonHours_
|
|
||||||
* checkDate_
|
|
||||||
* basic_
|
* basic_
|
||||||
* unicode2iso_
|
* checkDate_
|
||||||
* iso2unicode_
|
* checkLogonHours_
|
||||||
* groupMatch_
|
* date_
|
||||||
* listMatch_
|
|
||||||
* inGroup_
|
|
||||||
* encrypt_
|
* encrypt_
|
||||||
* token_
|
* groupMatch_
|
||||||
|
* has2f_ (|new| in version 2.0.10)
|
||||||
|
* inGroup_ (|new| in version 2.0.8)
|
||||||
* isInNet6_
|
* isInNet6_
|
||||||
* varIsInUri_
|
* iso2unicode_
|
||||||
|
* listMatch_ (|new| in version 2.0.7)
|
||||||
|
* token_
|
||||||
|
* unicode2iso_
|
||||||
|
* varIsInUri_ (|new| in version 2.0.7)
|
||||||
|
|
||||||
|
|
||||||
.. |new| image:: /documentation/new.png
|
.. |new| image:: /documentation/new.png
|
||||||
|
@ -238,6 +239,40 @@ Simple usage example:
|
||||||
|
|
||||||
groupMatch($hGroups, 'description', 'Service 1')
|
groupMatch($hGroups, 'description', 'Service 1')
|
||||||
|
|
||||||
|
|
||||||
|
.. _has2f:
|
||||||
|
|
||||||
|
has2f
|
||||||
|
~~~~~
|
||||||
|
|
||||||
|
.. versionadded:: 2.0.10
|
||||||
|
|
||||||
|
This function tests if the current user has registered a second factor. The following types are supported:
|
||||||
|
|
||||||
|
* :doc:`TOTP<totp2f>`
|
||||||
|
* :doc:`U2F<u2f>`
|
||||||
|
* :doc:`UBK<yubikey2f>`
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
has2f()
|
||||||
|
has2f('UBK')
|
||||||
|
has2f('UBK') or has2f('TOTP')
|
||||||
|
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
Do **NOT** use this test to check if the user has **used** their second factor for logging in!
|
||||||
|
This test only checks if the user has registered a second factor. Regardless of their **current**
|
||||||
|
authentication level. It can be used to simplify second factor activation rules.
|
||||||
|
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Before version 2.0.10, you need to use the following syntax ::
|
||||||
|
|
||||||
|
$_2fDevices =~ /"type":\s*"TOTP"/s
|
||||||
|
|
||||||
.. _listMatch:
|
.. _listMatch:
|
||||||
|
|
||||||
listMatch
|
listMatch
|
||||||
|
|
|
@ -57,6 +57,12 @@ logs, go into Manager, ``General Parameters`` > ``Logging`` >
|
||||||
User log samples
|
User log samples
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
The user name set in user log messages is configured with `whatToTrace` parameter, except
|
||||||
|
for messages corresponding to failed authentification, whe the user name logged is the
|
||||||
|
login used by the user.
|
||||||
|
|
||||||
Authentication:
|
Authentication:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
@ -84,6 +90,12 @@ Logout:
|
||||||
|
|
||||||
[notice] User dwho has been disconnected from LDAP (81.20.13.21)
|
[notice] User dwho has been disconnected from LDAP (81.20.13.21)
|
||||||
|
|
||||||
|
Password change:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
[notice] Password changed for dwho (81.20.13.21)
|
||||||
|
|
||||||
Access to a CAS application non registered in configuration (when CAS server is open):
|
Access to a CAS application non registered in configuration (when CAS server is open):
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
|
@ -27,6 +27,16 @@ attribute you see there can be used in a rule!
|
||||||
In Perl, ``eq`` means *Equal* and must be used on strings.
|
In Perl, ``eq`` means *Equal* and must be used on strings.
|
||||||
``==`` should be used only on numbers
|
``==`` should be used only on numbers
|
||||||
|
|
||||||
|
.. danger::
|
||||||
|
|
||||||
|
In Perl, ``@`` character means an array and ``%`` a hash!
|
||||||
|
If you want to write a macro with these characters, you have to escape them like this:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
$my_email = "$uid\@my-domain.com"
|
||||||
|
$percent = "$rate\%more"
|
||||||
|
|
||||||
- Restricting access to specific groups
|
- Restricting access to specific groups
|
||||||
|
|
||||||
::
|
::
|
||||||
|
@ -64,6 +74,17 @@ attribute you see there can be used in a rule!
|
||||||
|
|
||||||
$_auth ne 'Demo'
|
$_auth ne 'Demo'
|
||||||
|
|
||||||
|
- Checking if the user has a an **available** second factor.
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# Since 2.0.10
|
||||||
|
has2f()
|
||||||
|
has2f('TOTP')
|
||||||
|
has2f('TOTP') or has2f('U2F')
|
||||||
|
|
||||||
|
# Before 2.0.10
|
||||||
|
$_2fDevices =~ /"type":\s*"TOTP"/s
|
||||||
|
|
||||||
.. tip::
|
.. tip::
|
||||||
|
|
||||||
|
@ -71,6 +92,7 @@ attribute you see there can be used in a rule!
|
||||||
strings. ``\b`` means *word Boundary*. (?:) means *non capturing*
|
strings. ``\b`` means *word Boundary*. (?:) means *non capturing*
|
||||||
parenthesis.
|
parenthesis.
|
||||||
|
|
||||||
|
|
||||||
Using environment variables
|
Using environment variables
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ Presentation
|
||||||
|
|
||||||
LemonLDAP::NG uses Safe jail to evaluate all expressions:
|
LemonLDAP::NG uses Safe jail to evaluate all expressions:
|
||||||
|
|
||||||
- Access rule
|
- Access rules
|
||||||
- Header
|
- Headers
|
||||||
- Form replay parameters
|
- Form replay parameters
|
||||||
- Macros
|
- Macros
|
||||||
- Groups
|
- Groups
|
||||||
|
@ -31,3 +31,19 @@ to disable it.
|
||||||
|
|
||||||
To do this, go into Manager > General Parameters > Advanced Parameters >
|
To do this, go into Manager > General Parameters > Advanced Parameters >
|
||||||
Security > Use Safe Jail and disable it.
|
Security > Use Safe Jail and disable it.
|
||||||
|
|
||||||
|
|
||||||
|
Assignment test
|
||||||
|
===============
|
||||||
|
|
||||||
|
Presentation
|
||||||
|
------------
|
||||||
|
|
||||||
|
Perl comparaisons are done by using ``eq`` for strings or ``==`` for integers.
|
||||||
|
To avoid an unwanted assignment like ``$authLevel = 5`` (BAD EXPRESSION!),
|
||||||
|
you can enable ``Avoid assignment in expressions`` option.
|
||||||
|
|
||||||
|
To do this, go into Manager > General Parameters > Advanced Parameters >
|
||||||
|
Security > Avoid assignment in expressions and enable it.
|
||||||
|
|
||||||
|
DISABLE by default.
|
|
@ -7,15 +7,12 @@ options.
|
||||||
Disk cache (sessions an configuration)
|
Disk cache (sessions an configuration)
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
::
|
You need to set the correct context on the cache directory
|
||||||
|
|
||||||
chcon -R -t httpd_sys_rw_content_t /var/cache/lemonldap-ng
|
|
||||||
|
|
||||||
To persist the rule:
|
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
semanage fcontext -a -t http_sys_content_t /var/cache/lemonldap-ng
|
semanage fcontext --add -t httpd_cache_t -f a '/var/cache/lemonldap-ng(/.*)?'
|
||||||
|
restorecon -R /var/cache/lemonldap-ng/
|
||||||
|
|
||||||
LDAP
|
LDAP
|
||||||
----
|
----
|
||||||
|
|
|
@ -74,6 +74,12 @@ In the manager (advanced parameters), you just have to enable it:
|
||||||
required even if users are not registered. This is automatically done
|
required even if users are not registered. This is automatically done
|
||||||
when "activation" is simply set to "on".
|
when "activation" is simply set to "on".
|
||||||
|
|
||||||
|
|
||||||
|
.. danger::
|
||||||
|
|
||||||
|
Range is tested backward and forward to prevent
|
||||||
|
positive or negative clock drift.
|
||||||
|
|
||||||
Enrollment
|
Enrollment
|
||||||
----------
|
----------
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@ backups and a rollback plan ready!
|
||||||
------
|
------
|
||||||
|
|
||||||
- New dependency: IO::Socket::Timeout
|
- New dependency: IO::Socket::Timeout
|
||||||
|
- TOTP check tolerates forward AND backward clock drift (totp2fRange)
|
||||||
|
- Avoid assignment in expressions option is disabled by default
|
||||||
|
|
||||||
2.0.9
|
2.0.9
|
||||||
-----
|
-----
|
||||||
|
@ -31,7 +33,7 @@ backups and a rollback plan ready!
|
||||||
(see also `#2244 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/2244>`__)
|
(see also `#2244 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/2244>`__)
|
||||||
- SAML SOAP calls are now using ``text/xml`` instead of ``application/xml`` as the MIME Content Type, as required by `the SOAP standard <https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383526>`__
|
- SAML SOAP calls are now using ``text/xml`` instead of ``application/xml`` as the MIME Content Type, as required by `the SOAP standard <https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383526>`__
|
||||||
- Incremental lock times values can now be set in BruteForceProtection plugin through Manager.
|
- Incremental lock times values can now be set in BruteForceProtection plugin through Manager.
|
||||||
It must be a list of comma separated values. Default values are ``5, 15, 60, 300, 600``
|
It MUST be a list of comma separated values. Default values are ``5, 15, 60, 300, 600``
|
||||||
|
|
||||||
Cookie issues with Chrome
|
Cookie issues with Chrome
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -190,14 +190,14 @@ use macros, local macros,...
|
||||||
|
|
||||||
.. attention::
|
.. attention::
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- Since many HTTP servers refuse non ascii headers, it is recommended
|
- Since many HTTP servers refuse non ascii headers, it is recommended
|
||||||
to use encode_base64() function to transmit those headers
|
to use encode_base64() function to transmit those headers
|
||||||
- Don't forget to add an empty string as second argument to
|
- Don't forget to add an empty string as second argument to
|
||||||
encode_base64 function to avoid a "newline" characters insertion in
|
encode_base64 function to avoid a "newline" characters insertion in
|
||||||
result
|
result
|
||||||
- Header names must contain only letters and "-" character
|
- Header names must contain only letters and "-" character.
|
||||||
|
With Nginx, you can bypass this restriction by using
|
||||||
|
``underscores_in_headers on;`` directive
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,4 +8,16 @@ sub get_additional_arg {
|
||||||
return $_[0];
|
return $_[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub accessToTrace {
|
||||||
|
my $hash = shift;
|
||||||
|
my $custom = $hash->{custom};
|
||||||
|
my $req = $hash->{req};
|
||||||
|
my $vhost = $hash->{vhost};
|
||||||
|
my $custom = $hash->{custom};
|
||||||
|
my $params = $hash->{params};
|
||||||
|
my $session = $hash->{session};
|
||||||
|
|
||||||
|
return "$custom alias $params->[0]_$params->[1]:$session->{groups} with $session->{$params->[2]}";
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -22,7 +22,7 @@ dirName=__pwd__/e2e-tests/conf
|
||||||
checkXSS = 0
|
checkXSS = 0
|
||||||
portalSkin = bootstrap
|
portalSkin = bootstrap
|
||||||
staticPrefix = /static
|
staticPrefix = /static
|
||||||
languages = fr, en, vi, it, ar, de, zh, nl, es, pt, ro, tr
|
languages = fr, en, vi, it, ar, de, zh, nl, es, pt, ro, tr, zh_TW
|
||||||
templateDir = __pwd__/lemonldap-ng-portal/site/templates
|
templateDir = __pwd__/lemonldap-ng-portal/site/templates
|
||||||
portalStatus = 1
|
portalStatus = 1
|
||||||
totp2fActivation = 1
|
totp2fActivation = 1
|
||||||
|
@ -49,7 +49,7 @@ viewerAllowDiff = 1
|
||||||
|
|
||||||
staticPrefix = /static
|
staticPrefix = /static
|
||||||
instanceName = Demo
|
instanceName = Demo
|
||||||
languages = fr, en, vi, ar, de, it, zh, tr
|
languages = fr, en, vi, ar, it, zh, tr, zh_TW, es
|
||||||
templateDir = __pwd__/lemonldap-ng-manager/site/templates
|
templateDir = __pwd__/lemonldap-ng-manager/site/templates
|
||||||
|
|
||||||
[node-handler]
|
[node-handler]
|
||||||
|
|
|
@ -164,6 +164,16 @@
|
||||||
"default": "accept"
|
"default": "accept"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"vhostOptions":{
|
||||||
|
"manager.example.com": {
|
||||||
|
"vhostMaintenance": 0,
|
||||||
|
"vhostPort": -1,
|
||||||
|
"vhostHttps": -1,
|
||||||
|
"vhostAliases": "",
|
||||||
|
"vhostServiceTokenTTL": -1,
|
||||||
|
"vhostAccessToTrace": "My::accessToTrace, Doctor, Who","vhostType":"Main"
|
||||||
|
}
|
||||||
|
},
|
||||||
"loginHistoryEnabled": 1,
|
"loginHistoryEnabled": 1,
|
||||||
"macros": {
|
"macros": {
|
||||||
"UA" : "$ENV{HTTP_USER_AGENT}",
|
"UA" : "$ENV{HTTP_USER_AGENT}",
|
||||||
|
|
|
@ -196,7 +196,7 @@ staticPrefix = __PORTALSTATICDIR__
|
||||||
templateDir = __PORTALTEMPLATESDIR__
|
templateDir = __PORTALTEMPLATESDIR__
|
||||||
|
|
||||||
; languages: available languages for portal interface
|
; languages: available languages for portal interface
|
||||||
languages = en, fr, vi, it, ar, de, fi, tr, pl
|
languages = en, fr, vi, it, ar, de, fi, tr, pl, zh_TW, es
|
||||||
|
|
||||||
; II - Optional parameters (overwrite configuration)
|
; II - Optional parameters (overwrite configuration)
|
||||||
|
|
||||||
|
@ -383,7 +383,7 @@ staticPrefix = __MANAGERSTATICDIR__
|
||||||
templateDir = __MANAGERTEMPLATESDIR__
|
templateDir = __MANAGERTEMPLATESDIR__
|
||||||
|
|
||||||
; languages: available languages for manager interface
|
; languages: available languages for manager interface
|
||||||
languages = fr, en, it, vi, ar, tr, pl
|
languages = en, fr, it, vi, ar, tr, pl, zh_TW, es
|
||||||
|
|
||||||
; Manager modules enabled
|
; Manager modules enabled
|
||||||
; Set here the list of modules you want to see in manager interface
|
; Set here the list of modules you want to see in manager interface
|
||||||
|
|
|
@ -29,8 +29,8 @@ use constant DEFAULTCONFBACKEND => "File";
|
||||||
use constant DEFAULTCONFBACKENDOPTIONS => (
|
use constant DEFAULTCONFBACKENDOPTIONS => (
|
||||||
dirName => '/usr/local/lemonldap-ng/data/conf',
|
dirName => '/usr/local/lemonldap-ng/data/conf',
|
||||||
);
|
);
|
||||||
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|facebook|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|ombModule)s)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
|
our $hashParameters = qr/^(?:(?:l(?:o(?:ca(?:lSessionStorageOption|tionRule)|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|(?:(?:d(?:emo|bi)|facebook|webID)ExportedVa|exported(?:Heade|Va)|issuerDBGetParamete)r|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|macro)s|o(?:idc(?:S(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|RPMetaData(?:(?:Option(?:sExtraClaim)?|ExportedVar|Macro)s|Node)|OPMetaData(?:(?:ExportedVar|Option)s|J(?:SON|WKS)|Node))|penIdExportedVars)|c(?:as(?:A(?:ppMetaData(?:(?:ExportedVar|Option|Macro)s|Node)|ttributes)|S(?:rvMetaData(?:(?:ExportedVar|Option)s|Node)|torageOptions))|(?:ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)s)|s(?:aml(?:S(?:PMetaData(?:(?:ExportedAttribute|Option|Macro)s|Node|XML)|torageOptions)|IDPMetaData(?:(?:ExportedAttribute|Option)s|Node|XML))|essionDataToRemember|laveExportedVars|fExtra)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|p(?:ersistentStorageOptions|o(?:rtalSkinRules|st))|v(?:hostOptions|irtualHost)|S(?:MTPTLSOpts|SLVarIf))$/;
|
||||||
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|f(?:RemovedUseNotif|OnlyUpgrade)|kip(?:Upgrade|Renew)Confirmation|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Allow(?:PasswordGrant|Offline)|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:State|User|XSS)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|freshSessions)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|d(?:is(?:ablePersistentStorage|playSessionId)|biDynamicHashEnabled)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|g(?:roupsBeforeMacros|lobalLogoutTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|(?:activeTim|wsdlServ)er|krb(?:RemoveDomain|ByJs))$/;
|
our $boolKeys = qr/^(?:s(?:aml(?:IDP(?:MetaDataOptions(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|IsPassiv)e|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Force(?:Authn|UTF8)|StoreSAMLToken|RelayStateURL)|SSODescriptorWantAuthnRequestsSigned)|S(?:P(?:MetaDataOptions(?:(?:CheckS[LS]OMessageSignatur|OneTimeUs)e|EnableIDPInitiatedURL|ForceUTF8)|SSODescriptor(?:WantAssertion|AuthnRequest)sSigned)|erviceUseCertificateInResponse)|DiscoveryProtocol(?:Activation|IsPassive)|CommonDomainCookieActivation|UseQueryStringSpecific|MetadataForceUTF8)|f(?:RemovedUseNotif|OnlyUpgrade)|kip(?:Upgrade|Renew)Confirmation|oap(?:Session|Config)Server|t(?:ayConnecte|orePasswor)d|laveDisplayLogo|howLanguages|slByAjax)|o(?:idc(?:RPMetaDataOptions(?:Allow(?:PasswordGrant|Offline)|Re(?:freshToken|quirePKCE)|LogoutSessionRequired|IDTokenForceClaims|BypassConsent|Public)|ServiceAllow(?:(?:AuthorizationCode|Implicit|Hybrid)Flow|DynamicRegistration)|OPMetaDataOptions(?:(?:CheckJWTSignatur|UseNonc)e|StoreIDToken))|ldNotifFormat)|p(?:ortal(?:Display(?:Re(?:freshMyRights|setPassword|gister)|CertificateResetByMail|GeneratePassword|PasswordPolicy)|ErrorOn(?:ExpiredSession|MailNotFound)|(?:CheckLogin|Statu)s|OpenLinkInNewWindow|ForceAuthn|AntiFrame)|roxyUseSoap)|c(?:o(?:ntextSwitching(?:Allowed2fModifications|StopWithLogout)|mpactConf|rsEnabled)|a(?:ptcha_(?:register|login|mail)_enabled|sSrvMetaDataOptions(?:Gateway|Renew))|heck(?:State|User|XSS)|da)|l(?:dap(?:(?:Group(?:DecodeSearchedValu|Recursiv)|UsePasswordResetAttribut)e|(?:AllowResetExpired|Set)Password|ChangePasswordAsUser|PpolicyControl|ITDS)|oginHistoryEnabled)|no(?:tif(?:ication(?:Server(?:(?:POS|GE)T|DELETE)?|sExplorer)?|y(?:Deleted|Other))|AjaxHook)|i(?:ssuerDB(?:OpenID(?:Connect)?|SAML|CAS|Get)Activation|mpersonationSkipEmptyValues)|to(?:tp2f(?:UserCan(?:Chang|Remov)eKey|DisplayExistingSecret)|kenUseGlobalStorage)|u(?:se(?:RedirectOn(?:Forbidden|Error)|SafeJail)|2fUserCanRemoveKey|pgradeSession)|re(?:st(?:(?:Password|Session|Config|Auth)Server|ExportSecretKeys)|freshSessions)|br(?:uteForceProtection(?:IncrementalTempo)?|owsersDontStorePassword)|d(?:is(?:ablePersistentStorage|playSessionId)|biDynamicHashEnabled)|(?:mai(?:lOnPasswordChang|ntenanc)|vhostMaintenanc)e|g(?:roupsBeforeMacros|lobalLogoutTimer)|a(?:voidAssignment|ctiveTimer)|h(?:ideOldPassword|ttpOnly)|yubikey2fUserCanRemoveKey|krb(?:RemoveDomain|ByJs)|wsdlServer)$/;
|
||||||
|
|
||||||
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );
|
our @sessionTypes = ( 'remoteGlobal', 'global', 'localSession', 'persistent', 'saml', 'oidc', 'cas' );
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ our $specialNodeHash = {
|
||||||
};
|
};
|
||||||
|
|
||||||
our $doubleHashKeys = 'issuerDBGetParameters';
|
our $doubleHashKeys = 'issuerDBGetParameters';
|
||||||
our $simpleHashKeys = '(?:(?:l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|c(?:as(?:StorageOption|Attribute)|ustom(?:Plugins|Add)Param|ombModule)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|(?:(?:d(?:emo|bi)|facebook|webID)E|e)xportedVar|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|macro)s|o(?:idcS(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|penIdExportedVars)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember|fExtra)|S(?:MTPTLSOpts|SLVarIf))';
|
our $simpleHashKeys = '(?:(?:c(?:as(?:StorageOption|Attribute)|ustom(?:Plugins|Add)Param|heckUserHiddenHeader|ombModule)|l(?:o(?:calSessionStorageOption|goutService)|dapExportedVar|wp(?:Ssl)?Opt)|re(?:moteGlobalStorageOption|st2f(?:Verify|Init)Arg|loadUrl)|(?:(?:d(?:emo|bi)|facebook|webID)E|e)xportedVar|g(?:r(?:antSessionRule|oup)|lobalStorageOption)|n(?:otificationStorageOption|ginxCustomHandler)|p(?:ersistentStorageOption|ortalSkinRule)|macro)s|o(?:idcS(?:ervice(?:DynamicRegistrationEx(?:portedVar|traClaim)s|MetaDataAuthnContext)|torageOptions)|penIdExportedVars)|a(?:(?:daptativeAuthenticationLevelR|ut(?:hChoiceMod|oSigninR))ules|pplicationList)|s(?:(?:amlStorageOption|laveExportedVar)s|essionDataToRemember|fExtra)|S(?:MTPTLSOpts|SLVarIf))';
|
||||||
our $specialNodeKeys = '(?:(?:(?:saml(?:ID|S)|oidc[OR])P|cas(?:App|Srv))MetaDataNode|virtualHost)s';
|
our $specialNodeKeys = '(?:(?:(?:saml(?:ID|S)|oidc[OR])P|cas(?:App|Srv))MetaDataNode|virtualHost)s';
|
||||||
our $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:(?:UserAttribut|Servic|Rul)e|AuthnLevel)|(?:ExportedVar|Macro)s)';
|
our $casAppMetaDataNodeKeys = 'casAppMetaData(?:Options(?:(?:UserAttribut|Servic|Rul)e|AuthnLevel)|(?:ExportedVar|Macro)s)';
|
||||||
our $casSrvMetaDataNodeKeys = 'casSrvMetaData(?:Options(?:ProxiedServices|DisplayName|SortNumber|Gateway|Renew|Icon|Url)|ExportedVars)';
|
our $casSrvMetaDataNodeKeys = 'casSrvMetaData(?:Options(?:ProxiedServices|DisplayName|SortNumber|Gateway|Renew|Icon|Url)|ExportedVars)';
|
||||||
|
@ -30,7 +30,7 @@ our $oidcOPMetaDataNodeKeys = 'oidcOPMetaData(?:Options(?:C(?:lient(?:Secret|ID)
|
||||||
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:A(?:uth(?:orizationCodeExpiration|nLevel)|llow(?:PasswordGrant|Offline)|ccessTokenExpiration|dditionalAudiences)|I(?:DToken(?:ForceClaims|Expiration|SignAlg)|con)|R(?:e(?:directUris|freshToken|quirePKCE)|ule)|Logout(?:SessionRequired|Type|Url)|P(?:ostLogoutRedirectUris|ublic)|OfflineSessionExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims|UserIDAttr)|(?:ExportedVar|Macro)s)';
|
our $oidcRPMetaDataNodeKeys = 'oidcRPMetaData(?:Options(?:A(?:uth(?:orizationCodeExpiration|nLevel)|llow(?:PasswordGrant|Offline)|ccessTokenExpiration|dditionalAudiences)|I(?:DToken(?:ForceClaims|Expiration|SignAlg)|con)|R(?:e(?:directUris|freshToken|quirePKCE)|ule)|Logout(?:SessionRequired|Type|Url)|P(?:ostLogoutRedirectUris|ublic)|OfflineSessionExpiration|Client(?:Secret|ID)|BypassConsent|DisplayName|ExtraClaims|UserIDAttr)|(?:ExportedVar|Macro)s)';
|
||||||
our $samlIDPMetaDataNodeKeys = 'samlIDPMetaData(?:Options(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|EncryptionMod|UserAttribut|DisplayNam)e|S(?:ign(?:S[LS]OMessage|atureMethod)|toreSAMLToken|[LS]OBinding|ortNumber)|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Re(?:questedAuthnContext|solutionRule|layStateURL)|Force(?:Authn|UTF8)|I(?:sPassive|con)|NameIDFormat)|ExportedAttributes|XML)';
|
our $samlIDPMetaDataNodeKeys = 'samlIDPMetaData(?:Options(?:(?:Check(?:S[LS]OMessageSignatur|Audienc|Tim)|EncryptionMod|UserAttribut|DisplayNam)e|S(?:ign(?:S[LS]OMessage|atureMethod)|toreSAMLToken|[LS]OBinding|ortNumber)|A(?:llow(?:LoginFromIDP|ProxiedAuthn)|daptSessionUtime)|Re(?:questedAuthnContext|solutionRule|layStateURL)|Force(?:Authn|UTF8)|I(?:sPassive|con)|NameIDFormat)|ExportedAttributes|XML)';
|
||||||
our $samlSPMetaDataNodeKeys = 'samlSPMetaData(?:Options(?:S(?:ign(?:S[LS]OMessage|atureMethod)|essionNotOnOrAfterTimeout)|N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|(?:CheckS[LS]OMessageSignatur|OneTimeUs|Rul)e|En(?:ableIDPInitiatedURL|cryptionMode)|AuthnLevel|ForceUTF8)|(?:ExportedAttribute|Macro)s|XML)';
|
our $samlSPMetaDataNodeKeys = 'samlSPMetaData(?:Options(?:S(?:ign(?:S[LS]OMessage|atureMethod)|essionNotOnOrAfterTimeout)|N(?:ameID(?:SessionKey|Format)|otOnOrAfterTimeout)|(?:CheckS[LS]OMessageSignatur|OneTimeUs|Rul)e|En(?:ableIDPInitiatedURL|cryptionMode)|AuthnLevel|ForceUTF8)|(?:ExportedAttribute|Macro)s|XML)';
|
||||||
our $virtualHostKeys = '(?:vhost(?:A(?:uthnLevel|liases)|(?:Maintenanc|Typ)e|ServiceTokenTTL|Https|Port)|(?:exportedHeader|locationRule)s|post)';
|
our $virtualHostKeys = '(?:vhost(?:A(?:ccessToTrace|uthnLevel|liases)|(?:Maintenanc|Typ)e|ServiceTokenTTL|Https|Port)|(?:exportedHeader|locationRule)s|post)';
|
||||||
|
|
||||||
our $authParameters = {
|
our $authParameters = {
|
||||||
adParams => [qw(ADPwdMaxAge ADPwdExpireWarning)],
|
adParams => [qw(ADPwdMaxAge ADPwdExpireWarning)],
|
||||||
|
|
|
@ -9,6 +9,7 @@ use strict;
|
||||||
use Encode;
|
use Encode;
|
||||||
use MIME::Base64;
|
use MIME::Base64;
|
||||||
use Lemonldap::NG::Common::IPv6;
|
use Lemonldap::NG::Common::IPv6;
|
||||||
|
use JSON::XS;
|
||||||
|
|
||||||
#use AutoLoader qw(AUTOLOAD);
|
#use AutoLoader qw(AUTOLOAD);
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ our $VERSION = '2.1.0';
|
||||||
# Not that only functions, not methods, can be written here
|
# Not that only functions, not methods, can be written here
|
||||||
our $functions =
|
our $functions =
|
||||||
[
|
[
|
||||||
qw(&checkLogonHours &date &checkDate &basic &unicode2iso &iso2unicode &groupMatch &isInNet6 &varIsInUri)
|
qw(&checkLogonHours &date &checkDate &basic &unicode2iso &iso2unicode &groupMatch &isInNet6 &varIsInUri &has2f)
|
||||||
];
|
];
|
||||||
|
|
||||||
## @function boolean checkLogonHours(string logon_hours, string syntax, string time_correction, boolean default_access)
|
## @function boolean checkLogonHours(string logon_hours, string syntax, string time_correction, boolean default_access)
|
||||||
|
@ -64,8 +65,8 @@ sub checkLogonHours {
|
||||||
# Use time_correction
|
# Use time_correction
|
||||||
if ($time_correction) {
|
if ($time_correction) {
|
||||||
my ( $sign, $time ) = ( $time_correction =~ /([+|-]?)(\d+)/ );
|
my ( $sign, $time ) = ( $time_correction =~ /([+|-]?)(\d+)/ );
|
||||||
if ( $sign =~ /-/ ) { $hourpos -= $time; }
|
if ( $sign =~ /-/ ) { $hourpos -= $time; }
|
||||||
else { $hourpos += $time; }
|
else { $hourpos += $time; }
|
||||||
}
|
}
|
||||||
|
|
||||||
# Get the corresponding byte
|
# Get the corresponding byte
|
||||||
|
@ -224,4 +225,26 @@ sub varIsInUri {
|
||||||
: $uri =~ /$wanteduri$attribute/o;
|
: $uri =~ /$wanteduri$attribute/o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $json = JSON::XS->new;
|
||||||
|
|
||||||
|
sub has2f {
|
||||||
|
my ( $session, $type ) = @_;
|
||||||
|
return 0 unless ( $session->{_2fDevices} );
|
||||||
|
|
||||||
|
my $_2fDevices = eval { $json->decode( $session->{_2fDevices} ); };
|
||||||
|
return 0 if ( $@ or ref($_2fDevices) ne "ARRAY" );
|
||||||
|
|
||||||
|
my $length = scalar @{$_2fDevices};
|
||||||
|
|
||||||
|
# Empty array
|
||||||
|
return 0 unless $length;
|
||||||
|
|
||||||
|
# Array has one value and we did not specify a type, succeed
|
||||||
|
if ($type) {
|
||||||
|
my @found = grep { lc( $_->{type} ) eq lc($type) } @{$_2fDevices};
|
||||||
|
return ( @found ? 1 : 0 );
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -19,8 +19,9 @@ sub verifyCode {
|
||||||
$self->logger->error('Bad characters in TOTP secret');
|
$self->logger->error('Bad characters in TOTP secret');
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
for ( 0 .. $range ) {
|
for ( -$range .. $range ) {
|
||||||
if ( $code eq $self->_code( $s, $_, $interval, $digits ) ) {
|
if ( $code eq $self->_code( $s, $_, $interval, $digits ) ) {
|
||||||
|
$self->userLogger->info("Codes match at range $_");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,7 @@ t/69-Lemonldap-NG-Handler-PSGI-SecureToken.t
|
||||||
t/70-Lemonldap-NG-Handler-PSGI-AuthBasic.t
|
t/70-Lemonldap-NG-Handler-PSGI-AuthBasic.t
|
||||||
t/71-Lemonldap-NG-Handler-PSGI-OAuth2.t
|
t/71-Lemonldap-NG-Handler-PSGI-OAuth2.t
|
||||||
t/99-pod.t
|
t/99-pod.t
|
||||||
|
t/custom.pm
|
||||||
t/lmConf-1.json
|
t/lmConf-1.json
|
||||||
t/sessions/lock/.exists
|
t/sessions/lock/.exists
|
||||||
t/test-psgi-lib.pm
|
t/test-psgi-lib.pm
|
||||||
|
|
|
@ -238,6 +238,8 @@ sub defaultValuesInit {
|
||||||
$conf->{vhostOptions}->{$vhost}->{vhostAuthnLevel};
|
$conf->{vhostOptions}->{$vhost}->{vhostAuthnLevel};
|
||||||
$class->tsv->{serviceTokenTTL}->{$vhost} =
|
$class->tsv->{serviceTokenTTL}->{$vhost} =
|
||||||
$conf->{vhostOptions}->{$vhost}->{vhostServiceTokenTTL};
|
$conf->{vhostOptions}->{$vhost}->{vhostServiceTokenTTL};
|
||||||
|
$class->tsv->{accessToTrace}->{$vhost} =
|
||||||
|
$conf->{vhostOptions}->{$vhost}->{vhostAccessToTrace};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -626,6 +628,9 @@ sub substitute {
|
||||||
# handle inGroup
|
# handle inGroup
|
||||||
$expr =~ s/\binGroup\(([^)]*)\)/listMatch(\$s->{'hGroups'},$1,1)/g;
|
$expr =~ s/\binGroup\(([^)]*)\)/listMatch(\$s->{'hGroups'},$1,1)/g;
|
||||||
|
|
||||||
|
# handle has2f
|
||||||
|
$expr =~ s/\bhas2f\(([^),]*)\)/has2f(\$s,$1)/g;
|
||||||
|
|
||||||
return $expr;
|
return $expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,7 @@ sub checkType {
|
||||||
sub run {
|
sub run {
|
||||||
my ( $class, $req, $rule, $protection ) = @_;
|
my ( $class, $req, $rule, $protection ) = @_;
|
||||||
my ( $id, $session );
|
my ( $id, $session );
|
||||||
|
my $vhost = $class->resolveAlias($req);
|
||||||
|
|
||||||
return $class->DECLINED unless ( $class->is_initial_req($req) );
|
return $class->DECLINED unless ( $class->is_initial_req($req) );
|
||||||
|
|
||||||
|
@ -149,9 +150,41 @@ sub run {
|
||||||
|
|
||||||
# ACCOUNTING (1. Inform web server)
|
# ACCOUNTING (1. Inform web server)
|
||||||
$class->set_user( $req, $session->{ $class->tsv->{whatToTrace} } );
|
$class->set_user( $req, $session->{ $class->tsv->{whatToTrace} } );
|
||||||
$class->set_custom( $req, $session->{ $class->tsv->{customToTrace} } )
|
|
||||||
if $class->tsv->{customToTrace}
|
my $custom;
|
||||||
and $session->{ $class->tsv->{customToTrace} };
|
$custom = $session->{ $class->tsv->{customToTrace} }
|
||||||
|
if ( $class->tsv->{customToTrace}
|
||||||
|
and $session->{ $class->tsv->{customToTrace} } );
|
||||||
|
if ( $class->tsv->{accessToTrace}->{$vhost} ) {
|
||||||
|
my ( $function, @params ) = split /\s*,\s*/,
|
||||||
|
$class->tsv->{accessToTrace}->{$vhost};
|
||||||
|
if ( $function =~ qr/^(?:\w+(?:::\w+)*(?:\s+\w+(?:::\w+)*)*)?$/ ) {
|
||||||
|
my $c = eval {
|
||||||
|
no strict 'refs';
|
||||||
|
&{$function}( {
|
||||||
|
req => $req,
|
||||||
|
vhost => $vhost,
|
||||||
|
session => $session,
|
||||||
|
custom => $custom,
|
||||||
|
params => \@params
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
if ($@) {
|
||||||
|
$class->logger->error(
|
||||||
|
"Failed to overwrite customToTrace: $@");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$class->logger->debug("Overwrite customToTrace with: $c");
|
||||||
|
$custom = $c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$class->logger->error(
|
||||||
|
"accessToTrace: Bad custom function name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$class->set_custom( $req, $custom ) if $custom;
|
||||||
|
|
||||||
# AUTHORIZATION
|
# AUTHORIZATION
|
||||||
return ( $class->forbidden( $req, $session ), $session )
|
return ( $class->forbidden( $req, $session ), $session )
|
||||||
|
@ -794,10 +827,14 @@ sub localUnlog {
|
||||||
if ( $id //= $class->fetchId($req) ) {
|
if ( $id //= $class->fetchId($req) ) {
|
||||||
|
|
||||||
# Delete local cache
|
# Delete local cache
|
||||||
if ( $class->tsv->{refLocalStorage}
|
if ( $class->tsv->{sessionCacheModule} ) {
|
||||||
and $class->tsv->{refLocalStorage}->get($id) )
|
my $module = $class->tsv->{sessionCacheModule};
|
||||||
{
|
my $options = $class->tsv->{sessionCacheOptions};
|
||||||
$class->tsv->{refLocalStorage}->remove($id);
|
eval "use $module;";
|
||||||
|
my $cache = $module->new($options);
|
||||||
|
if ( $cache->get($id) ) {
|
||||||
|
$cache->remove($id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# change 'tests => 1' to 'tests => last_test_to_print';
|
# change 'tests => 1' to 'tests => last_test_to_print';
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Test::More tests => 13;
|
use Test::More tests => 17;
|
||||||
require 't/test.pm';
|
require 't/test.pm';
|
||||||
BEGIN { use_ok('Lemonldap::NG::Handler::Main::Jail') }
|
BEGIN { use_ok('Lemonldap::NG::Handler::Main::Jail') }
|
||||||
|
|
||||||
|
@ -60,3 +60,39 @@ ok(
|
||||||
ok( $res = &$code, "Function works" );
|
ok( $res = &$code, "Function works" );
|
||||||
ok( $res == 1, 'Get good result' );
|
ok( $res == 1, 'Get good result' );
|
||||||
|
|
||||||
|
$sub = "sub { return(has2f(\$_[0],\$_[1])) }";
|
||||||
|
$code = $jail->jail_reval($sub);
|
||||||
|
ok(
|
||||||
|
( defined($code) and ref($code) eq 'CODE' ),
|
||||||
|
'checkDate extended function is defined'
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
$code->( {
|
||||||
|
_2fDevices =>
|
||||||
|
"[{\"name\":\"MyTOTP\",\"_secret\":\"g5fsxwf4d34biemlojsbbvhgtskrssos\",\"epoch\":1602173208,\"type\":\"TOTP\"}]"
|
||||||
|
},
|
||||||
|
"TOTP"
|
||||||
|
),
|
||||||
|
1,
|
||||||
|
"Function works"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
$code->( {
|
||||||
|
_2fDevices =>
|
||||||
|
"[{\"name\":\"MyTOTP\",\"_secret\":\"g5fsxwf4d34biemlojsbbvhgtskrssos\",\"epoch\":1602173208,\"type\":\"TOTP\"}]"
|
||||||
|
},
|
||||||
|
"UBK"
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
"Function works"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
$code->( {
|
||||||
|
_2fDevices =>
|
||||||
|
"[{\"name\":\"MyTOTP\",\"_secret\":\"g5fsxwf4d34biemlojsbbvhgtskrssos\",\"epoch\":1602173208,\"type\":\"TOTP\"}]"
|
||||||
|
},
|
||||||
|
),
|
||||||
|
1,
|
||||||
|
"Function works"
|
||||||
|
);
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
# change 'tests => 1' to 'tests => last_test_to_print';
|
# change 'tests => 1' to 'tests => last_test_to_print';
|
||||||
|
|
||||||
use Test::More tests => 9;
|
use Test::More tests => 13;
|
||||||
require 't/test.pm';
|
require 't/test.pm';
|
||||||
BEGIN { use_ok('Lemonldap::NG::Handler::Main::Jail') }
|
BEGIN { use_ok('Lemonldap::NG::Handler::Main::Jail') }
|
||||||
|
|
||||||
|
@ -54,3 +54,40 @@ $listMatch = $jail->jail_reval($sub5);
|
||||||
ok( ( defined($listMatch) and ref($listMatch) eq 'CODE' ),
|
ok( ( defined($listMatch) and ref($listMatch) eq 'CODE' ),
|
||||||
'listMatch function is defined' );
|
'listMatch function is defined' );
|
||||||
ok( &$listMatch eq '0', 'Get good result' );
|
ok( &$listMatch eq '0', 'Get good result' );
|
||||||
|
|
||||||
|
# Test has2f method
|
||||||
|
my $sub6 = "sub { return(has2f(\$_[0],\$_[1])) }";
|
||||||
|
my $has2f = $jail->jail_reval($sub6);
|
||||||
|
ok(
|
||||||
|
( defined($has2f) and ref($has2f) eq 'CODE' ),
|
||||||
|
'checkDate extended function is defined'
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
$has2f->( {
|
||||||
|
_2fDevices =>
|
||||||
|
"[{\"name\":\"MyTOTP\",\"_secret\":\"g5fsxwf4d34biemlojsbbvhgtskrssos\",\"epoch\":1602173208,\"type\":\"TOTP\"}]"
|
||||||
|
},
|
||||||
|
"TOTP"
|
||||||
|
),
|
||||||
|
1,
|
||||||
|
"Function works"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
$has2f->( {
|
||||||
|
_2fDevices =>
|
||||||
|
"[{\"name\":\"MyTOTP\",\"_secret\":\"g5fsxwf4d34biemlojsbbvhgtskrssos\",\"epoch\":1602173208,\"type\":\"TOTP\"}]"
|
||||||
|
},
|
||||||
|
),
|
||||||
|
1,
|
||||||
|
"Function works"
|
||||||
|
);
|
||||||
|
is(
|
||||||
|
$has2f->( {
|
||||||
|
_2fDevices =>
|
||||||
|
"[{\"name\":\"MyTOTP\",\"_secret\":\"g5fsxwf4d34biemlojsbbvhgtskrssos\",\"epoch\":1602173208,\"type\":\"TOTP\"}]"
|
||||||
|
},
|
||||||
|
"UBK"
|
||||||
|
),
|
||||||
|
0,
|
||||||
|
"Function works"
|
||||||
|
);
|
||||||
|
|
|
@ -4,7 +4,10 @@ use MIME::Base64;
|
||||||
use Data::Dumper;
|
use Data::Dumper;
|
||||||
use URI::Escape;
|
use URI::Escape;
|
||||||
|
|
||||||
require 't/test-psgi-lib.pm';
|
BEGIN {
|
||||||
|
require 't/test-psgi-lib.pm';
|
||||||
|
require 't/custom.pm';
|
||||||
|
}
|
||||||
|
|
||||||
init('Lemonldap::NG::Handler::Server::Nginx');
|
init('Lemonldap::NG::Handler::Server::Nginx');
|
||||||
|
|
||||||
|
@ -31,6 +34,28 @@ count(4);
|
||||||
# Authentified queries
|
# Authentified queries
|
||||||
# --------------------
|
# --------------------
|
||||||
|
|
||||||
|
# Authorized query
|
||||||
|
ok(
|
||||||
|
$res =
|
||||||
|
$client->_get( '/', undef, 'test4.example.com', "lemonldap=$sessionId" ),
|
||||||
|
'Authentified query'
|
||||||
|
);
|
||||||
|
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res->[0], 200 );
|
||||||
|
count(2);
|
||||||
|
|
||||||
|
# Check headers
|
||||||
|
%h = @{ $res->[1] };
|
||||||
|
ok(
|
||||||
|
$h{'Lm-Remote-Custom'} eq
|
||||||
|
'dwho@badwolf.org alias Doctor_Who:users; timelords by using Mozilla/5.0 (X11; VAX4000; rv:43.0) Gecko/20100101 Firefox/143.0 Iceweasel/143.0.1',
|
||||||
|
'Lm-Remote-Custom is overwriten'
|
||||||
|
)
|
||||||
|
or explain(
|
||||||
|
\%h,
|
||||||
|
'Lm-Remote-Custom => "dwho@badwolf.org alias Doctor_Who:users; timelords by using Mozilla/5.0 (X11; VAX4000; rv:43.0) Gecko/20100101 Firefox/143.0 Iceweasel/143.0.1"'
|
||||||
|
);
|
||||||
|
count(1);
|
||||||
|
|
||||||
# Authorized query
|
# Authorized query
|
||||||
ok( $res = $client->_get( '/', undef, undef, "lemonldap=$sessionId" ),
|
ok( $res = $client->_get( '/', undef, undef, "lemonldap=$sessionId" ),
|
||||||
'Authentified query' );
|
'Authentified query' );
|
||||||
|
@ -43,7 +68,11 @@ ok( $h{'Headername1'} eq 'Auth-User', 'Headername1 is set to "Auth-User"' )
|
||||||
or explain( \%h, 'Headername1 => "Auth-User"' );
|
or explain( \%h, 'Headername1 => "Auth-User"' );
|
||||||
ok( $h{'Headervalue1'} eq 'dwho', 'Headervalue1 is set to "dwho"' )
|
ok( $h{'Headervalue1'} eq 'dwho', 'Headervalue1 is set to "dwho"' )
|
||||||
or explain( \%h, 'Headervalue1 => "dwho"' );
|
or explain( \%h, 'Headervalue1 => "dwho"' );
|
||||||
count(2);
|
ok(
|
||||||
|
$h{'Lm-Remote-Custom'} eq 'dwho@badwolf.org',
|
||||||
|
'Lm-Remote-Custom is set "dwho@badwolf.org"'
|
||||||
|
) or explain( \%h, 'Lm-Remote-User => "dwho@badwolf.org"' );
|
||||||
|
count(3);
|
||||||
|
|
||||||
# Request an URI protected by custom function -> allowed
|
# Request an URI protected by custom function -> allowed
|
||||||
ok(
|
ok(
|
||||||
|
|
|
@ -4,6 +4,7 @@ use MIME::Base64;
|
||||||
|
|
||||||
BEGIN {
|
BEGIN {
|
||||||
require 't/test-psgi-lib.pm';
|
require 't/test-psgi-lib.pm';
|
||||||
|
require 't/custom.pm';
|
||||||
}
|
}
|
||||||
|
|
||||||
init('Lemonldap::NG::Handler::PSGI');
|
init('Lemonldap::NG::Handler::PSGI');
|
||||||
|
@ -39,7 +40,6 @@ ok(
|
||||||
'Authentified query'
|
'Authentified query'
|
||||||
);
|
);
|
||||||
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res, 200 );
|
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res, 200 );
|
||||||
|
|
||||||
count(2);
|
count(2);
|
||||||
|
|
||||||
# Denied query
|
# Denied query
|
||||||
|
@ -50,7 +50,6 @@ ok(
|
||||||
'Denied query'
|
'Denied query'
|
||||||
);
|
);
|
||||||
ok( $res->[0] == 403, 'Code is 403' ) or explain( $res->[0], 403 );
|
ok( $res->[0] == 403, 'Code is 403' ) or explain( $res->[0], 403 );
|
||||||
|
|
||||||
count(2);
|
count(2);
|
||||||
|
|
||||||
# Bad cookie
|
# Bad cookie
|
||||||
|
@ -67,11 +66,9 @@ ok( $res->[0] == 302, 'Code is 302' ) or explain( $res->[0], 302 );
|
||||||
unlink(
|
unlink(
|
||||||
't/sessions/lock/Apache-Session-e5eec18ebb9bc96352595e2d8ce962e8ecf7af7c9a98cb9a43f9cd181cf4b545.lock'
|
't/sessions/lock/Apache-Session-e5eec18ebb9bc96352595e2d8ce962e8ecf7af7c9a98cb9a43f9cd181cf4b545.lock'
|
||||||
);
|
);
|
||||||
|
|
||||||
count(2);
|
count(2);
|
||||||
|
|
||||||
done_testing( count() );
|
done_testing( count() );
|
||||||
|
|
||||||
clean();
|
clean();
|
||||||
|
|
||||||
sub Lemonldap::NG::Handler::PSGI::handler {
|
sub Lemonldap::NG::Handler::PSGI::handler {
|
||||||
|
|
16
lemonldap-ng-handler/t/custom.pm
Normal file
16
lemonldap-ng-handler/t/custom.pm
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
package My;
|
||||||
|
|
||||||
|
sub accessToTrace {
|
||||||
|
my $hash = shift;
|
||||||
|
my $custom = $hash->{custom};
|
||||||
|
my $req = $hash->{req};
|
||||||
|
my $vhost = $hash->{vhost};
|
||||||
|
my $custom = $hash->{custom};
|
||||||
|
my $params = $hash->{params};
|
||||||
|
my $session = $hash->{session};
|
||||||
|
|
||||||
|
return
|
||||||
|
"$custom alias $params->[0]_$params->[1]:$session->{groups} by using $session->{ $params->[2] }";
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
|
@ -59,6 +59,9 @@
|
||||||
"^/logout": "logout_sso",
|
"^/logout": "logout_sso",
|
||||||
"default": "accept"
|
"default": "accept"
|
||||||
},
|
},
|
||||||
|
"test4.example.com": {
|
||||||
|
"default": "accept"
|
||||||
|
},
|
||||||
"*.example.org": {
|
"*.example.org": {
|
||||||
"^/orgdeny": "deny",
|
"^/orgdeny": "deny",
|
||||||
"default": "accept"
|
"default": "accept"
|
||||||
|
@ -74,15 +77,20 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"macros": {
|
"macros": {
|
||||||
"_whatToTrace": "$_auth eq 'SAML' ? \"$_user\\@$_idpConfKey\" : \"$_user\""
|
"_whatToTrace": "$_auth eq 'SAML' ? \"$_user\\@$_idpConfKey\" : \"$_user\"",
|
||||||
|
"UA": "$ENV{HTTP_USER_AGENT}"
|
||||||
},
|
},
|
||||||
"portal": "http://auth.example.com/",
|
"portal": "http://auth.example.com/",
|
||||||
"reloadUrls": {},
|
"reloadUrls": {},
|
||||||
"userDB": "Demo",
|
"userDB": "Demo",
|
||||||
"vhostOptions": {
|
"vhostOptions": {
|
||||||
"test2.example.com": {
|
"test2.example.com": {
|
||||||
"vhostAuthnLevel": 5
|
"vhostAuthnLevel": 5
|
||||||
}
|
},
|
||||||
|
"test4.example.com": {
|
||||||
|
"vhostAccessToTrace": "My::accessToTrace, Doctor, Who, UA"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"whatToTrace": "_whatToTrace"
|
"whatToTrace": "_whatToTrace",
|
||||||
|
"customToTrace": "mail"
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,17 +196,20 @@ site/htdocs/static/js/viewer.min.js.map
|
||||||
site/htdocs/static/languages/ar.json
|
site/htdocs/static/languages/ar.json
|
||||||
site/htdocs/static/languages/de.json
|
site/htdocs/static/languages/de.json
|
||||||
site/htdocs/static/languages/en.json
|
site/htdocs/static/languages/en.json
|
||||||
|
site/htdocs/static/languages/es.json
|
||||||
site/htdocs/static/languages/fr.json
|
site/htdocs/static/languages/fr.json
|
||||||
site/htdocs/static/languages/it.json
|
site/htdocs/static/languages/it.json
|
||||||
site/htdocs/static/languages/pl.json
|
site/htdocs/static/languages/pl.json
|
||||||
site/htdocs/static/languages/tr.json
|
site/htdocs/static/languages/tr.json
|
||||||
site/htdocs/static/languages/vi.json
|
site/htdocs/static/languages/vi.json
|
||||||
site/htdocs/static/languages/zh.json
|
site/htdocs/static/languages/zh.json
|
||||||
|
site/htdocs/static/languages/zh_TW.json
|
||||||
site/htdocs/static/logos/ar.png
|
site/htdocs/static/logos/ar.png
|
||||||
site/htdocs/static/logos/bootstrap.png
|
site/htdocs/static/logos/bootstrap.png
|
||||||
site/htdocs/static/logos/custom.png
|
site/htdocs/static/logos/custom.png
|
||||||
site/htdocs/static/logos/de.png
|
site/htdocs/static/logos/de.png
|
||||||
site/htdocs/static/logos/en.png
|
site/htdocs/static/logos/en.png
|
||||||
|
site/htdocs/static/logos/es.png
|
||||||
site/htdocs/static/logos/favicon.ico
|
site/htdocs/static/logos/favicon.ico
|
||||||
site/htdocs/static/logos/fr.png
|
site/htdocs/static/logos/fr.png
|
||||||
site/htdocs/static/logos/it.png
|
site/htdocs/static/logos/it.png
|
||||||
|
@ -216,6 +219,7 @@ site/htdocs/static/logos/pl.png
|
||||||
site/htdocs/static/logos/tr.png
|
site/htdocs/static/logos/tr.png
|
||||||
site/htdocs/static/logos/vi.png
|
site/htdocs/static/logos/vi.png
|
||||||
site/htdocs/static/logos/zh.png
|
site/htdocs/static/logos/zh.png
|
||||||
|
site/htdocs/static/logos/zh_TW.png
|
||||||
site/htdocs/static/reverseTree.json
|
site/htdocs/static/reverseTree.json
|
||||||
site/htdocs/static/struct.json
|
site/htdocs/static/struct.json
|
||||||
site/templates/2ndfa.tpl
|
site/templates/2ndfa.tpl
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
# Sessions.pm to manage sessions
|
# Sessions.pm to manage sessions
|
||||||
package Lemonldap::NG::Manager;
|
package Lemonldap::NG::Manager;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use JSON;
|
use JSON;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package Lemonldap::NG::Manager::2ndFA;
|
package Lemonldap::NG::Manager::2ndFA;
|
||||||
|
|
||||||
use 5.10.0;
|
|
||||||
use utf8;
|
use utf8;
|
||||||
use strict;
|
use strict;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
|
@ -12,9 +11,11 @@ use Lemonldap::NG::Common::Conf::ReConstants;
|
||||||
|
|
||||||
use feature 'state';
|
use feature 'state';
|
||||||
|
|
||||||
extends 'Lemonldap::NG::Manager::Plugin',
|
extends qw(
|
||||||
'Lemonldap::NG::Common::Conf::AccessLib',
|
Lemonldap::NG::Manager::Plugin
|
||||||
'Lemonldap::NG::Common::Session::REST';
|
Lemonldap::NG::Common::Session::REST
|
||||||
|
Lemonldap::NG::Common::Conf::AccessLib
|
||||||
|
);
|
||||||
|
|
||||||
our $VERSION = '2.1.0';
|
our $VERSION = '2.1.0';
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
# This module implements all the methods that responds to '/api/*' requests
|
# This module implements all the methods that responds to '/api/*' requests
|
||||||
package Lemonldap::NG::Manager::Api;
|
package Lemonldap::NG::Manager::Api;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
|
|
||||||
extends 'Lemonldap::NG::Manager::Plugin',
|
extends qw(
|
||||||
'Lemonldap::NG::Common::Conf::RESTServer',
|
Lemonldap::NG::Manager::Plugin
|
||||||
'Lemonldap::NG::Common::Session::REST';
|
Lemonldap::NG::Common::Session::REST
|
||||||
|
Lemonldap::NG::Common::Conf::RESTServer
|
||||||
|
);
|
||||||
|
|
||||||
use Lemonldap::NG::Manager::Api::2F;
|
use Lemonldap::NG::Manager::Api::2F;
|
||||||
use Lemonldap::NG::Manager::Api::Misc;
|
use Lemonldap::NG::Manager::Api::Misc;
|
||||||
|
|
|
@ -4,7 +4,7 @@ our $VERSION = '2.1.0';
|
||||||
|
|
||||||
package Lemonldap::NG::Manager::Api;
|
package Lemonldap::NG::Manager::Api;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use JSON;
|
use JSON;
|
||||||
|
|
|
@ -4,6 +4,7 @@ our $VERSION = '2.1.0';
|
||||||
|
|
||||||
package Lemonldap::NG::Manager::Api;
|
package Lemonldap::NG::Manager::Api;
|
||||||
|
|
||||||
|
use strict;
|
||||||
use Lemonldap::NG::Manager::Build::Attributes;
|
use Lemonldap::NG::Manager::Build::Attributes;
|
||||||
use Lemonldap::NG::Manager::Build::CTrees;
|
use Lemonldap::NG::Manager::Build::CTrees;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ sub _getDefaultValues {
|
||||||
my $defaultAttrs = Lemonldap::NG::Manager::Build::Attributes::attributes();
|
my $defaultAttrs = Lemonldap::NG::Manager::Build::Attributes::attributes();
|
||||||
my $attrs = {};
|
my $attrs = {};
|
||||||
|
|
||||||
foreach $attr (@allAttrs) {
|
foreach my $attr (@allAttrs) {
|
||||||
$attrs->{$attr} = $defaultAttrs->{$attr}->{default}
|
$attrs->{$attr} = $defaultAttrs->{$attr}->{default}
|
||||||
if ( defined $defaultAttrs->{$attr}
|
if ( defined $defaultAttrs->{$attr}
|
||||||
&& defined $defaultAttrs->{$attr}->{default} );
|
&& defined $defaultAttrs->{$attr}->{default} );
|
||||||
|
@ -39,7 +40,7 @@ sub _hasAllowedAttributes {
|
||||||
my ( $self, $attributes, $rootNode ) = @_;
|
my ( $self, $attributes, $rootNode ) = @_;
|
||||||
my @allowedAttributes = $self->_listAttributes($rootNode);
|
my @allowedAttributes = $self->_listAttributes($rootNode);
|
||||||
|
|
||||||
foreach $attribute ( keys %{$attributes} ) {
|
foreach my $attribute ( keys %{$attributes} ) {
|
||||||
if ( length( ref($attribute) ) ) {
|
if ( length( ref($attribute) ) ) {
|
||||||
return {
|
return {
|
||||||
res => "ko",
|
res => "ko",
|
||||||
|
|
|
@ -4,11 +4,10 @@ our $VERSION = '2.1.0';
|
||||||
|
|
||||||
package Lemonldap::NG::Manager::Api;
|
package Lemonldap::NG::Manager::Api;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use Lemonldap::NG::Manager::Conf::Parser;
|
use Lemonldap::NG::Manager::Conf::Parser;
|
||||||
use Data::Dumper;
|
|
||||||
|
|
||||||
extends 'Lemonldap::NG::Manager::Api::Common';
|
extends 'Lemonldap::NG::Manager::Api::Common';
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ our $VERSION = '2.1.0';
|
||||||
|
|
||||||
package Lemonldap::NG::Manager::Api;
|
package Lemonldap::NG::Manager::Api;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use Lemonldap::NG::Manager::Conf::Parser;
|
use Lemonldap::NG::Manager::Conf::Parser;
|
||||||
|
|
|
@ -5,6 +5,7 @@ our $VERSION = '2.1.0';
|
||||||
|
|
||||||
package Lemonldap::NG::Manager::Api;
|
package Lemonldap::NG::Manager::Api;
|
||||||
|
|
||||||
|
use strict;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
extends 'Lemonldap::NG::Manager::Api::Common';
|
extends 'Lemonldap::NG::Manager::Api::Common';
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ our $VERSION = '2.1.0';
|
||||||
|
|
||||||
package Lemonldap::NG::Manager::Api;
|
package Lemonldap::NG::Manager::Api;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use Lemonldap::NG::Manager::Conf::Parser;
|
use Lemonldap::NG::Manager::Conf::Parser;
|
||||||
|
|
|
@ -4,7 +4,7 @@ our $VERSION = '2.1.0';
|
||||||
|
|
||||||
package Lemonldap::NG::Manager::Api;
|
package Lemonldap::NG::Manager::Api;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use Lemonldap::NG::Manager::Conf::Parser;
|
use Lemonldap::NG::Manager::Conf::Parser;
|
||||||
|
|
|
@ -4,7 +4,7 @@ our $VERSION = '2.1.0';
|
||||||
|
|
||||||
package Lemonldap::NG::Manager::Api;
|
package Lemonldap::NG::Manager::Api;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
|
|
||||||
|
|
|
@ -22,10 +22,9 @@ sub perlExpr {
|
||||||
grep( { $_ =~ /(?:Undefined subroutine|Devel::StackTrace)/ ? () : $_; }
|
grep( { $_ =~ /(?:Undefined subroutine|Devel::StackTrace)/ ? () : $_; }
|
||||||
split( /\n/, $@, 0 ) )
|
split( /\n/, $@, 0 ) )
|
||||||
);
|
);
|
||||||
return -1, "__badExpression__: $err" if $err;
|
return -1, "__badExpression__: $err" if $err and $conf->{'useSafeJail'};
|
||||||
return $val =~ qr/(?<=[^=<!>\|\?])=(?![=~])/
|
return $val =~ qr/(?<=[^=<!>\|\?])=(?![=~])/
|
||||||
? ( -1, '__badExpressionAssignment__' )
|
&& $conf->{'avoidAssignment'} ? ( 1, '__badExpressionAssignment__' ) : 1;
|
||||||
: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub types {
|
sub types {
|
||||||
|
@ -642,6 +641,10 @@ sub attributes {
|
||||||
'default' => 'TOTP,U2F,Yubikey',
|
'default' => 'TOTP,U2F,Yubikey',
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
|
'avoidAssignment' => {
|
||||||
|
'default' => 0,
|
||||||
|
'type' => 'bool'
|
||||||
|
},
|
||||||
'browsersDontStorePassword' => {
|
'browsersDontStorePassword' => {
|
||||||
'default' => 0,
|
'default' => 0,
|
||||||
'type' => 'bool'
|
'type' => 'bool'
|
||||||
|
@ -891,6 +894,18 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
|
||||||
'default' => '_loginHistory _session_id hGroups',
|
'default' => '_loginHistory _session_id hGroups',
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
|
'checkUserHiddenHeaders' => {
|
||||||
|
'keyMsgFail' => '__badHostname__',
|
||||||
|
'keyTest' => qr/^\S+$/,
|
||||||
|
'test' => {
|
||||||
|
'keyMsgFail' => '__badHeaderName__',
|
||||||
|
'keyTest' => qr/^(?=[^\-])[\w\-\s]+(?<=[^-])$/,
|
||||||
|
'test' => sub {
|
||||||
|
return perlExpr(@_);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'type' => 'keyTextContainer'
|
||||||
|
},
|
||||||
'checkUserIdRule' => {
|
'checkUserIdRule' => {
|
||||||
'default' => 1,
|
'default' => 1,
|
||||||
'test' => sub {
|
'test' => sub {
|
||||||
|
@ -1906,6 +1921,9 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
|
||||||
'mail2fLogo' => {
|
'mail2fLogo' => {
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
|
'mail2fSessionKey' => {
|
||||||
|
'type' => 'text'
|
||||||
|
},
|
||||||
'mail2fSubject' => {
|
'mail2fSubject' => {
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
|
@ -4144,6 +4162,10 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
|
||||||
'utotp2fLogo' => {
|
'utotp2fLogo' => {
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
},
|
},
|
||||||
|
'vhostAccessToTrace' => {
|
||||||
|
'default' => '',
|
||||||
|
'type' => 'text'
|
||||||
|
},
|
||||||
'vhostAliases' => {
|
'vhostAliases' => {
|
||||||
'default' => '',
|
'default' => '',
|
||||||
'type' => 'text'
|
'type' => 'text'
|
||||||
|
|
|
@ -27,9 +27,10 @@ sub perlExpr {
|
||||||
my $err = join( '',
|
my $err = join( '',
|
||||||
grep { $_ =~ /(?:Undefined subroutine|Devel::StackTrace)/ ? () : $_ }
|
grep { $_ =~ /(?:Undefined subroutine|Devel::StackTrace)/ ? () : $_ }
|
||||||
split( /\n/, $@ ) );
|
split( /\n/, $@ ) );
|
||||||
return ( -1, "__badExpression__: $err" ) if $err;
|
return ( -1, "__badExpression__: $err" )
|
||||||
return $val =~ qr/(?<=[^=<!>\|\?])=(?![=~])/
|
if ( $err && $conf->{useSafeJail} );
|
||||||
? ( -1, "__badExpressionAssignment__" )
|
return ( $val =~ qr/(?<=[^=<!>\|\?])=(?![=~])/ && $conf->{avoidAssignment} )
|
||||||
|
? ( 1, "__badExpressionAssignment__" )
|
||||||
: 1;
|
: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,6 +517,17 @@ sub attributes {
|
||||||
documentation => 'Display empty headers rule',
|
documentation => 'Display empty headers rule',
|
||||||
flags => 'p',
|
flags => 'p',
|
||||||
},
|
},
|
||||||
|
checkUserHiddenHeaders => {
|
||||||
|
type => 'keyTextContainer',
|
||||||
|
keyTest => qr/^\S+$/,
|
||||||
|
keyMsgFail => '__badHostname__',
|
||||||
|
test => {
|
||||||
|
keyTest => qr/^(?=[^\-])[\w\-\s]+(?<=[^-])$/,
|
||||||
|
keyMsgFail => '__badHeaderName__',
|
||||||
|
test => sub { return perlExpr(@_) },
|
||||||
|
},
|
||||||
|
documentation => 'Header values to hide if not empty',
|
||||||
|
},
|
||||||
globalLogoutRule => {
|
globalLogoutRule => {
|
||||||
type => 'boolOrExpr',
|
type => 'boolOrExpr',
|
||||||
default => 0,
|
default => 0,
|
||||||
|
@ -1062,6 +1074,13 @@ sub attributes {
|
||||||
documentation => 'Activate Safe jail',
|
documentation => 'Activate Safe jail',
|
||||||
flags => 'hp',
|
flags => 'hp',
|
||||||
},
|
},
|
||||||
|
avoidAssignment => {
|
||||||
|
default => 0,
|
||||||
|
type => 'bool',
|
||||||
|
help => 'safejail.html',
|
||||||
|
documentation => 'Avoid assignment in expressions',
|
||||||
|
flags => 'hp',
|
||||||
|
},
|
||||||
whatToTrace => {
|
whatToTrace => {
|
||||||
type => 'lmAttrOrMacro',
|
type => 'lmAttrOrMacro',
|
||||||
default => 'uid',
|
default => 'uid',
|
||||||
|
@ -1878,6 +1897,10 @@ sub attributes {
|
||||||
type => 'text',
|
type => 'text',
|
||||||
documentation => 'Custom logo for Mail 2F',
|
documentation => 'Custom logo for Mail 2F',
|
||||||
},
|
},
|
||||||
|
mail2fSessionKey => {
|
||||||
|
type => 'text',
|
||||||
|
documentation => 'Session parameter where mail is stored',
|
||||||
|
},
|
||||||
|
|
||||||
# External second factor
|
# External second factor
|
||||||
ext2fActivation => {
|
ext2fActivation => {
|
||||||
|
@ -2239,8 +2262,9 @@ sub attributes {
|
||||||
type => 'int',
|
type => 'int',
|
||||||
default => -1,
|
default => -1,
|
||||||
},
|
},
|
||||||
vhostAliases => { type => 'text', default => '' },
|
vhostAccessToTrace => { type => 'text', default => '' },
|
||||||
vhostType => {
|
vhostAliases => { type => 'text', default => '' },
|
||||||
|
vhostType => {
|
||||||
type => 'select',
|
type => 'select',
|
||||||
select => [
|
select => [
|
||||||
{ k => 'AuthBasic', v => 'AuthBasic' },
|
{ k => 'AuthBasic', v => 'AuthBasic' },
|
||||||
|
|
|
@ -27,10 +27,10 @@ sub cTrees {
|
||||||
help => 'configvhost.html#options',
|
help => 'configvhost.html#options',
|
||||||
form => 'simpleInputContainer',
|
form => 'simpleInputContainer',
|
||||||
nodes => [
|
nodes => [
|
||||||
'vhostPort', 'vhostHttps',
|
'vhostPort', 'vhostHttps',
|
||||||
'vhostMaintenance', 'vhostAliases',
|
'vhostMaintenance', 'vhostAliases',
|
||||||
'vhostType', 'vhostAuthnLevel',
|
'vhostAccessToTrace', 'vhostType',
|
||||||
'vhostServiceTokenTTL'
|
'vhostAuthnLevel', 'vhostServiceTokenTTL'
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -271,7 +271,7 @@ sub tree {
|
||||||
'managerDn', 'managerPassword',
|
'managerDn', 'managerPassword',
|
||||||
'ldapTimeout', 'ldapIOTimeout',
|
'ldapTimeout', 'ldapIOTimeout',
|
||||||
'ldapVersion', 'ldapRaw',
|
'ldapVersion', 'ldapRaw',
|
||||||
'ldapCAFile', 'ldapCAPath',
|
'ldapCAFile', 'ldapCAPath',
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -553,10 +553,8 @@ sub tree {
|
||||||
title => 'logParams',
|
title => 'logParams',
|
||||||
help => 'logs.html',
|
help => 'logs.html',
|
||||||
form => 'simpleInputContainer',
|
form => 'simpleInputContainer',
|
||||||
nodes => [
|
nodes =>
|
||||||
'whatToTrace', 'customToTrace',
|
[ 'whatToTrace', 'customToTrace', 'hiddenAttributes' ]
|
||||||
'hiddenAttributes'
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title => 'cookieParams',
|
title => 'cookieParams',
|
||||||
|
@ -772,7 +770,6 @@ sub tree {
|
||||||
{
|
{
|
||||||
title => 'checkUsers',
|
title => 'checkUsers',
|
||||||
help => 'checkuser.html',
|
help => 'checkuser.html',
|
||||||
form => 'simpleInputContainer',
|
|
||||||
nodes => [
|
nodes => [
|
||||||
'checkUser',
|
'checkUser',
|
||||||
'checkUserIdRule',
|
'checkUserIdRule',
|
||||||
|
@ -783,6 +780,7 @@ sub tree {
|
||||||
'checkUserDisplayEmptyHeaders',
|
'checkUserDisplayEmptyHeaders',
|
||||||
'checkUserDisplayEmptyValues',
|
'checkUserDisplayEmptyValues',
|
||||||
'checkUserDisplayPersistentInfo',
|
'checkUserDisplayPersistentInfo',
|
||||||
|
'checkUserHiddenHeaders'
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -900,6 +898,7 @@ sub tree {
|
||||||
'mail2fTimeout', 'mail2fSubject',
|
'mail2fTimeout', 'mail2fSubject',
|
||||||
'mail2fBody', 'mail2fAuthnLevel',
|
'mail2fBody', 'mail2fAuthnLevel',
|
||||||
'mail2fLabel', 'mail2fLogo',
|
'mail2fLabel', 'mail2fLogo',
|
||||||
|
'mail2fSessionKey',
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -991,6 +990,7 @@ sub tree {
|
||||||
'key',
|
'key',
|
||||||
'trustedDomains',
|
'trustedDomains',
|
||||||
'useSafeJail',
|
'useSafeJail',
|
||||||
|
'avoidAssignment',
|
||||||
'checkXSS',
|
'checkXSS',
|
||||||
'requireToken',
|
'requireToken',
|
||||||
'formTimeout',
|
'formTimeout',
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
# Read methods are inherited from Lemonldap::NG::Common::Conf::RESTServer
|
# Read methods are inherited from Lemonldap::NG::Common::Conf::RESTServer
|
||||||
package Lemonldap::NG::Manager::Conf;
|
package Lemonldap::NG::Manager::Conf;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use Lemonldap::NG::Common::Conf::Constants;
|
use Lemonldap::NG::Common::Conf::Constants;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package Lemonldap::NG::Manager::Conf::Tests;
|
package Lemonldap::NG::Manager::Conf::Tests;
|
||||||
|
|
||||||
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Lemonldap::NG::Common::Regexp;
|
use Lemonldap::NG::Common::Regexp;
|
||||||
use Lemonldap::NG::Handler::Main;
|
use Lemonldap::NG::Handler::Main;
|
||||||
|
@ -449,7 +450,7 @@ sub tests {
|
||||||
"RSA_SHA1" )
|
"RSA_SHA1" )
|
||||||
{
|
{
|
||||||
undef $allsha1;
|
undef $allsha1;
|
||||||
break;
|
last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -461,7 +462,7 @@ sub tests {
|
||||||
->{samlSPMetaDataOptionsSignatureMethod} ne "RSA_SHA1" )
|
->{samlSPMetaDataOptionsSignatureMethod} ne "RSA_SHA1" )
|
||||||
{
|
{
|
||||||
undef $allsha1;
|
undef $allsha1;
|
||||||
break;
|
last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -865,8 +866,7 @@ sub tests {
|
||||||
$appUrl =~ m#^(https?://[^/]+)(/.*)?$#;
|
$appUrl =~ m#^(https?://[^/]+)(/.*)?$#;
|
||||||
my $appHost = $1;
|
my $appHost = $1;
|
||||||
unless ($appHost) {
|
unless ($appHost) {
|
||||||
push @msg,
|
push @msg, "$casConfKey CAS Application has no Service URL";
|
||||||
"$clientConfKey CAS Application has no Service URL";
|
|
||||||
$res = 0;
|
$res = 0;
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package Lemonldap::NG::Manager::Notifications;
|
package Lemonldap::NG::Manager::Notifications;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use JSON qw(from_json to_json);
|
use JSON qw(from_json to_json);
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package Lemonldap::NG::Manager::Sessions;
|
package Lemonldap::NG::Manager::Sessions;
|
||||||
|
|
||||||
use 5.10.0;
|
|
||||||
use utf8;
|
use utf8;
|
||||||
use strict;
|
use strict;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package Lemonldap::NG::Manager::Viewer;
|
package Lemonldap::NG::Manager::Viewer;
|
||||||
|
|
||||||
use 5.10.0;
|
use strict;
|
||||||
use utf8;
|
use utf8;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use Lemonldap::NG::Common::Conf::Constants;
|
use Lemonldap::NG::Common::Conf::Constants;
|
||||||
|
|
|
@ -577,7 +577,9 @@ llapp.controller 'TreeCtrl', [
|
||||||
d = $q.defer()
|
d = $q.defer()
|
||||||
d.notify 'Trying to get datas'
|
d.notify 'Trying to get datas'
|
||||||
$scope.waiting = true
|
$scope.waiting = true
|
||||||
$http.get("#{window.confPrefix}#{$scope.currentCfg.cfgNum}/#{node.cnodes}").then (response) ->
|
console.log "Trying to get key #{node.cnodes}"
|
||||||
|
uri = encodeURI node.cnodes
|
||||||
|
$http.get("#{window.confPrefix}#{$scope.currentCfg.cfgNum}/#{uri}").then (response) ->
|
||||||
data = response.data
|
data = response.data
|
||||||
# Manage datas errors
|
# Manage datas errors
|
||||||
if not data
|
if not data
|
||||||
|
@ -759,7 +761,13 @@ llapp.controller 'TreeCtrl', [
|
||||||
d.reject response.statusLine
|
d.reject response.statusLine
|
||||||
$scope.waiting = false
|
$scope.waiting = false
|
||||||
else
|
else
|
||||||
$http.get("#{window.confPrefix}#{$scope.currentCfg.cfgNum}/#{if node.get then node.get else node.title}").then (response) ->
|
uri = ''
|
||||||
|
if node.get
|
||||||
|
console.log "Trying to get key #{node.get}"
|
||||||
|
uri = encodeURI node.get
|
||||||
|
else
|
||||||
|
console.log "Trying to get title #{node.title}"
|
||||||
|
$http.get("#{window.confPrefix}#{$scope.currentCfg.cfgNum}/#{if node.get then uri else node.title}").then (response) ->
|
||||||
# Set default value if response is null or if asked by server
|
# Set default value if response is null or if asked by server
|
||||||
data = response.data
|
data = response.data
|
||||||
if (data.value == null or (data.error and data.error.match /setDefault$/ ) ) and node['default'] != null
|
if (data.value == null or (data.error and data.error.match /setDefault$/ ) ) and node['default'] != null
|
||||||
|
|
|
@ -258,7 +258,9 @@ llapp.controller 'TreeCtrl', [
|
||||||
d = $q.defer()
|
d = $q.defer()
|
||||||
d.notify 'Trying to get datas'
|
d.notify 'Trying to get datas'
|
||||||
$scope.waiting = true
|
$scope.waiting = true
|
||||||
$http.get("#{window.viewPrefix}#{$scope.currentCfg.cfgNum}/#{node.cnodes}").then (response) ->
|
console.log "Trying to get key #{node.cnodes}"
|
||||||
|
uri = encodeURI node.cnodes
|
||||||
|
$http.get("#{window.confPrefix}#{$scope.currentCfg.cfgNum}/#{uri}").then (response) ->
|
||||||
data = response.data
|
data = response.data
|
||||||
# Manage datas errors
|
# Manage datas errors
|
||||||
if not data
|
if not data
|
||||||
|
@ -360,7 +362,13 @@ llapp.controller 'TreeCtrl', [
|
||||||
d.reject response.statusLine
|
d.reject response.statusLine
|
||||||
$scope.waiting = false
|
$scope.waiting = false
|
||||||
else
|
else
|
||||||
$http.get("#{window.viewPrefix}#{$scope.currentCfg.cfgNum}/#{if node.get then node.get else node.title}").then (response) ->
|
uri = ''
|
||||||
|
if node.get
|
||||||
|
console.log "Trying to get key #{node.get}"
|
||||||
|
uri = encodeURI node.get
|
||||||
|
else
|
||||||
|
console.log "Trying to get title #{node.title}"
|
||||||
|
$http.get("#{window.confPrefix}#{$scope.currentCfg.cfgNum}/#{if node.get then uri else node.title}").then (response) ->
|
||||||
# Set default value if response is null or if asked by server
|
# Set default value if response is null or if asked by server
|
||||||
data = response.data
|
data = response.data
|
||||||
if (data.value == null or (data.error and data.error.match /setDefault$/ ) ) and node['default'] != null
|
if (data.value == null or (data.error and data.error.match /setDefault$/ ) ) and node['default'] != null
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1327,6 +1327,12 @@ function templates(tpl,key) {
|
||||||
"id" : tpl+"s/"+key+"/"+"vhostAliases",
|
"id" : tpl+"s/"+key+"/"+"vhostAliases",
|
||||||
"title" : "vhostAliases"
|
"title" : "vhostAliases"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"default" : "",
|
||||||
|
"get" : tpl+"s/"+key+"/"+"vhostAccessToTrace",
|
||||||
|
"id" : tpl+"s/"+key+"/"+"vhostAccessToTrace",
|
||||||
|
"title" : "vhostAccessToTrace"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"default" : "Main",
|
"default" : "Main",
|
||||||
"get" : tpl+"s/"+key+"/"+"vhostType",
|
"get" : tpl+"s/"+key+"/"+"vhostType",
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -718,11 +718,13 @@ This file contains:
|
||||||
return _download(node);
|
return _download(node);
|
||||||
};
|
};
|
||||||
_download = function(node) {
|
_download = function(node) {
|
||||||
var d;
|
var d, uri;
|
||||||
d = $q.defer();
|
d = $q.defer();
|
||||||
d.notify('Trying to get datas');
|
d.notify('Trying to get datas');
|
||||||
$scope.waiting = true;
|
$scope.waiting = true;
|
||||||
$http.get("" + window.confPrefix + $scope.currentCfg.cfgNum + "/" + node.cnodes).then(function(response) {
|
console.log("Trying to get key " + node.cnodes);
|
||||||
|
uri = encodeURI(node.cnodes);
|
||||||
|
$http.get("" + window.confPrefix + $scope.currentCfg.cfgNum + "/" + uri).then(function(response) {
|
||||||
var a, data, len, o;
|
var a, data, len, o;
|
||||||
data = response.data;
|
data = response.data;
|
||||||
if (!data) {
|
if (!data) {
|
||||||
|
@ -900,7 +902,7 @@ This file contains:
|
||||||
}, readError);
|
}, readError);
|
||||||
};
|
};
|
||||||
$scope.getKey = function(node) {
|
$scope.getKey = function(node) {
|
||||||
var d, i, len, n, o, ref, tmp;
|
var d, i, len, n, o, ref, tmp, uri;
|
||||||
d = $q.defer();
|
d = $q.defer();
|
||||||
if (!node.data) {
|
if (!node.data) {
|
||||||
$scope.waiting = true;
|
$scope.waiting = true;
|
||||||
|
@ -923,7 +925,14 @@ This file contains:
|
||||||
return $scope.waiting = false;
|
return $scope.waiting = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
$http.get("" + window.confPrefix + $scope.currentCfg.cfgNum + "/" + (node.get ? node.get : node.title)).then(function(response) {
|
uri = '';
|
||||||
|
if (node.get) {
|
||||||
|
console.log("Trying to get key " + node.get);
|
||||||
|
uri = encodeURI(node.get);
|
||||||
|
} else {
|
||||||
|
console.log("Trying to get title " + node.title);
|
||||||
|
}
|
||||||
|
$http.get("" + window.confPrefix + $scope.currentCfg.cfgNum + "/" + (node.get ? uri : node.title)).then(function(response) {
|
||||||
var data;
|
var data;
|
||||||
data = response.data;
|
data = response.data;
|
||||||
if ((data.value === null || (data.error && data.error.match(/setDefault$/))) && node['default'] !== null) {
|
if ((data.value === null || (data.error && data.error.match(/setDefault$/))) && node['default'] !== null) {
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
||||||
// Generated by CoffeeScript 1.12.7
|
// Generated by CoffeeScript 1.12.8
|
||||||
|
|
||||||
/*
|
/*
|
||||||
LemonLDAP::NG Viewer client
|
LemonLDAP::NG Viewer client
|
||||||
|
@ -328,11 +328,13 @@ This file contains:
|
||||||
return _download(node);
|
return _download(node);
|
||||||
};
|
};
|
||||||
_download = function(node) {
|
_download = function(node) {
|
||||||
var d;
|
var d, uri;
|
||||||
d = $q.defer();
|
d = $q.defer();
|
||||||
d.notify('Trying to get datas');
|
d.notify('Trying to get datas');
|
||||||
$scope.waiting = true;
|
$scope.waiting = true;
|
||||||
$http.get("" + window.viewPrefix + $scope.currentCfg.cfgNum + "/" + node.cnodes).then(function(response) {
|
console.log("Trying to get key " + node.cnodes);
|
||||||
|
uri = encodeURI(node.cnodes);
|
||||||
|
$http.get("" + window.confPrefix + $scope.currentCfg.cfgNum + "/" + uri).then(function(response) {
|
||||||
var a, data, l, len;
|
var a, data, l, len;
|
||||||
data = response.data;
|
data = response.data;
|
||||||
if (!data) {
|
if (!data) {
|
||||||
|
@ -420,7 +422,7 @@ This file contains:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
$scope.getKey = function(node) {
|
$scope.getKey = function(node) {
|
||||||
var d, i, l, len, n, ref, tmp;
|
var d, i, l, len, n, ref, tmp, uri;
|
||||||
d = $q.defer();
|
d = $q.defer();
|
||||||
if (!node.data) {
|
if (!node.data) {
|
||||||
$scope.waiting = true;
|
$scope.waiting = true;
|
||||||
|
@ -443,7 +445,14 @@ This file contains:
|
||||||
return $scope.waiting = false;
|
return $scope.waiting = false;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
$http.get("" + window.viewPrefix + $scope.currentCfg.cfgNum + "/" + (node.get ? node.get : node.title)).then(function(response) {
|
uri = '';
|
||||||
|
if (node.get) {
|
||||||
|
console.log("Trying to get key " + node.get);
|
||||||
|
uri = encodeURI(node.get);
|
||||||
|
} else {
|
||||||
|
console.log("Trying to get title " + node.title);
|
||||||
|
}
|
||||||
|
$http.get("" + window.confPrefix + $scope.currentCfg.cfgNum + "/" + (node.get ? uri : node.title)).then(function(response) {
|
||||||
var data;
|
var data;
|
||||||
data = response.data;
|
data = response.data;
|
||||||
if ((data.value === null || (data.error && data.error.match(/setDefault$/))) && node['default'] !== null) {
|
if ((data.value === null || (data.error && data.error.match(/setDefault$/))) && node['default'] !== null) {
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -75,6 +75,7 @@
|
||||||
"auto":"تلقائي",
|
"auto":"تلقائي",
|
||||||
"autoSignin":"Auto Signin",
|
"autoSignin":"Auto Signin",
|
||||||
"autoSigninRules":"القواعد",
|
"autoSigninRules":"القواعد",
|
||||||
|
"avoidAssignment":"Avoid assignment in expressions",
|
||||||
"backtoportal":"العودة إلى البوابة",
|
"backtoportal":"العودة إلى البوابة",
|
||||||
"badCasProxyId":"معرف خدمة بروكسي كاس غير صالح",
|
"badCasProxyId":"معرف خدمة بروكسي كاس غير صالح",
|
||||||
"badChoiceKey":"اسم مفتاح سيئ في قائمة الاختيارات",
|
"badChoiceKey":"اسم مفتاح سيئ في قائمة الاختيارات",
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
"badDomainName":"اسم النطاق سيئ",
|
"badDomainName":"اسم النطاق سيئ",
|
||||||
"badEncoding":"تشفير خاطئ",
|
"badEncoding":"تشفير خاطئ",
|
||||||
"badExpression":"تعبير خاطئ",
|
"badExpression":"تعبير خاطئ",
|
||||||
"badExpressionAssignment":"Expression containing an assignment",
|
"badExpressionAssignment":"Expression containing an assignment. You can use \\x3D to avoid this warning.",
|
||||||
"badHeaderName":" حقل الهيدر خاطئ",
|
"badHeaderName":" حقل الهيدر خاطئ",
|
||||||
"badHostname":"اسم الخادم خاطئ",
|
"badHostname":"اسم الخادم خاطئ",
|
||||||
"badLdapUri":"\n URI LDAP خاطئ",
|
"badLdapUri":"\n URI LDAP خاطئ",
|
||||||
|
@ -207,6 +208,7 @@
|
||||||
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
||||||
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
||||||
"checkUserDisplayEmptyValues":"Display empty values",
|
"checkUserDisplayEmptyValues":"Display empty values",
|
||||||
|
"checkUserHiddenHeaders":"Hidden headers",
|
||||||
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
||||||
"choiceParams":"اختيارالإعدادات",
|
"choiceParams":"اختيارالإعدادات",
|
||||||
"chooseLogo":"اختيار الشعار",
|
"chooseLogo":"اختيار الشعار",
|
||||||
|
@ -494,6 +496,7 @@
|
||||||
"mail2fAuthnLevel":"مستوى إثبات الهوية",
|
"mail2fAuthnLevel":"مستوى إثبات الهوية",
|
||||||
"mail2fLabel":"Label",
|
"mail2fLabel":"Label",
|
||||||
"mail2fLogo":"شعار",
|
"mail2fLogo":"شعار",
|
||||||
|
"mail2fSessionKey":"مفتاح الجلسة الذي يحتوي على عنوان البريد الإلكتروني",
|
||||||
"mailBody":"محتوى البريد الناجح",
|
"mailBody":"محتوى البريد الناجح",
|
||||||
"mailCharset":"charset",
|
"mailCharset":"charset",
|
||||||
"mailConfirmBody":"تأكيد محتوى البريد",
|
"mailConfirmBody":"تأكيد محتوى البريد",
|
||||||
|
@ -586,7 +589,7 @@
|
||||||
"offlineSessions":"Offline sessions",
|
"offlineSessions":"Offline sessions",
|
||||||
"oldValue":"قيمة قديمة",
|
"oldValue":"قيمة قديمة",
|
||||||
"on":"تنشيط",
|
"on":"تنشيط",
|
||||||
"oidcAttribute":"OIDC Attribute",
|
"oidcAttribute":"خاصيات OIDC",
|
||||||
"oidcAuthnLevel":"مستوى إثبات الهوية",
|
"oidcAuthnLevel":"مستوى إثبات الهوية",
|
||||||
"oidcConsents":"OpenID Connect Consents",
|
"oidcConsents":"OpenID Connect Consents",
|
||||||
"oidcOP":" أوبين أيدي كونيكت بروفيدر",
|
"oidcOP":" أوبين أيدي كونيكت بروفيدر",
|
||||||
|
@ -1004,6 +1007,7 @@
|
||||||
"verifyU2FKey":"Verify U2F key",
|
"verifyU2FKey":"Verify U2F key",
|
||||||
"verifyTOTPKey":"Verify TOTP key",
|
"verifyTOTPKey":"Verify TOTP key",
|
||||||
"version":"الإصدار",
|
"version":"الإصدار",
|
||||||
|
"vhostAccessToTrace":"Access to trace",
|
||||||
"vhostAliases":"اسماء مستعارة",
|
"vhostAliases":"اسماء مستعارة",
|
||||||
"vhostAuthnLevel":"مستوى إثبات الهوية واجب",
|
"vhostAuthnLevel":"مستوى إثبات الهوية واجب",
|
||||||
"vhostHttps":"إتش تي تي بي س",
|
"vhostHttps":"إتش تي تي بي س",
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
"auto":"Automatic",
|
"auto":"Automatic",
|
||||||
"autoSignin":"Auto Signin",
|
"autoSignin":"Auto Signin",
|
||||||
"autoSigninRules":"Regeln",
|
"autoSigninRules":"Regeln",
|
||||||
|
"avoidAssignment":"Avoid assignment in expressions",
|
||||||
"backtoportal":"Back to portal",
|
"backtoportal":"Back to portal",
|
||||||
"badCasProxyId":"Bad CAS proxied service identifier",
|
"badCasProxyId":"Bad CAS proxied service identifier",
|
||||||
"badChoiceKey":"Bad key name in Choice menu",
|
"badChoiceKey":"Bad key name in Choice menu",
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
"badDomainName":"Ungültiger Domainname",
|
"badDomainName":"Ungültiger Domainname",
|
||||||
"badEncoding":"Ungültige Codierung",
|
"badEncoding":"Ungültige Codierung",
|
||||||
"badExpression":"Bad expression",
|
"badExpression":"Bad expression",
|
||||||
"badExpressionAssignment":"Expression containing an assignment",
|
"badExpressionAssignment":"Expression containing an assignment. You can use \\x3D to avoid this warning.",
|
||||||
"badHeaderName":"Bad header name",
|
"badHeaderName":"Bad header name",
|
||||||
"badHostname":"Ungültiger Hostname",
|
"badHostname":"Ungültiger Hostname",
|
||||||
"badLdapUri":"Bad LDAP URI",
|
"badLdapUri":"Bad LDAP URI",
|
||||||
|
@ -206,6 +207,7 @@
|
||||||
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
||||||
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
||||||
"checkUserDisplayEmptyValues":"Display empty values",
|
"checkUserDisplayEmptyValues":"Display empty values",
|
||||||
|
"checkUserHiddenHeaders":"Hidden headers",
|
||||||
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
||||||
"choiceParams":"Choice parameters",
|
"choiceParams":"Choice parameters",
|
||||||
"chooseLogo":"Choose logo",
|
"chooseLogo":"Choose logo",
|
||||||
|
@ -493,6 +495,7 @@
|
||||||
"mail2fAuthnLevel":"Authentication level",
|
"mail2fAuthnLevel":"Authentication level",
|
||||||
"mail2fLabel":"Label",
|
"mail2fLabel":"Label",
|
||||||
"mail2fLogo":"Logo",
|
"mail2fLogo":"Logo",
|
||||||
|
"mail2fSessionKey":"Session key containing mail address",
|
||||||
"mailBody":"Success mail content",
|
"mailBody":"Success mail content",
|
||||||
"mailCharset":"Charset",
|
"mailCharset":"Charset",
|
||||||
"mailConfirmBody":"Confirmation mail content",
|
"mailConfirmBody":"Confirmation mail content",
|
||||||
|
@ -1003,6 +1006,7 @@
|
||||||
"verifyU2FKey":"Verify U2F key",
|
"verifyU2FKey":"Verify U2F key",
|
||||||
"verifyTOTPKey":"Verify TOTP key",
|
"verifyTOTPKey":"Verify TOTP key",
|
||||||
"version":"Version",
|
"version":"Version",
|
||||||
|
"vhostAccessToTrace":"Access to trace",
|
||||||
"vhostAliases":"Aliases",
|
"vhostAliases":"Aliases",
|
||||||
"vhostAuthnLevel":"Required authentication level",
|
"vhostAuthnLevel":"Required authentication level",
|
||||||
"vhostHttps":"HTTPS",
|
"vhostHttps":"HTTPS",
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
"auto":"Automatic",
|
"auto":"Automatic",
|
||||||
"autoSignin":"Auto Signin",
|
"autoSignin":"Auto Signin",
|
||||||
"autoSigninRules":"Rules",
|
"autoSigninRules":"Rules",
|
||||||
|
"avoidAssignment":"Avoid assignment in expressions",
|
||||||
"backtoportal":"Back to portal",
|
"backtoportal":"Back to portal",
|
||||||
"badCasProxyId":"Bad CAS proxied service identifier",
|
"badCasProxyId":"Bad CAS proxied service identifier",
|
||||||
"badChoiceKey":"Bad key name in Choice menu",
|
"badChoiceKey":"Bad key name in Choice menu",
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
"badDomainName":"Bad domain name",
|
"badDomainName":"Bad domain name",
|
||||||
"badEncoding":"Bad encoding",
|
"badEncoding":"Bad encoding",
|
||||||
"badExpression":"Bad expression",
|
"badExpression":"Bad expression",
|
||||||
"badExpressionAssignment":"Expression containing an assignment",
|
"badExpressionAssignment":"Expression containing an assignment. You can use \\x3D to avoid this warning.",
|
||||||
"badHeaderName":"Bad header name",
|
"badHeaderName":"Bad header name",
|
||||||
"badHostname":"Bad hostname",
|
"badHostname":"Bad hostname",
|
||||||
"badLdapUri":"Bad LDAP URI",
|
"badLdapUri":"Bad LDAP URI",
|
||||||
|
@ -206,6 +207,7 @@
|
||||||
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
||||||
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
||||||
"checkUserDisplayEmptyValues":"Display empty values",
|
"checkUserDisplayEmptyValues":"Display empty values",
|
||||||
|
"checkUserHiddenHeaders":"Hidden headers",
|
||||||
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
||||||
"choiceParams":"Choice parameters",
|
"choiceParams":"Choice parameters",
|
||||||
"chooseLogo":"Choose logo",
|
"chooseLogo":"Choose logo",
|
||||||
|
@ -493,6 +495,7 @@
|
||||||
"mail2fAuthnLevel":"Authentication level",
|
"mail2fAuthnLevel":"Authentication level",
|
||||||
"mail2fLabel":"Label",
|
"mail2fLabel":"Label",
|
||||||
"mail2fLogo":"Logo",
|
"mail2fLogo":"Logo",
|
||||||
|
"mail2fSessionKey":"Session key containing mail address",
|
||||||
"mailBody":"Success mail content",
|
"mailBody":"Success mail content",
|
||||||
"mailCharset":"Charset",
|
"mailCharset":"Charset",
|
||||||
"mailConfirmBody":"Confirmation mail content",
|
"mailConfirmBody":"Confirmation mail content",
|
||||||
|
@ -1003,6 +1006,7 @@
|
||||||
"verifyU2FKey":"Verify U2F key",
|
"verifyU2FKey":"Verify U2F key",
|
||||||
"verifyTOTPKey":"Verify TOTP key",
|
"verifyTOTPKey":"Verify TOTP key",
|
||||||
"version":"Version",
|
"version":"Version",
|
||||||
|
"vhostAccessToTrace":"Access to trace",
|
||||||
"vhostAliases":"Aliases",
|
"vhostAliases":"Aliases",
|
||||||
"vhostAuthnLevel":"Required authentication level",
|
"vhostAuthnLevel":"Required authentication level",
|
||||||
"vhostHttps":"HTTPS",
|
"vhostHttps":"HTTPS",
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
"auto":"Automatique",
|
"auto":"Automatique",
|
||||||
"autoSignin":"Connexion automatique",
|
"autoSignin":"Connexion automatique",
|
||||||
"autoSigninRules":"Règles",
|
"autoSigninRules":"Règles",
|
||||||
|
"avoidAssignment":"Eviter une affectation dans les expressions",
|
||||||
"backtoportal":"Retour au portail",
|
"backtoportal":"Retour au portail",
|
||||||
"badCasProxyId":"Mauvais identifiant de service proxy CAS",
|
"badCasProxyId":"Mauvais identifiant de service proxy CAS",
|
||||||
"badChoiceKey":"Mauvais nom de clef dans le menu Choice",
|
"badChoiceKey":"Mauvais nom de clef dans le menu Choice",
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
"badDomainName":"Mauvais nom de domaine",
|
"badDomainName":"Mauvais nom de domaine",
|
||||||
"badEncoding":"Mauvais encodage",
|
"badEncoding":"Mauvais encodage",
|
||||||
"badExpression":"Mauvaise expression",
|
"badExpression":"Mauvaise expression",
|
||||||
"badExpressionAssignment":"Expression contenant une affectation",
|
"badExpressionAssignment":"Expression contenant une affectation. Vous pouvez utliser \\x3D pour éviter cet avertissement.",
|
||||||
"badHeaderName":"Mauvais nom d'en-tête",
|
"badHeaderName":"Mauvais nom d'en-tête",
|
||||||
"badHostname":"Mauvais nom d'hôte",
|
"badHostname":"Mauvais nom d'hôte",
|
||||||
"badLdapUri":"Mauvaise URI LDAP",
|
"badLdapUri":"Mauvaise URI LDAP",
|
||||||
|
@ -206,6 +207,7 @@
|
||||||
"checkUserDisplayPersistentInfo":"Afficher les données de session persistante",
|
"checkUserDisplayPersistentInfo":"Afficher les données de session persistante",
|
||||||
"checkUserDisplayEmptyHeaders":"Afficher les entêtes nuls",
|
"checkUserDisplayEmptyHeaders":"Afficher les entêtes nuls",
|
||||||
"checkUserDisplayEmptyValues":"Afficher les valeurs nulles",
|
"checkUserDisplayEmptyValues":"Afficher les valeurs nulles",
|
||||||
|
"checkUserHiddenHeaders":"Entêtes masqués",
|
||||||
"checkUserSearchAttributes":"Attributs utilisés pour rechercher les sessions",
|
"checkUserSearchAttributes":"Attributs utilisés pour rechercher les sessions",
|
||||||
"choiceParams":"Paramètres des choix",
|
"choiceParams":"Paramètres des choix",
|
||||||
"chooseLogo":"Choisir le logo",
|
"chooseLogo":"Choisir le logo",
|
||||||
|
@ -373,7 +375,7 @@
|
||||||
"impersonationMergeSSOgroups":"Fusionner les groupes SSO réels et usurpés",
|
"impersonationMergeSSOgroups":"Fusionner les groupes SSO réels et usurpés",
|
||||||
"impersonationSkipEmptyValues":"Ignorer les valeurs nulles",
|
"impersonationSkipEmptyValues":"Ignorer les valeurs nulles",
|
||||||
"impersonationUnrestrictedUsersRule":"Règle des utilisateurs non restreints",
|
"impersonationUnrestrictedUsersRule":"Règle des utilisateurs non restreints",
|
||||||
"incompleteForm":"Des champs requis manquent",
|
"incompleteForm":"Des champs requis sont manquants",
|
||||||
"index":"Index",
|
"index":"Index",
|
||||||
"infoFormMethod":"Méthode du formulaire d'information",
|
"infoFormMethod":"Méthode du formulaire d'information",
|
||||||
"invalidSessionData":"Donnée de session invalide",
|
"invalidSessionData":"Donnée de session invalide",
|
||||||
|
@ -493,6 +495,7 @@
|
||||||
"mail2fAuthnLevel":"Niveau de l'authentification",
|
"mail2fAuthnLevel":"Niveau de l'authentification",
|
||||||
"mail2fLabel":"Label",
|
"mail2fLabel":"Label",
|
||||||
"mail2fLogo":"Logo",
|
"mail2fLogo":"Logo",
|
||||||
|
"mail2fSessionKey":"Clef de session contenant l'adresse email",
|
||||||
"mailBody":"Contenu du message de succès",
|
"mailBody":"Contenu du message de succès",
|
||||||
"mailCharset":"Charset",
|
"mailCharset":"Charset",
|
||||||
"mailConfirmBody":"Contenu du message de confirmation",
|
"mailConfirmBody":"Contenu du message de confirmation",
|
||||||
|
@ -1003,6 +1006,7 @@
|
||||||
"verifyU2FKey":"Vérifier la clef U2F",
|
"verifyU2FKey":"Vérifier la clef U2F",
|
||||||
"verifyTOTPKey":"Vérifier la clef TOTP",
|
"verifyTOTPKey":"Vérifier la clef TOTP",
|
||||||
"version":"Version",
|
"version":"Version",
|
||||||
|
"vhostAccessToTrace":"Accès à tracer",
|
||||||
"vhostAliases":"Alias",
|
"vhostAliases":"Alias",
|
||||||
"vhostAuthnLevel":"Niveau d'authentification requis",
|
"vhostAuthnLevel":"Niveau d'authentification requis",
|
||||||
"vhostHttps":"HTTPS",
|
"vhostHttps":"HTTPS",
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
"auto":"Automatico",
|
"auto":"Automatico",
|
||||||
"autoSignin":"Accesso automatico",
|
"autoSignin":"Accesso automatico",
|
||||||
"autoSigninRules":"Regole",
|
"autoSigninRules":"Regole",
|
||||||
|
"avoidAssignment":"Avoid assignment in expressions",
|
||||||
"backtoportal":"Torna al portale",
|
"backtoportal":"Torna al portale",
|
||||||
"badCasProxyId":"Identificatore di servizio difettoso CAS proxy",
|
"badCasProxyId":"Identificatore di servizio difettoso CAS proxy",
|
||||||
"badChoiceKey":"Nome chiave errato nel menu Scelta",
|
"badChoiceKey":"Nome chiave errato nel menu Scelta",
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
"badDomainName":"Nome di dominio errato",
|
"badDomainName":"Nome di dominio errato",
|
||||||
"badEncoding":"Codifica errata",
|
"badEncoding":"Codifica errata",
|
||||||
"badExpression":"Espressione errata",
|
"badExpression":"Espressione errata",
|
||||||
"badExpressionAssignment":"Expression containing an assignment",
|
"badExpressionAssignment":"Expression containing an assignment. You can use \\x3D to avoid this warning.",
|
||||||
"badHeaderName":"Nome intestazione errato",
|
"badHeaderName":"Nome intestazione errato",
|
||||||
"badHostname":"Hostname errato",
|
"badHostname":"Hostname errato",
|
||||||
"badLdapUri":"LDAP URI errata",
|
"badLdapUri":"LDAP URI errata",
|
||||||
|
@ -206,6 +207,7 @@
|
||||||
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
||||||
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
||||||
"checkUserDisplayEmptyValues":"Mostra valori vuoti",
|
"checkUserDisplayEmptyValues":"Mostra valori vuoti",
|
||||||
|
"checkUserHiddenHeaders":"Hidden headers",
|
||||||
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
||||||
"choiceParams":"Scelta parametri",
|
"choiceParams":"Scelta parametri",
|
||||||
"chooseLogo":"Scegli logo",
|
"chooseLogo":"Scegli logo",
|
||||||
|
@ -493,6 +495,7 @@
|
||||||
"mail2fAuthnLevel":"Livello di autenticazione",
|
"mail2fAuthnLevel":"Livello di autenticazione",
|
||||||
"mail2fLabel":"Label",
|
"mail2fLabel":"Label",
|
||||||
"mail2fLogo":"Logo",
|
"mail2fLogo":"Logo",
|
||||||
|
"mail2fSessionKey":"Chiave di sessione contenente l'indirizzo di posta",
|
||||||
"mailBody":"Successo contenuto di posta",
|
"mailBody":"Successo contenuto di posta",
|
||||||
"mailCharset":"Charset",
|
"mailCharset":"Charset",
|
||||||
"mailConfirmBody":"Contenuto della mail di conferma",
|
"mailConfirmBody":"Contenuto della mail di conferma",
|
||||||
|
@ -585,7 +588,7 @@
|
||||||
"offlineSessions":"Offline sessions",
|
"offlineSessions":"Offline sessions",
|
||||||
"oldValue":"Vecchio valore",
|
"oldValue":"Vecchio valore",
|
||||||
"on":"On",
|
"on":"On",
|
||||||
"oidcAttribute":"OIDC Attribute",
|
"oidcAttribute":"Attributo OIDC",
|
||||||
"oidcAuthnLevel":"Livello di autenticazione",
|
"oidcAuthnLevel":"Livello di autenticazione",
|
||||||
"oidcConsents":"OpenID Connect Consents",
|
"oidcConsents":"OpenID Connect Consents",
|
||||||
"oidcOP":"Provider di OpenID Connect",
|
"oidcOP":"Provider di OpenID Connect",
|
||||||
|
@ -1003,6 +1006,7 @@
|
||||||
"verifyU2FKey":"Verifica la chiave U2F",
|
"verifyU2FKey":"Verifica la chiave U2F",
|
||||||
"verifyTOTPKey":"Verifica la chiave TOTP",
|
"verifyTOTPKey":"Verifica la chiave TOTP",
|
||||||
"version":"Versioni",
|
"version":"Versioni",
|
||||||
|
"vhostAccessToTrace":"Access to trace",
|
||||||
"vhostAliases":"Alias",
|
"vhostAliases":"Alias",
|
||||||
"vhostAuthnLevel":"Livello di autenticazione richiesto",
|
"vhostAuthnLevel":"Livello di autenticazione richiesto",
|
||||||
"vhostHttps":"HTTPS",
|
"vhostHttps":"HTTPS",
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
"auto":"Automatycznie",
|
"auto":"Automatycznie",
|
||||||
"autoSignin":"Zaloguj się automatycznie",
|
"autoSignin":"Zaloguj się automatycznie",
|
||||||
"autoSigninRules":"Zasady",
|
"autoSigninRules":"Zasady",
|
||||||
|
"avoidAssignment":"Avoid assignment in expressions",
|
||||||
"backtoportal":"Powrót do portalu",
|
"backtoportal":"Powrót do portalu",
|
||||||
"badCasProxyId":"Nieprawidłowy identyfikator usługi proxy CAS",
|
"badCasProxyId":"Nieprawidłowy identyfikator usługi proxy CAS",
|
||||||
"badChoiceKey":"Błędna nazwa klucza w menu Wybór",
|
"badChoiceKey":"Błędna nazwa klucza w menu Wybór",
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
"badDomainName":"Błędna nazwa domeny",
|
"badDomainName":"Błędna nazwa domeny",
|
||||||
"badEncoding":"Błędne kodowanie",
|
"badEncoding":"Błędne kodowanie",
|
||||||
"badExpression":"Błędne wyrażenie",
|
"badExpression":"Błędne wyrażenie",
|
||||||
"badExpressionAssignment":"Expression containing an assignment",
|
"badExpressionAssignment":"Expression containing an assignment. You can use \\x3D to avoid this warning.",
|
||||||
"badHeaderName":"Błędna nazwa nagłówka",
|
"badHeaderName":"Błędna nazwa nagłówka",
|
||||||
"badHostname":"Błędna nazwa hosta",
|
"badHostname":"Błędna nazwa hosta",
|
||||||
"badLdapUri":"Błędny identyfikator URI LDAP",
|
"badLdapUri":"Błędny identyfikator URI LDAP",
|
||||||
|
@ -206,6 +207,7 @@
|
||||||
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
||||||
"checkUserDisplayEmptyHeaders":"Wyświetl puste nagłówki",
|
"checkUserDisplayEmptyHeaders":"Wyświetl puste nagłówki",
|
||||||
"checkUserDisplayEmptyValues":"Wyświetl puste wartości",
|
"checkUserDisplayEmptyValues":"Wyświetl puste wartości",
|
||||||
|
"checkUserHiddenHeaders":"Hidden headers",
|
||||||
"checkUserSearchAttributes":"Atrybuty używane do wyszukiwania sesji",
|
"checkUserSearchAttributes":"Atrybuty używane do wyszukiwania sesji",
|
||||||
"choiceParams":"Parametry wyboru",
|
"choiceParams":"Parametry wyboru",
|
||||||
"chooseLogo":"Wybierz logo",
|
"chooseLogo":"Wybierz logo",
|
||||||
|
@ -493,6 +495,7 @@
|
||||||
"mail2fAuthnLevel":"Poziom uwierzytelnienia",
|
"mail2fAuthnLevel":"Poziom uwierzytelnienia",
|
||||||
"mail2fLabel":"Etykieta",
|
"mail2fLabel":"Etykieta",
|
||||||
"mail2fLogo":"Logo",
|
"mail2fLogo":"Logo",
|
||||||
|
"mail2fSessionKey":"Klucz sesji zawierający adres e-mail",
|
||||||
"mailBody":"Treść wiadomości o powodzeniu",
|
"mailBody":"Treść wiadomości o powodzeniu",
|
||||||
"mailCharset":"Zestaw znaków",
|
"mailCharset":"Zestaw znaków",
|
||||||
"mailConfirmBody":"Treść wiadomości potwierdzającej",
|
"mailConfirmBody":"Treść wiadomości potwierdzającej",
|
||||||
|
@ -585,7 +588,7 @@
|
||||||
"offlineSessions":"Sesje offline",
|
"offlineSessions":"Sesje offline",
|
||||||
"oldValue":"Stara wartość",
|
"oldValue":"Stara wartość",
|
||||||
"on":"Włączone",
|
"on":"Włączone",
|
||||||
"oidcAttribute":"OIDC Attribute",
|
"oidcAttribute":"Atrybut OIDC",
|
||||||
"oidcAuthnLevel":"Poziom uwierzytelnienia",
|
"oidcAuthnLevel":"Poziom uwierzytelnienia",
|
||||||
"oidcConsents":"Zgoda na OpenID Connect",
|
"oidcConsents":"Zgoda na OpenID Connect",
|
||||||
"oidcOP":"Dostawca OpenID Connect",
|
"oidcOP":"Dostawca OpenID Connect",
|
||||||
|
@ -1003,6 +1006,7 @@
|
||||||
"verifyU2FKey":"Sprawdź klucz U2F",
|
"verifyU2FKey":"Sprawdź klucz U2F",
|
||||||
"verifyTOTPKey":"Sprawdź klucz TOTP",
|
"verifyTOTPKey":"Sprawdź klucz TOTP",
|
||||||
"version":"Wersja",
|
"version":"Wersja",
|
||||||
|
"vhostAccessToTrace":"Access to trace",
|
||||||
"vhostAliases":"Aliasy",
|
"vhostAliases":"Aliasy",
|
||||||
"vhostAuthnLevel":"Wymagany poziom uwierzytelnienia",
|
"vhostAuthnLevel":"Wymagany poziom uwierzytelnienia",
|
||||||
"vhostHttps":"HTTPS",
|
"vhostHttps":"HTTPS",
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
"ADPwdMaxAge":"Parola maksimum sınırı",
|
"ADPwdMaxAge":"Parola maksimum sınırı",
|
||||||
"advancedParams":"Gelişmiş parametreler",
|
"advancedParams":"Gelişmiş parametreler",
|
||||||
"allowedMarkups":"İzin verilen biçimlendirmeler:",
|
"allowedMarkups":"İzin verilen biçimlendirmeler:",
|
||||||
"always":"Always",
|
"always":"Her zaman",
|
||||||
"apacheParams":"Apache parametreleri",
|
"apacheParams":"Apache parametreleri",
|
||||||
"apacheAuthnLevel":"Doğrulama seviyesi",
|
"apacheAuthnLevel":"Doğrulama seviyesi",
|
||||||
"application":"Uygulama",
|
"application":"Uygulama",
|
||||||
|
@ -55,7 +55,7 @@
|
||||||
"appsInThisCat":"Bu kategorideki uygulamalar",
|
"appsInThisCat":"Bu kategorideki uygulamalar",
|
||||||
"array":"Array",
|
"array":"Array",
|
||||||
"attributesAndMacros":"Nitelikler ve Makrolar",
|
"attributesAndMacros":"Nitelikler ve Makrolar",
|
||||||
"attributeName":"Attribute name",
|
"attributeName":"Nitelik adı",
|
||||||
"authAndUserdb":"Yetkilendirme ve kullanıcı veri tabanı",
|
"authAndUserdb":"Yetkilendirme ve kullanıcı veri tabanı",
|
||||||
"authChain":"Doğrulama zinciri",
|
"authChain":"Doğrulama zinciri",
|
||||||
"authChoice":"Kimlik doğrulama tercihi",
|
"authChoice":"Kimlik doğrulama tercihi",
|
||||||
|
@ -75,6 +75,7 @@
|
||||||
"auto":"Otomatik",
|
"auto":"Otomatik",
|
||||||
"autoSignin":"Otomatik Oturum Açma",
|
"autoSignin":"Otomatik Oturum Açma",
|
||||||
"autoSigninRules":"Kurallar",
|
"autoSigninRules":"Kurallar",
|
||||||
|
"avoidAssignment":"Avoid assignment in expressions",
|
||||||
"backtoportal":"Portala geri dön",
|
"backtoportal":"Portala geri dön",
|
||||||
"badCasProxyId":"Hatalı CAS vekil servis tanımlayıcısı",
|
"badCasProxyId":"Hatalı CAS vekil servis tanımlayıcısı",
|
||||||
"badChoiceKey":"Tercih menüsünde hatalı anahtar adı",
|
"badChoiceKey":"Tercih menüsünde hatalı anahtar adı",
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
"badDomainName":"Hatalı etki alanı adı",
|
"badDomainName":"Hatalı etki alanı adı",
|
||||||
"badEncoding":"Hatalı kodlama",
|
"badEncoding":"Hatalı kodlama",
|
||||||
"badExpression":"Hatalı ifade",
|
"badExpression":"Hatalı ifade",
|
||||||
"badExpressionAssignment":"İfade bir atama içeriyor",
|
"badExpressionAssignment":"Expression containing an assignment. You can use \\x3D to avoid this warning.",
|
||||||
"badHeaderName":"Hatalı başlık adı",
|
"badHeaderName":"Hatalı başlık adı",
|
||||||
"badHostname":"Hatalı konak adı",
|
"badHostname":"Hatalı konak adı",
|
||||||
"badLdapUri":"Hatalı LDAP URI",
|
"badLdapUri":"Hatalı LDAP URI",
|
||||||
|
@ -100,7 +101,7 @@
|
||||||
"badValue":"Hatalı değer",
|
"badValue":"Hatalı değer",
|
||||||
"badVariableName":"Hatalı değişken adı",
|
"badVariableName":"Hatalı değişken adı",
|
||||||
"blackList":"Kara liste",
|
"blackList":"Kara liste",
|
||||||
"bool":"Boolean",
|
"bool":"Mantıksal",
|
||||||
"browse":"Göz at",
|
"browse":"Göz at",
|
||||||
"browsersDontStorePassword":"Kullanıcı parolasını tarayıcılarda saklamaktan kaçının",
|
"browsersDontStorePassword":"Kullanıcı parolasını tarayıcılarda saklamaktan kaçının",
|
||||||
"browserIdAuthnLevel":"Doğrulama seviyesi",
|
"browserIdAuthnLevel":"Doğrulama seviyesi",
|
||||||
|
@ -193,7 +194,7 @@
|
||||||
"cfgVersion":"Yapılandırma sürümü",
|
"cfgVersion":"Yapılandırma sürümü",
|
||||||
"checkXSS":"XSS saldırılarını kontrol et",
|
"checkXSS":"XSS saldırılarını kontrol et",
|
||||||
"clickHereToForce":"Zorlamak için buraya tıklayın",
|
"clickHereToForce":"Zorlamak için buraya tıklayın",
|
||||||
"claimName":"Claim name",
|
"claimName":"İstek adı",
|
||||||
"checkboxes":"Onay kutuları",
|
"checkboxes":"Onay kutuları",
|
||||||
"checkState":"Aktivasyon",
|
"checkState":"Aktivasyon",
|
||||||
"checkStateSecret":"Paylaşılan sır",
|
"checkStateSecret":"Paylaşılan sır",
|
||||||
|
@ -206,6 +207,7 @@
|
||||||
"checkUserDisplayPersistentInfo":"Kalıcı oturum verisini görüntüle",
|
"checkUserDisplayPersistentInfo":"Kalıcı oturum verisini görüntüle",
|
||||||
"checkUserDisplayEmptyHeaders":"Boş başlıkları görüntüle",
|
"checkUserDisplayEmptyHeaders":"Boş başlıkları görüntüle",
|
||||||
"checkUserDisplayEmptyValues":"Boş değerleri görüntüle",
|
"checkUserDisplayEmptyValues":"Boş değerleri görüntüle",
|
||||||
|
"checkUserHiddenHeaders":"Hidden headers",
|
||||||
"checkUserSearchAttributes":"Arama oturumlarında kullanılan nitelikler",
|
"checkUserSearchAttributes":"Arama oturumlarında kullanılan nitelikler",
|
||||||
"choiceParams":"Tercih parametreleri",
|
"choiceParams":"Tercih parametreleri",
|
||||||
"chooseLogo":"Logo seçin",
|
"chooseLogo":"Logo seçin",
|
||||||
|
@ -377,7 +379,7 @@
|
||||||
"index":"Dizin",
|
"index":"Dizin",
|
||||||
"infoFormMethod":"Bilgi formu için metot",
|
"infoFormMethod":"Bilgi formu için metot",
|
||||||
"invalidSessionData":"Geçersiz oturum verisi",
|
"invalidSessionData":"Geçersiz oturum verisi",
|
||||||
"int":"Integer",
|
"int":"Sayı",
|
||||||
"internalReference":"Dahili referans",
|
"internalReference":"Dahili referans",
|
||||||
"ipAddr":"IP adresi",
|
"ipAddr":"IP adresi",
|
||||||
"ipAddresses":"IP adresleri",
|
"ipAddresses":"IP adresleri",
|
||||||
|
@ -493,6 +495,7 @@
|
||||||
"mail2fAuthnLevel":"Doğrulama seviyesi",
|
"mail2fAuthnLevel":"Doğrulama seviyesi",
|
||||||
"mail2fLabel":"Etiket",
|
"mail2fLabel":"Etiket",
|
||||||
"mail2fLogo":"Logo",
|
"mail2fLogo":"Logo",
|
||||||
|
"mail2fSessionKey":"Oturum anahtarı e-posta adresini içeriyor",
|
||||||
"mailBody":"Başarılı e-posta içeriği",
|
"mailBody":"Başarılı e-posta içeriği",
|
||||||
"mailCharset":"Karakter seti",
|
"mailCharset":"Karakter seti",
|
||||||
"mailConfirmBody":"Doğrulama e-postası içeriği",
|
"mailConfirmBody":"Doğrulama e-postası içeriği",
|
||||||
|
@ -526,7 +529,7 @@
|
||||||
"name":"Ad",
|
"name":"Ad",
|
||||||
"needConfirmation":"Yeni bir yapılandırma mevcut. Bunu kaydetmeye zorlamak için 'kaydet' butonunun yanındaki onay kutusuna tıklayın.",
|
"needConfirmation":"Yeni bir yapılandırma mevcut. Bunu kaydetmeye zorlamak için 'kaydet' butonunun yanındaki onay kutusuna tıklayın.",
|
||||||
"networkProblem":"Ağ problemi",
|
"networkProblem":"Ağ problemi",
|
||||||
"never":"Never",
|
"never":"Asla",
|
||||||
"newApp":"Yeni uygulama",
|
"newApp":"Yeni uygulama",
|
||||||
"newChain":"Yeni zincir",
|
"newChain":"Yeni zincir",
|
||||||
"newCat":"Yeni kategori",
|
"newCat":"Yeni kategori",
|
||||||
|
@ -585,7 +588,7 @@
|
||||||
"offlineSessions":"Çevrimdışı oturumlar",
|
"offlineSessions":"Çevrimdışı oturumlar",
|
||||||
"oldValue":"Eski değer",
|
"oldValue":"Eski değer",
|
||||||
"on":"Açık",
|
"on":"Açık",
|
||||||
"oidcAttribute":"OIDC Attribute",
|
"oidcAttribute":"OIDC niteliği",
|
||||||
"oidcAuthnLevel":"Doğrulama seviyesi",
|
"oidcAuthnLevel":"Doğrulama seviyesi",
|
||||||
"oidcConsents":"OpenID Connect İzinleri",
|
"oidcConsents":"OpenID Connect İzinleri",
|
||||||
"oidcOP":"OpenID Connect Sağlayıcısı",
|
"oidcOP":"OpenID Connect Sağlayıcısı",
|
||||||
|
@ -999,10 +1002,11 @@
|
||||||
"value":"Değer",
|
"value":"Değer",
|
||||||
"values":"Değerler",
|
"values":"Değerler",
|
||||||
"variables":"Değişkenler",
|
"variables":"Değişkenler",
|
||||||
"variableName":"Variable name",
|
"variableName":"Değişken adı",
|
||||||
"verifyU2FKey":"U2F anahtarını doğrula",
|
"verifyU2FKey":"U2F anahtarını doğrula",
|
||||||
"verifyTOTPKey":"TOTP anahtarını doğrula",
|
"verifyTOTPKey":"TOTP anahtarını doğrula",
|
||||||
"version":"Sürüm",
|
"version":"Sürüm",
|
||||||
|
"vhostAccessToTrace":"Access to trace",
|
||||||
"vhostAliases":"Takma adlar",
|
"vhostAliases":"Takma adlar",
|
||||||
"vhostAuthnLevel":"Gereken doğrulama seviyesi",
|
"vhostAuthnLevel":"Gereken doğrulama seviyesi",
|
||||||
"vhostHttps":"HTTPS",
|
"vhostHttps":"HTTPS",
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
"auto":"Tự động",
|
"auto":"Tự động",
|
||||||
"autoSignin":"Auto Signin",
|
"autoSignin":"Auto Signin",
|
||||||
"autoSigninRules":"Quy tắc",
|
"autoSigninRules":"Quy tắc",
|
||||||
|
"avoidAssignment":"Avoid assignment in expressions",
|
||||||
"backtoportal":"Quay lại cổng thông tin",
|
"backtoportal":"Quay lại cổng thông tin",
|
||||||
"badCasProxyId":"Dịch vụ định danh đệm bởi CAS không hợp lệ",
|
"badCasProxyId":"Dịch vụ định danh đệm bởi CAS không hợp lệ",
|
||||||
"badChoiceKey":"Tên khoá không hợp lệ trong trình đơn Chọn",
|
"badChoiceKey":"Tên khoá không hợp lệ trong trình đơn Chọn",
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
"badDomainName":"Tên miền không hợp lệ",
|
"badDomainName":"Tên miền không hợp lệ",
|
||||||
"badEncoding":"Mã hoá không hợp lệ",
|
"badEncoding":"Mã hoá không hợp lệ",
|
||||||
"badExpression":"Biểu thức không hợp lệ",
|
"badExpression":"Biểu thức không hợp lệ",
|
||||||
"badExpressionAssignment":"Expression containing an assignment",
|
"badExpressionAssignment":"Expression containing an assignment. You can use \\x3D to avoid this warning.",
|
||||||
"badHeaderName":"Tên tiêu đề không hợp lệ",
|
"badHeaderName":"Tên tiêu đề không hợp lệ",
|
||||||
"badHostname":"Tên máy chủ không hợp lệ",
|
"badHostname":"Tên máy chủ không hợp lệ",
|
||||||
"badLdapUri":"URI LDAP không đúng",
|
"badLdapUri":"URI LDAP không đúng",
|
||||||
|
@ -206,6 +207,7 @@
|
||||||
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
||||||
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
||||||
"checkUserDisplayEmptyValues":"Display empty values",
|
"checkUserDisplayEmptyValues":"Display empty values",
|
||||||
|
"checkUserHiddenHeaders":"Hidden headers",
|
||||||
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
||||||
"choiceParams":"Các tham số lựa chọn",
|
"choiceParams":"Các tham số lựa chọn",
|
||||||
"chooseLogo":"Chọn logo",
|
"chooseLogo":"Chọn logo",
|
||||||
|
@ -493,6 +495,7 @@
|
||||||
"mail2fAuthnLevel":"Mức xác thực",
|
"mail2fAuthnLevel":"Mức xác thực",
|
||||||
"mail2fLabel":"Label",
|
"mail2fLabel":"Label",
|
||||||
"mail2fLogo":"Logo",
|
"mail2fLogo":"Logo",
|
||||||
|
"mail2fSessionKey":"Khóa phiên chứa địa chỉ thư",
|
||||||
"mailBody":"Nội dung thư thành công",
|
"mailBody":"Nội dung thư thành công",
|
||||||
"mailCharset":"Charset",
|
"mailCharset":"Charset",
|
||||||
"mailConfirmBody":"Xác nhận nội dung thư",
|
"mailConfirmBody":"Xác nhận nội dung thư",
|
||||||
|
@ -585,7 +588,7 @@
|
||||||
"offlineSessions":"Offline sessions",
|
"offlineSessions":"Offline sessions",
|
||||||
"oldValue":"Giá trị cũ",
|
"oldValue":"Giá trị cũ",
|
||||||
"on":"Vào",
|
"on":"Vào",
|
||||||
"oidcAttribute":"OIDC Attribute",
|
"oidcAttribute":"thuộc tính OIDC",
|
||||||
"oidcAuthnLevel":"Mức xác thực",
|
"oidcAuthnLevel":"Mức xác thực",
|
||||||
"oidcConsents":"OpenID Connect Consents",
|
"oidcConsents":"OpenID Connect Consents",
|
||||||
"oidcOP":"Bộ cung cấp Kết nối OpenID",
|
"oidcOP":"Bộ cung cấp Kết nối OpenID",
|
||||||
|
@ -1003,6 +1006,7 @@
|
||||||
"verifyU2FKey":"Verify U2F key",
|
"verifyU2FKey":"Verify U2F key",
|
||||||
"verifyTOTPKey":"Verify TOTP key",
|
"verifyTOTPKey":"Verify TOTP key",
|
||||||
"version":"Phiên bản",
|
"version":"Phiên bản",
|
||||||
|
"vhostAccessToTrace":"Access to trace",
|
||||||
"vhostAliases":"Bí danh",
|
"vhostAliases":"Bí danh",
|
||||||
"vhostAuthnLevel":"Mức xác thực bắt buộc",
|
"vhostAuthnLevel":"Mức xác thực bắt buộc",
|
||||||
"vhostHttps":"HTTPS",
|
"vhostHttps":"HTTPS",
|
||||||
|
|
|
@ -75,6 +75,7 @@
|
||||||
"auto":"自动",
|
"auto":"自动",
|
||||||
"autoSignin":"Auto Signin",
|
"autoSignin":"Auto Signin",
|
||||||
"autoSigninRules":"Rules",
|
"autoSigninRules":"Rules",
|
||||||
|
"avoidAssignment":"Avoid assignment in expressions",
|
||||||
"backtoportal":"返回 portal",
|
"backtoportal":"返回 portal",
|
||||||
"badCasProxyId":"无效的 CAS proxied service identifier",
|
"badCasProxyId":"无效的 CAS proxied service identifier",
|
||||||
"badChoiceKey":"选择菜单的无效 key ",
|
"badChoiceKey":"选择菜单的无效 key ",
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
"badDomainName":"无效的域名",
|
"badDomainName":"无效的域名",
|
||||||
"badEncoding":"无效的编码",
|
"badEncoding":"无效的编码",
|
||||||
"badExpression":"无效的表达式",
|
"badExpression":"无效的表达式",
|
||||||
"badExpressionAssignment":"Expression containing an assignment",
|
"badExpressionAssignment":"Expression containing an assignment. You can use \\x3D to avoid this warning.",
|
||||||
"badHeaderName":"无效的头部名称",
|
"badHeaderName":"无效的头部名称",
|
||||||
"badHostname":"无效的主机名",
|
"badHostname":"无效的主机名",
|
||||||
"badLdapUri":"无效的 LDAP URI ",
|
"badLdapUri":"无效的 LDAP URI ",
|
||||||
|
@ -206,6 +207,7 @@
|
||||||
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
"checkUserDisplayPersistentInfo":"Display persistent session data",
|
||||||
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
"checkUserDisplayEmptyHeaders":"Display empty headers",
|
||||||
"checkUserDisplayEmptyValues":"Display empty values",
|
"checkUserDisplayEmptyValues":"Display empty values",
|
||||||
|
"checkUserHiddenHeaders":"Hidden headers",
|
||||||
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
"checkUserSearchAttributes":"Attributes used for searching sessions",
|
||||||
"choiceParams":"Choice parameters",
|
"choiceParams":"Choice parameters",
|
||||||
"chooseLogo":"Choose logo",
|
"chooseLogo":"Choose logo",
|
||||||
|
@ -493,6 +495,7 @@
|
||||||
"mail2fAuthnLevel":"认证等级",
|
"mail2fAuthnLevel":"认证等级",
|
||||||
"mail2fLabel":"Label",
|
"mail2fLabel":"Label",
|
||||||
"mail2fLogo":"Logo",
|
"mail2fLogo":"Logo",
|
||||||
|
"mail2fSessionKey":"Session key containing mail address",
|
||||||
"mailBody":"Success mail content",
|
"mailBody":"Success mail content",
|
||||||
"mailCharset":"Charset",
|
"mailCharset":"Charset",
|
||||||
"mailConfirmBody":"Confirmation mail content",
|
"mailConfirmBody":"Confirmation mail content",
|
||||||
|
@ -1003,6 +1006,7 @@
|
||||||
"verifyU2FKey":"Verify U2F key",
|
"verifyU2FKey":"Verify U2F key",
|
||||||
"verifyTOTPKey":"Verify TOTP key",
|
"verifyTOTPKey":"Verify TOTP key",
|
||||||
"version":"Version",
|
"version":"Version",
|
||||||
|
"vhostAccessToTrace":"Access to trace",
|
||||||
"vhostAliases":"Aliases",
|
"vhostAliases":"Aliases",
|
||||||
"vhostAuthnLevel":"Required authentication level",
|
"vhostAuthnLevel":"Required authentication level",
|
||||||
"vhostHttps":"HTTPS",
|
"vhostHttps":"HTTPS",
|
||||||
|
|
BIN
lemonldap-ng-manager/site/htdocs/static/logos/es.png
Normal file
BIN
lemonldap-ng-manager/site/htdocs/static/logos/es.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 273 B |
BIN
lemonldap-ng-manager/site/htdocs/static/logos/zh_TW.png
Normal file
BIN
lemonldap-ng-manager/site/htdocs/static/logos/zh_TW.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.2 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -25,30 +25,29 @@ ok( $resBody = from_json( $res->[2]->[0] ), "Result body contains JSON text" );
|
||||||
|
|
||||||
ok( $resBody->{result} == 0, "JSON response contains \"result:0\"" )
|
ok( $resBody->{result} == 0, "JSON response contains \"result:0\"" )
|
||||||
or print STDERR Dumper($resBody);
|
or print STDERR Dumper($resBody);
|
||||||
|
|
||||||
ok( $resBody->{needConfirm} == 1, "JSON response contains \"needConfirm:1\"" )
|
ok( $resBody->{needConfirm} == 1, "JSON response contains \"needConfirm:1\"" )
|
||||||
or print STDERR Dumper($resBody);
|
or print STDERR Dumper($resBody);
|
||||||
|
|
||||||
ok(
|
ok(
|
||||||
@{ $resBody->{details}->{__warnings__} } == 3,
|
@{ $resBody->{details}->{__warnings__} } == 4,
|
||||||
'JSON response contains 3 warnings'
|
'JSON response contains 4 warnings'
|
||||||
) or print STDERR Dumper($resBody);
|
) or print STDERR Dumper($resBody);
|
||||||
|
count(6);
|
||||||
|
|
||||||
foreach my $i ( 0 .. 2 ) {
|
foreach my $i ( 0 .. 3 ) {
|
||||||
ok(
|
ok(
|
||||||
$resBody->{details}->{__warnings__}->[$i]->{message} =~
|
$resBody->{details}->{__warnings__}->[$i]->{message} =~
|
||||||
/\b(unprotected|cross-domain-authentication|retries)\b/,
|
/\b(unprotected|cross-domain-authentication|retries|__badExpressionAssignment__)\b/,
|
||||||
"Warning with 'unprotect', 'CDA' or 'retries' found"
|
"Warning with 'unprotect', 'CDA', 'assignment' or 'retries' found"
|
||||||
) or print STDERR Dumper($resBody);
|
) or print STDERR Dumper($resBody);
|
||||||
|
count(1);
|
||||||
}
|
}
|
||||||
count(4);
|
|
||||||
ok(
|
ok(
|
||||||
@{ $resBody->{details}->{__needConfirmation__} } == 2,
|
@{ $resBody->{details}->{__needConfirmation__} } == 1,
|
||||||
'JSON response contains 2 needConfirmation'
|
'JSON response contains 1 needConfirmation'
|
||||||
) or print STDERR Dumper($resBody);
|
) or print STDERR Dumper($resBody);
|
||||||
ok(
|
ok(
|
||||||
@{ $resBody->{details}->{__changes__} } == 23,
|
@{ $resBody->{details}->{__changes__} } == 24,
|
||||||
'JSON response contains 23 changes'
|
'JSON response contains 24 changes'
|
||||||
) or print STDERR Dumper($resBody);
|
) or print STDERR Dumper($resBody);
|
||||||
|
|
||||||
#print STDERR Dumper($resBody);
|
#print STDERR Dumper($resBody);
|
||||||
|
@ -89,7 +88,7 @@ while ( my $c = shift @{ $resBody->{details}->{__changes__} } ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ok( !@changes, 'All changes detected' ) or $bug = 1;
|
ok( !@changes, 'All changes detected' ) or $bug = 1;
|
||||||
|
count(1);
|
||||||
if ($bug) {
|
if ($bug) {
|
||||||
print STDERR 'Expected not found: '
|
print STDERR 'Expected not found: '
|
||||||
. Dumper( \@changes )
|
. Dumper( \@changes )
|
||||||
|
@ -99,8 +98,6 @@ if ($bug) {
|
||||||
|
|
||||||
#print STDERR Dumper(\@changes,\@cmsg);
|
#print STDERR Dumper(\@changes,\@cmsg);
|
||||||
|
|
||||||
count(6);
|
|
||||||
|
|
||||||
# TODO: check result of this
|
# TODO: check result of this
|
||||||
ok( $res = &client->jsonResponse('/diff/1/2'), 'Diff called' );
|
ok( $res = &client->jsonResponse('/diff/1/2'), 'Diff called' );
|
||||||
my ( @c1, @c2 );
|
my ( @c1, @c2 );
|
||||||
|
@ -108,8 +105,8 @@ ok( ( @c1 = sort keys %{ $res->[0] } ), 'diff() detects changes in conf 1' );
|
||||||
ok( ( @c2 = sort keys %{ $res->[1] } ), 'diff() detects changes in conf 2' );
|
ok( ( @c2 = sort keys %{ $res->[1] } ), 'diff() detects changes in conf 2' );
|
||||||
ok( @c1 == 12, '12 keys changed in conf 1' )
|
ok( @c1 == 12, '12 keys changed in conf 1' )
|
||||||
or print STDERR "Expect: 12 keys, get: " . join( ', ', @c1 ) . "\n";
|
or print STDERR "Expect: 12 keys, get: " . join( ', ', @c1 ) . "\n";
|
||||||
ok( @c2 == 16, '16 keys changed or created in conf 2' )
|
ok( @c2 == 17, '17 keys changed or created in conf 2' )
|
||||||
or print STDERR "Expect: 16 keys, get: " . join( ',', @c2 ) . "\n";
|
or print STDERR "Expect: 17 keys, get: " . join( ',', @c2 ) . "\n";
|
||||||
count(5);
|
count(5);
|
||||||
|
|
||||||
unlink $confFiles->[1];
|
unlink $confFiles->[1];
|
||||||
|
@ -242,6 +239,11 @@ sub changes {
|
||||||
{
|
{
|
||||||
'confCompacted' => '1',
|
'confCompacted' => '1',
|
||||||
'removedKeys' => 'some; keys'
|
'removedKeys' => 'some; keys'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'new' => 1,
|
||||||
|
'key' => 'avoidAssignment',
|
||||||
|
'old' => '0'
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1597,6 +1597,12 @@
|
||||||
"title": "useSafeJail",
|
"title": "useSafeJail",
|
||||||
"type": "bool",
|
"type": "bool",
|
||||||
"data": 1
|
"data": 1
|
||||||
|
}, {
|
||||||
|
"default": 0,
|
||||||
|
"id": "avoidAssignment",
|
||||||
|
"title": "avoidAssignment",
|
||||||
|
"type": "bool",
|
||||||
|
"data": 1
|
||||||
}, {
|
}, {
|
||||||
"default": 1,
|
"default": 1,
|
||||||
"id": "checkXSS",
|
"id": "checkXSS",
|
||||||
|
|
|
@ -373,6 +373,7 @@ site/htdocs/static/common/ro.png
|
||||||
site/htdocs/static/common/tr.png
|
site/htdocs/static/common/tr.png
|
||||||
site/htdocs/static/common/vi.png
|
site/htdocs/static/common/vi.png
|
||||||
site/htdocs/static/common/zh.png
|
site/htdocs/static/common/zh.png
|
||||||
|
site/htdocs/static/common/zh_TW.png
|
||||||
site/htdocs/static/languages/ar.json
|
site/htdocs/static/languages/ar.json
|
||||||
site/htdocs/static/languages/de.json
|
site/htdocs/static/languages/de.json
|
||||||
site/htdocs/static/languages/en.json
|
site/htdocs/static/languages/en.json
|
||||||
|
@ -387,6 +388,7 @@ site/htdocs/static/languages/ro.json
|
||||||
site/htdocs/static/languages/tr.json
|
site/htdocs/static/languages/tr.json
|
||||||
site/htdocs/static/languages/vi.json
|
site/htdocs/static/languages/vi.json
|
||||||
site/htdocs/static/languages/zh.json
|
site/htdocs/static/languages/zh.json
|
||||||
|
site/htdocs/static/languages/zh_TW.json
|
||||||
site/templates/bootstrap/2fchoice.tpl
|
site/templates/bootstrap/2fchoice.tpl
|
||||||
site/templates/bootstrap/2fregisters.tpl
|
site/templates/bootstrap/2fregisters.tpl
|
||||||
site/templates/bootstrap/captcha.tpl
|
site/templates/bootstrap/captcha.tpl
|
||||||
|
@ -456,6 +458,7 @@ site/templates/common/bullet_go.png
|
||||||
site/templates/common/key.png
|
site/templates/common/key.png
|
||||||
site/templates/common/mail/ar.json
|
site/templates/common/mail/ar.json
|
||||||
site/templates/common/mail/en.json
|
site/templates/common/mail/en.json
|
||||||
|
site/templates/common/mail/es.json
|
||||||
site/templates/common/mail/fi.json
|
site/templates/common/mail/fi.json
|
||||||
site/templates/common/mail/fr.json
|
site/templates/common/mail/fr.json
|
||||||
site/templates/common/mail/it.json
|
site/templates/common/mail/it.json
|
||||||
|
@ -463,6 +466,7 @@ site/templates/common/mail/ms.json
|
||||||
site/templates/common/mail/tr.json
|
site/templates/common/mail/tr.json
|
||||||
site/templates/common/mail/vi.json
|
site/templates/common/mail/vi.json
|
||||||
site/templates/common/mail/zh_CN.json
|
site/templates/common/mail/zh_CN.json
|
||||||
|
site/templates/common/mail/zh_TW.json
|
||||||
site/templates/common/mail_2fcode.tpl
|
site/templates/common/mail_2fcode.tpl
|
||||||
site/templates/common/mail_certificateConfirm.tpl
|
site/templates/common/mail_certificateConfirm.tpl
|
||||||
site/templates/common/mail_certificateReset.tpl
|
site/templates/common/mail_certificateReset.tpl
|
||||||
|
@ -481,6 +485,7 @@ t/01-AuthDemo.t
|
||||||
t/01-CSP-and-CORS-headers.t
|
t/01-CSP-and-CORS-headers.t
|
||||||
t/01-Handler-redirection-and-URL-check-by-portal.t
|
t/01-Handler-redirection-and-URL-check-by-portal.t
|
||||||
t/01-pdata.t
|
t/01-pdata.t
|
||||||
|
t/01-Unauth-Logout.t
|
||||||
t/02-Password-Demo-Local-noPpolicy.t
|
t/02-Password-Demo-Local-noPpolicy.t
|
||||||
t/02-Password-Demo-Local-Ppolicy.t
|
t/02-Password-Demo-Local-Ppolicy.t
|
||||||
t/02-Password-Demo.t
|
t/02-Password-Demo.t
|
||||||
|
@ -657,6 +662,7 @@ t/64-StayConnected-with-History.t
|
||||||
t/65-AutoSignin.t
|
t/65-AutoSignin.t
|
||||||
t/66-CDA-already-auth.t
|
t/66-CDA-already-auth.t
|
||||||
t/66-CDA-PSGI-Try.t
|
t/66-CDA-PSGI-Try.t
|
||||||
|
t/66-CDA-with-doubleCookies.t
|
||||||
t/66-CDA-with-REST.t
|
t/66-CDA-with-REST.t
|
||||||
t/66-CDA-with-SOAP.t
|
t/66-CDA-with-SOAP.t
|
||||||
t/66-CDA.t
|
t/66-CDA.t
|
||||||
|
@ -686,6 +692,7 @@ t/69-FavApps.t
|
||||||
t/70-2F-TOTP-8-with-global-storage.t
|
t/70-2F-TOTP-8-with-global-storage.t
|
||||||
t/70-2F-TOTP-and-U2F-with-TTL-and-JSON.t
|
t/70-2F-TOTP-and-U2F-with-TTL-and-JSON.t
|
||||||
t/70-2F-TOTP-with-History-and-Refresh.t
|
t/70-2F-TOTP-with-History-and-Refresh.t
|
||||||
|
t/70-2F-TOTP-with-Range.t
|
||||||
t/70-2F-TOTP-with-TTL-and-JSON.t
|
t/70-2F-TOTP-with-TTL-and-JSON.t
|
||||||
t/70-2F-TOTP-with-TTL-and-XML.t
|
t/70-2F-TOTP-with-TTL-and-XML.t
|
||||||
t/70-2F-TOTP-with-TTL.t
|
t/70-2F-TOTP-with-TTL.t
|
||||||
|
@ -705,6 +712,7 @@ t/76-2F-Ext-with-CodeActivation.t
|
||||||
t/76-2F-Ext-with-GrantSession.t
|
t/76-2F-Ext-with-GrantSession.t
|
||||||
t/76-2F-Ext-with-History.t
|
t/76-2F-Ext-with-History.t
|
||||||
t/77-2F-Extra.t
|
t/77-2F-Extra.t
|
||||||
|
t/77-2F-Mail-SessionKey.t
|
||||||
t/77-2F-Mail-with-global-storage.t
|
t/77-2F-Mail-with-global-storage.t
|
||||||
t/77-2F-Mail.t
|
t/77-2F-Mail.t
|
||||||
t/78-2F-Upgrade-Many.t
|
t/78-2F-Upgrade-Many.t
|
||||||
|
|
|
@ -40,11 +40,20 @@ has ott => (
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
has sessionKey => (
|
||||||
|
is => 'rw',
|
||||||
|
lazy => 1,
|
||||||
|
default => sub {
|
||||||
|
return $_[0]->{conf}->{mail2fSessionKey}
|
||||||
|
|| $_[0]->{conf}->{mailSessionKey};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
sub init {
|
sub init {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
$self->{conf}->{mail2fCodeRegex} ||= '\d{6}';
|
$self->{conf}->{mail2fCodeRegex} ||= '\d{6}';
|
||||||
unless ( $self->conf->{mailSessionKey} ) {
|
unless ( $self->sessionKey ) {
|
||||||
$self->error("Missing 'mailSessionKey' parameter, aborting");
|
$self->error("Missing session key parameter, aborting");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
$self->prefix( $self->conf->{sfPrefix} )
|
$self->prefix( $self->conf->{sfPrefix} )
|
||||||
|
@ -65,7 +74,7 @@ sub run {
|
||||||
$self->logger->debug("Generated two-factor code: $code");
|
$self->logger->debug("Generated two-factor code: $code");
|
||||||
$self->ott->updateToken( $token, __mail2fcode => $code );
|
$self->ott->updateToken( $token, __mail2fcode => $code );
|
||||||
|
|
||||||
my $dest = $req->{sessionInfo}->{ $self->conf->{mailSessionKey} };
|
my $dest = $req->{sessionInfo}->{ $self->sessionKey };
|
||||||
unless ($dest) {
|
unless ($dest) {
|
||||||
$self->logger->error( "Could not find mail attribute for login "
|
$self->logger->error( "Could not find mail attribute for login "
|
||||||
. $req->{sessionInfo}->{_user} );
|
. $req->{sessionInfo}->{_user} );
|
||||||
|
|
|
@ -4,13 +4,18 @@ use strict;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
|
|
||||||
# Add constants used by this module
|
# Add constants used by this module
|
||||||
use Lemonldap::NG::Portal::Main::Constants
|
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||||
qw(PE_OK PE_FORBIDDENIP PE_USERNOTFOUND);
|
PE_OK
|
||||||
use Lemonldap::NG::Portal::Lib::Slave;
|
PE_FORBIDDENIP
|
||||||
|
PE_USERNOTFOUND
|
||||||
|
);
|
||||||
|
|
||||||
our $VERSION = '2.1.0';
|
our $VERSION = '2.1.0';
|
||||||
|
|
||||||
extends 'Lemonldap::NG::Portal::Main::Auth';
|
extends qw(
|
||||||
|
Lemonldap::NG::Portal::Main::Auth
|
||||||
|
Lemonldap::NG::Portal::Lib::Slave
|
||||||
|
);
|
||||||
|
|
||||||
# INITIALIZATION
|
# INITIALIZATION
|
||||||
|
|
||||||
|
|
|
@ -455,7 +455,7 @@ sub userModifyPassword {
|
||||||
return PE_LDAPERROR;
|
return PE_LDAPERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
$self->{portal}->userLogger->notice("Password changed for $dn");
|
$self->{portal}->logger->notice("Password changed for $dn");
|
||||||
|
|
||||||
# Rebind as manager for next LDAP operations if we were bound as user
|
# Rebind as manager for next LDAP operations if we were bound as user
|
||||||
$self->bind() if $asUser;
|
$self->bind() if $asUser;
|
||||||
|
@ -588,8 +588,7 @@ sub userModifyPassword {
|
||||||
return PE_WRONGMANAGERACCOUNT
|
return PE_WRONGMANAGERACCOUNT
|
||||||
if ( $mesg->code == 50 || $mesg->code == 8 );
|
if ( $mesg->code == 50 || $mesg->code == 8 );
|
||||||
if ( $mesg->code == 0 ) {
|
if ( $mesg->code == 0 ) {
|
||||||
$self->{portal}
|
$self->{portal}->logger->notice("Password changed for $dn");
|
||||||
->userLogger->notice("Password changed $self->{portal}->{user}");
|
|
||||||
|
|
||||||
# Rebind as manager for next LDAP operations if we were bound as user
|
# Rebind as manager for next LDAP operations if we were bound as user
|
||||||
$self->bind() if $asUser;
|
$self->bind() if $asUser;
|
||||||
|
|
|
@ -5,11 +5,9 @@
|
||||||
# Slave common functions
|
# Slave common functions
|
||||||
package Lemonldap::NG::Portal::Lib::Slave;
|
package Lemonldap::NG::Portal::Lib::Slave;
|
||||||
|
|
||||||
use Exporter;
|
|
||||||
use base qw(Exporter);
|
|
||||||
use strict;
|
use strict;
|
||||||
|
use Mouse;
|
||||||
|
|
||||||
our @EXPORT = qw(checkIP checkHeader);
|
|
||||||
our $VERSION = '2.1.0';
|
our $VERSION = '2.1.0';
|
||||||
|
|
||||||
# RUNNING METHODS
|
# RUNNING METHODS
|
||||||
|
@ -49,4 +47,4 @@ sub checkHeader {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -161,28 +161,29 @@ sub setPortalRoutes {
|
||||||
|
|
||||||
# psgi.js
|
# psgi.js
|
||||||
->addUnauthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
->addUnauthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
||||||
->addAuthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
->addAuthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
||||||
|
|
||||||
# portal.css
|
# portal.css
|
||||||
->addUnauthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
->addUnauthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
||||||
->addAuthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
->addAuthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
||||||
|
|
||||||
# lmerror
|
# lmerror
|
||||||
->addUnauthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
->addUnauthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
||||||
->addAuthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
->addAuthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
||||||
|
|
||||||
# Core REST API
|
# Core REST API
|
||||||
->addUnauthRoute( ping => 'pleaseAuth', ['GET'] )
|
->addUnauthRoute( ping => 'pleaseAuth', ['GET'] )
|
||||||
->addAuthRoute( ping => 'authenticated', ['GET'] )
|
->addAuthRoute( ping => 'authenticated', ['GET'] )
|
||||||
|
|
||||||
# Refresh session
|
# Refresh session
|
||||||
->addAuthRoute( refresh => 'refresh', ['GET'] )
|
->addAuthRoute( refresh => 'refresh', ['GET'] )
|
||||||
|
|
||||||
->addAuthRoute( '*' => 'corsPreflight', ['OPTIONS'] )
|
->addAuthRoute( '*' => 'corsPreflight', ['OPTIONS'] )
|
||||||
->addUnauthRoute( '*' => 'corsPreflight', ['OPTIONS'] )
|
->addUnauthRoute( '*' => 'corsPreflight', ['OPTIONS'] )
|
||||||
|
|
||||||
# Logout
|
# Logout
|
||||||
->addAuthRoute( logout => 'logout', ['GET'] );
|
->addAuthRoute( logout => 'logout', ['GET'] )
|
||||||
|
->addUnauthRoute( logout => 'unauthLogout', ['GET'] );
|
||||||
|
|
||||||
# Default routes must point to routines declared above
|
# Default routes must point to routines declared above
|
||||||
$self->defaultAuthRoute('');
|
$self->defaultAuthRoute('');
|
||||||
|
@ -239,9 +240,11 @@ sub reloadConf {
|
||||||
|
|
||||||
# Initialize templateDir
|
# Initialize templateDir
|
||||||
$self->{templateDir} =
|
$self->{templateDir} =
|
||||||
$self->conf->{templateDir} . '/' . $self->conf->{portalSkin};
|
$self->conf->{templateDir} . '/' . $self->conf->{portalSkin}
|
||||||
|
if ( $self->conf->{templateDir} and $self->conf->{portalSkin} );
|
||||||
unless ( -d $self->{templateDir} ) {
|
unless ( -d $self->{templateDir} ) {
|
||||||
$self->error("Template dir $self->{templateDir} doesn't exist");
|
$self->error("Template dir $self->{templateDir} doesn't exist")
|
||||||
|
if ref( $self->{templateDir} ) eq 'SCALAR';
|
||||||
return $self->fail;
|
return $self->fail;
|
||||||
}
|
}
|
||||||
$self->templateDir(
|
$self->templateDir(
|
||||||
|
@ -526,7 +529,11 @@ sub loadModule {
|
||||||
$self->error("Unable to build $module object: $@");
|
$self->error("Unable to build $module object: $@");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
( $obj and $obj->init ) or return 0;
|
unless ( $obj and $obj->init ) {
|
||||||
|
$self->error("$module init failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
$self->loadedModules->{$module} = $obj;
|
$self->loadedModules->{$module} = $obj;
|
||||||
return $obj;
|
return $obj;
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,6 +179,27 @@ sub checkLogout {
|
||||||
PE_OK;
|
PE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub checkUnauthLogout {
|
||||||
|
my ( $self, $req ) = @_;
|
||||||
|
if ( defined $req->param('logout') ) {
|
||||||
|
$self->userLogger->info('Unauthenticated logout request');
|
||||||
|
$self->logger->debug('Cleaning pdata');
|
||||||
|
$self->logger->debug("Removing $self->{conf}->{cookieName} cookie");
|
||||||
|
$req->pdata({});
|
||||||
|
$req->addCookie(
|
||||||
|
$self->cookie(
|
||||||
|
name => $self->conf->{cookieName},
|
||||||
|
domain => $self->conf->{domain},
|
||||||
|
secure => $self->conf->{securedCookie},
|
||||||
|
expires => 'Wed, 21 Oct 2015 00:00:00 GMT',
|
||||||
|
value => 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$req->steps( [ sub { PE_LOGOUT_OK } ] );
|
||||||
|
}
|
||||||
|
PE_OK;
|
||||||
|
}
|
||||||
|
|
||||||
sub authLogout {
|
sub authLogout {
|
||||||
my ( $self, $req ) = @_;
|
my ( $self, $req ) = @_;
|
||||||
my $res = $self->_authentication->authLogout($req);
|
my $res = $self->_authentication->authLogout($req);
|
||||||
|
@ -349,7 +370,7 @@ sub authenticate {
|
||||||
$req->steps( [
|
$req->steps( [
|
||||||
'setSessionInfo', 'setMacros',
|
'setSessionInfo', 'setMacros',
|
||||||
'setPersistentSessionInfo', 'storeHistory',
|
'setPersistentSessionInfo', 'storeHistory',
|
||||||
@{ $self->afterData }, sub { PE_BADCREDENTIALS }
|
@{ $self->afterData }, sub { PE_BADCREDENTIALS }
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -133,10 +133,11 @@ sub login {
|
||||||
return $self->do(
|
return $self->do(
|
||||||
$req,
|
$req,
|
||||||
[
|
[
|
||||||
'controlUrl', @{ $self->beforeAuth },
|
'checkUnauthLogout', 'controlUrl', # Fix 2342
|
||||||
$self->authProcess, @{ $self->betweenAuthAndData },
|
@{ $self->beforeAuth }, $self->authProcess,
|
||||||
$self->sessionData, @{ $self->afterData },
|
@{ $self->betweenAuthAndData }, $self->sessionData,
|
||||||
$self->validSession, @{ $self->endAuth },
|
@{ $self->afterData }, $self->validSession,
|
||||||
|
@{ $self->endAuth }
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -146,11 +147,11 @@ sub postLogin {
|
||||||
return $self->do(
|
return $self->do(
|
||||||
$req,
|
$req,
|
||||||
[
|
[
|
||||||
'restoreArgs', 'controlUrl',
|
'checkUnauthLogout', 'restoreArgs', # Fix 2342
|
||||||
@{ $self->beforeAuth }, $self->authProcess,
|
'controlUrl', @{ $self->beforeAuth },
|
||||||
@{ $self->betweenAuthAndData }, $self->sessionData,
|
$self->authProcess, @{ $self->betweenAuthAndData },
|
||||||
@{ $self->afterData }, $self->validSession,
|
$self->sessionData, @{ $self->afterData },
|
||||||
@{ $self->endAuth },
|
$self->validSession, @{ $self->endAuth }
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -232,6 +233,24 @@ sub logout {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub unauthLogout {
|
||||||
|
my ( $self, $req ) = @_;
|
||||||
|
$self->userLogger->info('Unauthenticated logout request');
|
||||||
|
$self->logger->debug('Cleaning pdata');
|
||||||
|
$self->logger->debug("Removing $self->{conf}->{cookieName} cookie");
|
||||||
|
$req->pdata( {} );
|
||||||
|
$req->addCookie(
|
||||||
|
$self->cookie(
|
||||||
|
name => $self->conf->{cookieName},
|
||||||
|
domain => $self->conf->{domain},
|
||||||
|
secure => $self->conf->{securedCookie},
|
||||||
|
expires => 'Wed, 21 Oct 2015 00:00:00 GMT',
|
||||||
|
value => 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return $self->do( $req, [ sub { PE_LOGOUT_OK } ] );
|
||||||
|
}
|
||||||
|
|
||||||
# RUNNING METHODS
|
# RUNNING METHODS
|
||||||
# ---------------
|
# ---------------
|
||||||
|
|
||||||
|
@ -1051,7 +1070,7 @@ sub registerLogin {
|
||||||
}
|
}
|
||||||
|
|
||||||
my $history = $req->sessionInfo->{_loginHistory} ||= {};
|
my $history = $req->sessionInfo->{_loginHistory} ||= {};
|
||||||
my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login';
|
my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login';
|
||||||
$history->{$type} ||= [];
|
$history->{$type} ||= [];
|
||||||
$self->logger->debug("Current login saved into $type");
|
$self->logger->debug("Current login saved into $type");
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,10 @@ sub _modifyPassword {
|
||||||
my $res = $self->modifyPassword( $req, $req->data->{newpassword} );
|
my $res = $self->modifyPassword( $req, $req->data->{newpassword} );
|
||||||
if ( $res == PE_PASSWORD_OK ) {
|
if ( $res == PE_PASSWORD_OK ) {
|
||||||
$self->logger->debug( 'Update password in session for ' . $req->user );
|
$self->logger->debug( 'Update password in session for ' . $req->user );
|
||||||
|
my $userlog = $req->sessionInfo->{ $self->conf->{whatToTrace} };
|
||||||
|
my $iplog = $req->sessionInfo->{ipAddr};
|
||||||
|
$self->userLogger->notice("Password changed for $userlog ($iplog)")
|
||||||
|
if ( defined $userlog and $iplog );
|
||||||
my $infos;
|
my $infos;
|
||||||
|
|
||||||
# Store new password if asked
|
# Store new password if asked
|
||||||
|
|
|
@ -18,9 +18,8 @@ our $VERSION = '2.1.0';
|
||||||
|
|
||||||
sub init {
|
sub init {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
$self->ldap
|
return ( $self->Lemonldap::NG::Portal::Password::Base::init
|
||||||
and $self->filter
|
and $self->Lemonldap::NG::Portal::Lib::LDAP::init );
|
||||||
and $self->Lemonldap::NG::Portal::Password::Base::init;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Confirmation is done by Lib::Net::LDAP::userModifyPassword
|
# Confirmation is done by Lib::Net::LDAP::userModifyPassword
|
||||||
|
|
|
@ -4,6 +4,7 @@ use strict;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||||
PE_APACHESESSIONERROR
|
PE_APACHESESSIONERROR
|
||||||
|
PE_ERROR
|
||||||
PE_OK
|
PE_OK
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -37,9 +38,18 @@ sub changeUrldc {
|
||||||
$cdaInfos->{cookie_name} = $self->{conf}->{cookieName};
|
$cdaInfos->{cookie_name} = $self->{conf}->{cookieName};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$cdaInfos->{cookie_value} =
|
if ( $req->{sessionInfo}->{_httpSession} ) {
|
||||||
$req->{sessionInfo}->{_httpSession};
|
$cdaInfos->{cookie_value} =
|
||||||
$cdaInfos->{cookie_name} = $self->{conf}->{cookieName} . "http";
|
$req->{sessionInfo}->{_httpSession};
|
||||||
|
$cdaInfos->{cookie_name} = $self->{conf}->{cookieName} . "http";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->logger->error(
|
||||||
|
"Session does not contain _httpSession field. "
|
||||||
|
. "Portal must be accessed over HTTPS when using CDA with double cookie"
|
||||||
|
);
|
||||||
|
return PE_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
my $cdaSession =
|
my $cdaSession =
|
||||||
|
|
|
@ -23,7 +23,7 @@ sub init {
|
||||||
}
|
}
|
||||||
$self->addUnauthRoute( checkstate => 'check', ['GET'] )
|
$self->addUnauthRoute( checkstate => 'check', ['GET'] )
|
||||||
->addAuthRoute( checkstate => 'check', ['GET'] );
|
->addAuthRoute( checkstate => 'check', ['GET'] );
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ sub check {
|
||||||
# - "buildCookie" useless here
|
# - "buildCookie" useless here
|
||||||
$req->steps( [
|
$req->steps( [
|
||||||
'getUser', 'authenticate',
|
'getUser', 'authenticate',
|
||||||
@{ $self->p->betweenAuthAndData }, $self->sessionData,
|
@{ $self->p->betweenAuthAndData }, $self->p->sessionData,
|
||||||
@{ $self->p->afterData }, 'storeHistory',
|
@{ $self->p->afterData }, 'storeHistory',
|
||||||
@{ $self->p->endAuth }
|
@{ $self->p->endAuth }
|
||||||
]
|
]
|
||||||
|
|
|
@ -115,7 +115,9 @@ sub display {
|
||||||
$self->userLogger->info("Using spoofed SSO groups if exist")
|
$self->userLogger->info("Using spoofed SSO groups if exist")
|
||||||
if ( $self->conf->{impersonationRule} );
|
if ( $self->conf->{impersonationRule} );
|
||||||
|
|
||||||
$attrs = $self->_removePersistentAttributes($attrs)
|
$attrs =
|
||||||
|
$self->_removeKeys( $attrs, $self->persistentAttrs,
|
||||||
|
'Remove persistent session attributes...' )
|
||||||
unless $self->displayPersistentInfoRule->( $req, $req->userData );
|
unless $self->displayPersistentInfoRule->( $req, $req->userData );
|
||||||
|
|
||||||
# Create an array of hashes and dispatch attributes for template loop
|
# Create an array of hashes and dispatch attributes for template loop
|
||||||
|
@ -180,8 +182,7 @@ sub check {
|
||||||
LOGIN => '',
|
LOGIN => '',
|
||||||
TOKEN => $token,
|
TOKEN => $token,
|
||||||
};
|
};
|
||||||
return $self->p->sendJSONresponse( $req, $params )
|
return $self->p->sendJSONresponse( $req, $params ) if $req->wantJSON;
|
||||||
if ( $req->wantJSON );
|
|
||||||
return $self->p->sendHtml( $req, 'checkuser', params => $params )
|
return $self->p->sendHtml( $req, 'checkuser', params => $params )
|
||||||
if $msg;
|
if $msg;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +196,7 @@ sub check {
|
||||||
$user = '';
|
$user = '';
|
||||||
$attrs = {};
|
$attrs = {};
|
||||||
return $self->p->sendError( $req, 'Malformed user', 400 )
|
return $self->p->sendError( $req, 'Malformed user', 400 )
|
||||||
if ( $req->wantJSON );
|
if $req->wantJSON;
|
||||||
return $self->p->sendHtml(
|
return $self->p->sendHtml(
|
||||||
$req,
|
$req,
|
||||||
'checkuser',
|
'checkuser',
|
||||||
|
@ -219,7 +220,7 @@ sub check {
|
||||||
if ( !$user or $user eq $req->{user} ) {
|
if ( !$user or $user eq $req->{user} ) {
|
||||||
$self->userLogger->info("checkUser requested for himself");
|
$self->userLogger->info("checkUser requested for himself");
|
||||||
$self->userLogger->info("Using spoofed SSO groups if exist")
|
$self->userLogger->info("Using spoofed SSO groups if exist")
|
||||||
if ( $self->conf->{impersonationRule} );
|
if $self->conf->{impersonationRule};
|
||||||
$attrs = $req->userData;
|
$attrs = $req->userData;
|
||||||
$user = $req->{user};
|
$user = $req->{user};
|
||||||
}
|
}
|
||||||
|
@ -262,7 +263,10 @@ sub check {
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check identities rule
|
# Check identities rule
|
||||||
$self->logger->info("\"$user\" is an unrestricted user!") if $unUser;
|
$self->logger->info( '"'
|
||||||
|
. $savedUserData->{ $self->conf->{whatToTrace} }
|
||||||
|
. '" is an unrestricted user!' )
|
||||||
|
if $unUser;
|
||||||
unless ( $unUser || $self->idRule->( $req, $attrs ) ) {
|
unless ( $unUser || $self->idRule->( $req, $attrs ) ) {
|
||||||
$self->userLogger->warn(
|
$self->userLogger->warn(
|
||||||
"checkUser requested for an invalid user ($user)");
|
"checkUser requested for an invalid user ($user)");
|
||||||
|
@ -279,8 +283,10 @@ sub check {
|
||||||
$attrs = {};
|
$attrs = {};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$msg = 'checkUser' . $self->merged;
|
$msg = 'checkUser' . $self->merged;
|
||||||
$attrs = $self->_removePersistentAttributes($attrs)
|
$attrs =
|
||||||
|
$self->_removeKeys( $attrs, $self->persistentAttrs,
|
||||||
|
'Remove persistent session attributes...' )
|
||||||
unless $self->displayPersistentInfoRule->( $req, $savedUserData );
|
unless $self->displayPersistentInfoRule->( $req, $savedUserData );
|
||||||
|
|
||||||
if ($computed) {
|
if ($computed) {
|
||||||
|
@ -320,17 +326,23 @@ sub check {
|
||||||
$self->_createArray( $req, $attrs, $savedUserData ) );
|
$self->_createArray( $req, $attrs, $savedUserData ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( $self->p->checkXSSAttack( 'CheckUser URL', $url ) ) {
|
||||||
|
$url = '';
|
||||||
|
$auth = 'VHnotFound';
|
||||||
|
}
|
||||||
|
|
||||||
# Check if user is allowed to access submitted URL and compute headers
|
# Check if user is allowed to access submitted URL and compute headers
|
||||||
if ( $url and %$attrs ) {
|
if ( $url and %$attrs ) {
|
||||||
|
|
||||||
# Check url format
|
# Check url format
|
||||||
$url = $self->_urlFormat($url);
|
my $originalUrl;
|
||||||
|
( $url, $originalUrl ) = $self->_resolveURL( $req, $url );
|
||||||
|
|
||||||
# User is allowed ?
|
# User is allowed ?
|
||||||
$self->logger->debug(
|
$self->logger->debug(
|
||||||
"checkUser requested for user: $attrs->{ $self->{conf}->{whatToTrace} } and URL: $url"
|
"checkUser requested for user: $attrs->{ $self->{conf}->{whatToTrace} } and URL: $url | alias: $originalUrl"
|
||||||
);
|
);
|
||||||
$auth = $self->_authorization( $req, $url, $attrs );
|
$auth = $self->_authorization( $req, $originalUrl, $attrs );
|
||||||
if ( $auth >= 0 ) {
|
if ( $auth >= 0 ) {
|
||||||
$auth = $auth ? "allowed" : "forbidden";
|
$auth = $auth ? "allowed" : "forbidden";
|
||||||
$self->logger->debug(
|
$self->logger->debug(
|
||||||
|
@ -338,7 +350,8 @@ sub check {
|
||||||
. "$auth to access to $url" );
|
. "$auth to access to $url" );
|
||||||
|
|
||||||
# Return VirtualHost headers
|
# Return VirtualHost headers
|
||||||
$array_hdrs = $self->_headers( $req, $url, $attrs, $savedUserData );
|
$array_hdrs =
|
||||||
|
$self->_headers( $req, $originalUrl, $attrs, $savedUserData );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$auth = 'VHnotFound';
|
$auth = 'VHnotFound';
|
||||||
|
@ -352,17 +365,14 @@ sub check {
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
my $params = {
|
my $params = {
|
||||||
PORTAL => $self->conf->{portal},
|
PORTAL => $self->conf->{portal},
|
||||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||||
SKIN => $self->p->getSkin($req),
|
SKIN => $self->p->getSkin($req),
|
||||||
LANGS => $self->conf->{showLanguages},
|
LANGS => $self->conf->{showLanguages},
|
||||||
MSG => $msg,
|
MSG => $msg,
|
||||||
ALERTE => ( $msg eq 'checkUser' ? 'alert-info' : 'alert-warning' ),
|
ALERTE => ( $msg eq 'checkUser' ? 'alert-info' : 'alert-warning' ),
|
||||||
LOGIN => $user,
|
LOGIN => $user,
|
||||||
URL => (
|
URL => $url,
|
||||||
$self->p->checkXSSAttack( 'URL', $url ) ? ""
|
|
||||||
: $url
|
|
||||||
),
|
|
||||||
ALLOWED => $auth,
|
ALLOWED => $auth,
|
||||||
ALERTE_AUTH => $alert_auth,
|
ALERTE_AUTH => $alert_auth,
|
||||||
HEADERS => $array_hdrs,
|
HEADERS => $array_hdrs,
|
||||||
|
@ -370,7 +380,8 @@ sub check {
|
||||||
MACROS => $array_attrs->[1],
|
MACROS => $array_attrs->[1],
|
||||||
GROUPS => $array_attrs->[0],
|
GROUPS => $array_attrs->[0],
|
||||||
TOKEN => (
|
TOKEN => (
|
||||||
$self->ottRule->( $req, {} ) ? $self->ott->createToken()
|
$self->ottRule->( $req, {} )
|
||||||
|
? $self->ott->createToken()
|
||||||
: ''
|
: ''
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
@ -380,17 +391,24 @@ sub check {
|
||||||
return $self->p->sendHtml( $req, 'checkuser', params => $params );
|
return $self->p->sendHtml( $req, 'checkuser', params => $params );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _urlFormat {
|
sub _resolveURL {
|
||||||
my ( $self, $url ) = @_;
|
my ( $self, $req, $url ) = @_;
|
||||||
$url = 'http://' . $url unless ( $url =~ m#^https?://[^/]*.*#i );
|
my ($proto) = $url =~ m#^(https?://).*#i;
|
||||||
my ( $proto, $vhost, $appuri ) = $url =~ m#^(https?://)([^/]*)(.*)#i;
|
my ( $vhost, $appuri ) = $url =~ m#^(?:https?://)?([^/]*)(.*)#i;
|
||||||
my ($port) = $vhost =~ m#^.+(:\d+)$#;
|
my ($port) = $vhost =~ m#^.+(:\d+)$#;
|
||||||
|
|
||||||
$port ||= '';
|
$port ||= '';
|
||||||
$vhost =~ s/:\d+$//;
|
$vhost =~ s/:\d+$//;
|
||||||
$vhost .= $self->conf->{domain} unless ( $vhost =~ /\./ );
|
$vhost .= $self->conf->{domain} unless ( $vhost =~ /\./ );
|
||||||
|
$proto =
|
||||||
|
$self->p->HANDLER->_isHttps( $req, $vhost ) ? 'https://' : 'http://'
|
||||||
|
unless $proto;
|
||||||
|
$self->logger->debug( 'VHost is ' . uc( ( split( /:/, $proto ) )[0] ) );
|
||||||
|
my $originalVhost = $self->p->HANDLER->resolveAlias($vhost);
|
||||||
|
|
||||||
return lc("$proto$vhost$port") . "$appuri";
|
return (
|
||||||
|
lc("$proto$vhost$port") . $appuri,
|
||||||
|
lc("$proto$originalVhost$port") . $appuri
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _userData {
|
sub _userData {
|
||||||
|
@ -407,12 +425,9 @@ sub _userData {
|
||||||
: push @$steps, 'setLocalGroups';
|
: push @$steps, 'setLocalGroups';
|
||||||
$req->steps($steps);
|
$req->steps($steps);
|
||||||
if ( my $error = $self->p->process($req) ) {
|
if ( my $error = $self->p->process($req) ) {
|
||||||
if ( $error == PE_BADCREDENTIALS ) {
|
$self->userLogger->warn(
|
||||||
$self->userLogger->warn(
|
'checkUser requested for an invalid user (' . $req->{user} . ")" )
|
||||||
'checkUser requested for an invalid user ('
|
if ( $error == PE_BADCREDENTIALS );
|
||||||
. $req->{user}
|
|
||||||
. ")" );
|
|
||||||
}
|
|
||||||
$self->logger->debug("Process returned error: $error");
|
$self->logger->debug("Process returned error: $error");
|
||||||
return $req->error(PE_BADCREDENTIALS);
|
return $req->error(PE_BADCREDENTIALS);
|
||||||
}
|
}
|
||||||
|
@ -468,16 +483,48 @@ sub _headers {
|
||||||
$vhost =~ s/:\d+$//;
|
$vhost =~ s/:\d+$//;
|
||||||
$req->{env}->{HTTP_HOST} = $vhost;
|
$req->{env}->{HTTP_HOST} = $vhost;
|
||||||
$self->p->HANDLER->headersInit( $self->{conf} );
|
$self->p->HANDLER->headersInit( $self->{conf} );
|
||||||
|
my $headers = $self->p->HANDLER->checkHeaders( $req, $attrs );
|
||||||
|
|
||||||
|
# Remove hidden headers relative to VHost if required
|
||||||
|
unless ( $self->unrestrictedUsersRule->( $req, $savedUserData ) ) {
|
||||||
|
my $keysToRemove = '';
|
||||||
|
$keysToRemove = '__all__'
|
||||||
|
if exists $self->conf->{checkUserHiddenHeaders}->{$vhost};
|
||||||
|
$keysToRemove = $self->conf->{checkUserHiddenHeaders}->{$vhost}
|
||||||
|
if ( $keysToRemove
|
||||||
|
&& $self->conf->{checkUserHiddenHeaders}->{$vhost} =~ /\w+/ );
|
||||||
|
|
||||||
|
if ( $keysToRemove eq '__all__' ) {
|
||||||
|
$self->logger->debug(
|
||||||
|
"Overwrite for VirtualHost: $vhost ALL valued header(s)...");
|
||||||
|
@$headers = map {
|
||||||
|
$_->{value} =~ /\w+/
|
||||||
|
? { key => $_->{key}, value => '******' }
|
||||||
|
: $_
|
||||||
|
} @$headers;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->logger->debug(
|
||||||
|
"Mask hidden header(s) for VirtualHost: $vhost");
|
||||||
|
my $hash = { map { $_->{key} => $_->{value} } @$headers };
|
||||||
|
$hash = $self->_removeKeys( $hash, $keysToRemove,
|
||||||
|
"Overwrite valued \"$keysToRemove\" header(s)...", 1 );
|
||||||
|
@$headers = (
|
||||||
|
map { { key => $_, value => $hash->{$_} } }
|
||||||
|
sort keys %$hash
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove empty headers if required
|
||||||
|
unless ( $self->displayEmptyHeadersRule->( $req, $savedUserData ) ) {
|
||||||
|
$self->logger->debug("Remove empty headers...");
|
||||||
|
@$headers = grep $_->{value} =~ /.+/, @$headers;
|
||||||
|
}
|
||||||
$self->logger->debug(
|
$self->logger->debug(
|
||||||
"Return \"$attrs->{ $self->{conf}->{whatToTrace} }\" headers");
|
"Return \"$attrs->{ $self->{conf}->{whatToTrace} }\" headers");
|
||||||
return $self->p->HANDLER->checkHeaders( $req, $attrs )
|
|
||||||
if ( $self->displayEmptyHeadersRule->( $req, $savedUserData ) );
|
|
||||||
|
|
||||||
$self->logger->debug("Remove empty headers");
|
return $headers;
|
||||||
my @headers = grep $_->{value} =~ /.+/,
|
|
||||||
@{ $self->p->HANDLER->checkHeaders( $req, $attrs ) };
|
|
||||||
|
|
||||||
return \@headers;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _createArray {
|
sub _createArray {
|
||||||
|
@ -511,7 +558,7 @@ sub _dispatchAttributes {
|
||||||
my ( $grps, $mcrs, $others ) = ( [], [], [] );
|
my ( $grps, $mcrs, $others ) = ( [], [], [] );
|
||||||
my $macros = $self->{conf}->{macros};
|
my $macros = $self->{conf}->{macros};
|
||||||
|
|
||||||
$self->logger->debug("Dispatching attributes...");
|
$self->logger->debug("Dispatch attributes...");
|
||||||
while (@$attrs) {
|
while (@$attrs) {
|
||||||
my $element = shift @$attrs;
|
my $element = shift @$attrs;
|
||||||
$self->logger->debug( "Processing element: $element->{key} => "
|
$self->logger->debug( "Processing element: $element->{key} => "
|
||||||
|
@ -539,9 +586,9 @@ sub _dispatchAttributes {
|
||||||
|
|
||||||
# Sort real and spoofed attributes if required
|
# Sort real and spoofed attributes if required
|
||||||
if ( $self->sorted ) {
|
if ( $self->sorted ) {
|
||||||
$self->logger->debug('Dispatching real and spoofed attributes...');
|
$self->logger->debug('Sort real and spoofed attributes...');
|
||||||
my ( $realAttrs, $spoofedAttrs ) = ( [], [] );
|
my ( $realAttrs, $spoofedAttrs ) = ( [], [] );
|
||||||
my $prefix = "$self->{conf}->{impersonationPrefix}";
|
my $prefix = $self->{conf}->{impersonationPrefix};
|
||||||
while (@$others) {
|
while (@$others) {
|
||||||
my $element = shift @$others;
|
my $element = shift @$others;
|
||||||
$self->logger->debug( "Processing attribute $element->{key} => "
|
$self->logger->debug( "Processing attribute $element->{key} => "
|
||||||
|
@ -560,12 +607,22 @@ sub _dispatchAttributes {
|
||||||
return [ $grps, $mcrs, $others ];
|
return [ $grps, $mcrs, $others ];
|
||||||
}
|
}
|
||||||
|
|
||||||
sub _removePersistentAttributes {
|
sub _removeKeys {
|
||||||
my ( $self, $attrs ) = @_;
|
my ( $self, $attrs, $hidden, $msg, $mask ) = @_;
|
||||||
my $regex = join '|', split /\s+/, $self->persistentAttrs;
|
my $regex = join '|', split /\s+/, $hidden;
|
||||||
my @keys = grep /$regex/, keys %$attrs;
|
my @keys = grep /$regex/, keys %$attrs;
|
||||||
$self->logger->debug("Remove persistent session attributes");
|
|
||||||
delete @$attrs{@keys};
|
$self->logger->debug($msg);
|
||||||
|
if ($mask) {
|
||||||
|
$self->userLogger->info('Hide some headers');
|
||||||
|
foreach (@keys) {
|
||||||
|
$attrs->{$_} = '******' if $attrs->{$_} =~ /\w+/;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->userLogger->info('Remove some headers');
|
||||||
|
delete @$attrs{@keys};
|
||||||
|
}
|
||||||
|
|
||||||
return $attrs;
|
return $attrs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,7 +140,7 @@ sub display {
|
||||||
sub run {
|
sub run {
|
||||||
my ( $self, $req ) = @_;
|
my ( $self, $req ) = @_;
|
||||||
my $statut = PE_OK;
|
my $statut = PE_OK;
|
||||||
my $realId = $req->{user};
|
my $realId = $req->userData->{ $self->conf->{whatToTrace} };
|
||||||
my $spoofId = $req->param('spoofId') || ''; # ContextSwitching required ?
|
my $spoofId = $req->param('spoofId') || ''; # ContextSwitching required ?
|
||||||
my $unUser = $self->unrestrictedUsersRule->( $req, $req->userData ) || 0;
|
my $unUser = $self->unrestrictedUsersRule->( $req, $req->userData ) || 0;
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ sub _switchContext {
|
||||||
my ( $self, $req, $spoofId, $unUser ) = @_;
|
my ( $self, $req, $spoofId, $unUser ) = @_;
|
||||||
my $realSessionId = $req->userData->{_session_id};
|
my $realSessionId = $req->userData->{_session_id};
|
||||||
my $realAuthLevel = $req->userData->{authenticationLevel};
|
my $realAuthLevel = $req->userData->{authenticationLevel};
|
||||||
my $realId = $req->{user};
|
my $realId = $req->userData->{ $self->conf->{whatToTrace} };
|
||||||
my $raz = 0;
|
my $raz = 0;
|
||||||
$req->{user} = $spoofId;
|
$req->{user} = $spoofId;
|
||||||
|
|
||||||
|
|
|
@ -54,9 +54,9 @@ sub run {
|
||||||
my ( $self, $req ) = @_;
|
my ( $self, $req ) = @_;
|
||||||
my $user = $req->{userData}->{ $self->conf->{whatToTrace} };
|
my $user = $req->{userData}->{ $self->conf->{whatToTrace} };
|
||||||
|
|
||||||
# Check activation rules
|
# Check activation rule
|
||||||
unless ( $self->rule->( $req, $req->userData ) ) {
|
unless ( $self->rule->( $req, $req->userData ) ) {
|
||||||
$self->userLogger->info("Global logout not required for $user");
|
$self->userLogger->info("GlobaLogout not allowed for $user");
|
||||||
return PE_OK;
|
return PE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,20 +116,22 @@ sub globalLogout {
|
||||||
# Read active sessions from token
|
# Read active sessions from token
|
||||||
my $sessions = eval { from_json( $token->{sessions} ) };
|
my $sessions = eval { from_json( $token->{sessions} ) };
|
||||||
if ($@) {
|
if ($@) {
|
||||||
$self->logger->error("Bad encoding in OTT: $@");
|
$self->logger->error(
|
||||||
|
"GlobalLogout: bad encoding in OTT ($@)");
|
||||||
$res = PE_ERROR;
|
$res = PE_ERROR;
|
||||||
}
|
}
|
||||||
my $as;
|
my $as;
|
||||||
foreach (@$sessions) {
|
my $user = $token->{user};
|
||||||
unless ( $as = $self->p->getApacheSession( $_->{id} ) ) {
|
my $req_user =
|
||||||
$self->userLogger->info(
|
$req->{userData}->{ $self->{conf}->{whatToTrace} };
|
||||||
"GlobalLogout: session $_->{id} expired");
|
if ( $req_user eq $user ) {
|
||||||
next;
|
foreach (@$sessions) {
|
||||||
}
|
unless ( $as = $self->p->getApacheSession( $_->{id} ) )
|
||||||
my $user = $token->{user};
|
{
|
||||||
if ( $req->{userData}->{ $self->{conf}->{whatToTrace} } eq
|
$self->userLogger->info(
|
||||||
$user )
|
"GlobalLogout: session $_->{id} expired");
|
||||||
{
|
next;
|
||||||
|
}
|
||||||
unless ( $req->{userData}->{_session_id} eq $_->{id} ) {
|
unless ( $req->{userData}->{_session_id} eq $_->{id} ) {
|
||||||
$self->userLogger->info(
|
$self->userLogger->info(
|
||||||
"Remove \"$user\" session: $_->{id}");
|
"Remove \"$user\" session: $_->{id}");
|
||||||
|
@ -137,11 +139,12 @@ sub globalLogout {
|
||||||
$count++;
|
$count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
$self->userLogger->warn(
|
else {
|
||||||
"GlobalLogout called with an invalid token");
|
$self->userLogger->warn(
|
||||||
$res = PE_TOKENEXPIRED;
|
"GlobalLogout called with an invalid token: $req_user is NOT $user"
|
||||||
}
|
);
|
||||||
|
$res = PE_TOKENEXPIRED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -157,7 +160,7 @@ sub globalLogout {
|
||||||
}
|
}
|
||||||
|
|
||||||
return $self->p->do( $req, [ sub { $res } ] ) if $res;
|
return $self->p->do( $req, [ sub { $res } ] ) if $res;
|
||||||
$self->userLogger->info("$count remaining session(s) have been removed");
|
$self->userLogger->info("$count remaining session(s) removed");
|
||||||
return $self->p->do( $req, [ 'authLogout', 'deleteSession' ] );
|
return $self->p->do( $req, [ 'authLogout', 'deleteSession' ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,16 +180,16 @@ sub activeSessions {
|
||||||
$self->module->searchOn( $moduleOptions, $self->conf->{whatToTrace},
|
$self->module->searchOn( $moduleOptions, $self->conf->{whatToTrace},
|
||||||
$user );
|
$user );
|
||||||
|
|
||||||
$self->logger->debug('Remove corrupted sessions...');
|
$self->logger->debug('Remove non-SSO session(s)...');
|
||||||
my $corrupted = 0;
|
my $other = 0;
|
||||||
foreach ( keys %$sessions ) {
|
foreach ( keys %$sessions ) {
|
||||||
unless ( $sessions->{$_}->{_session_kind} eq 'SSO' ) {
|
unless ( $sessions->{$_}->{_session_kind} eq 'SSO' ) {
|
||||||
delete $sessions->{$_};
|
delete $sessions->{$_};
|
||||||
$corrupted++;
|
$other++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$self->logger->info("$corrupted corrupted session(s) removed")
|
$self->logger->info("$other non-SSO session(s) removed")
|
||||||
if $corrupted;
|
if $other;
|
||||||
|
|
||||||
$self->logger->debug('Build an array ref with sessions info...');
|
$self->logger->debug('Build an array ref with sessions info...');
|
||||||
@$activeSessions =
|
@$activeSessions =
|
||||||
|
|
|
@ -72,16 +72,17 @@ sub run {
|
||||||
$req, 'simpleInfo', params => { trspan => $msg }
|
$req, 'simpleInfo', params => { trspan => $msg }
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
$self->userLogger->error( 'User '
|
$self->userLogger->error( 'User "'
|
||||||
. $req->sessionInfo->{uid}
|
. $req->{sessionInfo}->{ $self->conf->{whatToTrace} }
|
||||||
. " was not granted to open session (rule -> $rule)" );
|
. '" was not granted to open session (rule ->'
|
||||||
|
. "$rule)" );
|
||||||
$req->urldc( $self->conf->{portal} );
|
$req->urldc( $self->conf->{portal} );
|
||||||
return $req->authResult(PE_SESSIONNOTGRANTED);
|
return $req->authResult(PE_SESSIONNOTGRANTED);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$self->userLogger->error( 'User '
|
$self->userLogger->error( 'User "'
|
||||||
. $req->sessionInfo->{uid}
|
. $req->{sessionInfo}->{ $self->conf->{whatToTrace} }
|
||||||
. " was not granted to open session (rule -> "
|
. '" was not granted to open session (rule -> '
|
||||||
. $self->conf->{grantSessionRules}->{$_}
|
. $self->conf->{grantSessionRules}->{$_}
|
||||||
. ")" );
|
. ")" );
|
||||||
$req->urldc( $self->conf->{portal} );
|
$req->urldc( $self->conf->{portal} );
|
||||||
|
|
|
@ -490,6 +490,11 @@ sub changePwd {
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $userlog = $req->sessionInfo->{ $self->conf->{whatToTrace} };
|
||||||
|
my $iplog = $req->sessionInfo->{ipAddr};
|
||||||
|
$self->userLogger->notice("Password changed for $userlog ($iplog)")
|
||||||
|
if ( defined $userlog and $iplog );
|
||||||
|
|
||||||
# Send mail containing the new password
|
# Send mail containing the new password
|
||||||
$req->data->{mailAddress} ||=
|
$req->data->{mailAddress} ||=
|
||||||
$self->p->getFirstValue(
|
$self->p->getFirstValue(
|
||||||
|
|
|
@ -182,7 +182,7 @@ sub removeOther {
|
||||||
}
|
}
|
||||||
|
|
||||||
return $self->p->do( $req, [ sub { $res } ] ) if $res;
|
return $self->p->do( $req, [ sub { $res } ] ) if $res;
|
||||||
$self->userLogger->info("$count remaining session(s) have been removed");
|
$self->userLogger->info("$count remaining session(s) removed");
|
||||||
$req->mustRedirect(1);
|
$req->mustRedirect(1);
|
||||||
return $self->p->autoRedirect($req);
|
return $self->p->autoRedirect($req);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,16 @@ sub setSessionInfo {
|
||||||
%{ $self->conf->{ldapExportedVars} } );
|
%{ $self->conf->{ldapExportedVars} } );
|
||||||
while ( my ( $k, $v ) = each %vars ) {
|
while ( my ( $k, $v ) = each %vars ) {
|
||||||
|
|
||||||
|
my $value = $self->ldap->getLdapValue( $req->data->{ldapentry}, $v );
|
||||||
|
|
||||||
# getLdapValue returns an empty string for missing attribute
|
# getLdapValue returns an empty string for missing attribute
|
||||||
# but we really want to return undef so they don't get stored in session
|
# but we really want to return undef so they don't get stored in session
|
||||||
$req->sessionInfo->{$k} =
|
# This has to be a string comparison because "0" is a valid attribute
|
||||||
$self->ldap->getLdapValue( $req->data->{ldapentry}, $v ) || undef;
|
# value. See #2403
|
||||||
}
|
$value = undef if ( $value eq "" );
|
||||||
|
|
||||||
|
$req->sessionInfo->{$k} = $value;
|
||||||
|
}
|
||||||
PE_OK;
|
PE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,18 @@ package Lemonldap::NG::Portal::UserDB::Slave;
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use Mouse;
|
use Mouse;
|
||||||
use Lemonldap::NG::Portal::Lib::Slave;
|
|
||||||
use Lemonldap::NG::Portal::Main::Constants qw(PE_FORBIDDENIP PE_OK);
|
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||||
|
PE_OK
|
||||||
|
PE_FORBIDDENIP
|
||||||
|
);
|
||||||
|
|
||||||
our $VERSION = '2.1.0';
|
our $VERSION = '2.1.0';
|
||||||
|
|
||||||
extends 'Lemonldap::NG::Common::Module';
|
extends qw(
|
||||||
|
Lemonldap::NG::Common::Module
|
||||||
|
Lemonldap::NG::Portal::Lib::Slave
|
||||||
|
);
|
||||||
|
|
||||||
# INITIALIZATION
|
# INITIALIZATION
|
||||||
|
|
||||||
|
|
|
@ -482,7 +482,7 @@ $(window).on 'load', () ->
|
||||||
$('#newpassword')[0].setCustomValidity(translate('PE28'))
|
$('#newpassword')[0].setCustomValidity(translate('PE28'))
|
||||||
return
|
return
|
||||||
|
|
||||||
if window.datas.ppolicy?
|
if window.datas.ppolicy? and $('#newpassword').length
|
||||||
# Initialize display
|
# Initialize display
|
||||||
checkpassword ''
|
checkpassword ''
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user