Merge branch 'v2.0' into 2683
This commit is contained in:
commit
67aaadf51b
|
@ -61,6 +61,8 @@ build_centos_8:
|
|||
extends: .build_job
|
||||
image: buildpkg/centos:8
|
||||
script:
|
||||
- sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
|
||||
- sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
|
||||
- yum-config-manager --enable PowerTools
|
||||
- yum-config-manager --enable AppStream
|
||||
- yum -y install epel-release
|
||||
|
|
|
@ -10,6 +10,7 @@ Applications
|
|||
applications/awx
|
||||
applications/bugzilla
|
||||
applications/bigbluebutton
|
||||
applications/confluence
|
||||
applications/cornerstone
|
||||
applications/discourse
|
||||
applications/django
|
||||
|
@ -94,6 +95,7 @@ Application Configuration
|
|||
.. image:: applications/logo-awx.png :doc:`AWX (Ansible Tower)<applications/awx>` ✔
|
||||
.. image:: applications/bigbluebutton-logo.png :doc:`BigBlueButton<applications/bigbluebutton>` ✔
|
||||
.. image:: applications/bugzilla_logo.png :doc:`Bugzilla<applications/bugzilla>` ✔
|
||||
.. image:: applications/confluence.png :doc:`Confluence<applications/confluence>` ✔ ✔
|
||||
.. image:: applications/csod_logo.png :doc:`Cornerstone<applications/cornerstone>` ✔
|
||||
.. image:: applications/discourse.jpg :doc:`Discourse<applications/discourse>` ✔ ✔
|
||||
.. image:: applications/django_logo.png :doc:`Django<applications/django>` ✔
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
|
@ -0,0 +1,65 @@
|
|||
Confluence
|
||||
==========
|
||||
|
||||
Presentation
|
||||
------------
|
||||
|
||||
Confluence is a web-based corporate wiki developed by Atlassian.
|
||||
|
||||
It is compatible with SAML and OpenID Connect. This tutorial will focus on SAML.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
||||
You must first configure LemonLDAP::NG as a :doc:`SAML Identity Provider<../idpsaml>`.
|
||||
|
||||
Configure SAML in Confluence
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the SSO configuration page, choose SAML as the authentication method. And set the following parameters.
|
||||
|
||||
Don't forget to replace ``auth.example.com`` with your actual domain.
|
||||
|
||||
* Single sign on issuer: ``https://auth.example.com/saml/metadata``
|
||||
* Identity provider single sign on URL: ``https://auth.example.com/saml/singleSignOn``
|
||||
* X.509 certificate: You can find this certificate in the manager: SAML2 Service » Security » Signature » Public key
|
||||
* Username mapping attribute: ``${uid}``
|
||||
|
||||
.. danger:: Make sure the certificate you copy into Confluence starts with BEGIN CERTIFICATE and not with BEGIN PRIVATE KEY
|
||||
|
||||
Write down the *Assertion Consumer Service URL* and the *Audience URL*, that Confluence is showing you, you will need it to configure LemonLDAP::NG
|
||||
|
||||
Configure LemonLDAP::NG
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In the LemonLDAP::NG Manager, create a new *SAML Service Provider*
|
||||
|
||||
In *Metadata*, copy the following XML document, and don't forget to change ``AUDIENCE_URL`` and ``CONSUMER_SERVICE_URL`` the URLs with the values given by Confluence.
|
||||
|
||||
::
|
||||
|
||||
<?xml version="1.0"?>
|
||||
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
|
||||
entityID="AUDIENCE_URL">
|
||||
<md:SPSSODescriptor
|
||||
AuthnRequestsSigned="false"
|
||||
WantAssertionsSigned="false"
|
||||
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
||||
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>
|
||||
<md:AssertionConsumerService
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
||||
Location="CONSUMER_SERVICE_URL"
|
||||
index="1"/>
|
||||
</md:SPSSODescriptor>
|
||||
</md:EntityDescriptor>
|
||||
|
||||
In *Exported Attributes*, add a new attribute:
|
||||
|
||||
* Variable name: the session variable containing user logins
|
||||
* Attribute name: ``uid``
|
||||
* Mandatory: ``On``
|
||||
|
||||
Finally, in *Options* » *Signature*, set
|
||||
|
||||
* Check SSO message signature: Off
|
||||
* Check SLO message signature: Off
|
|
@ -4,8 +4,8 @@ Error messages
|
|||
|
||||
.. note::
|
||||
|
||||
This page do not reference all error messages, but only the
|
||||
most common
|
||||
This page does not reference all error messages,
|
||||
but only the most common ones
|
||||
|
||||
Lemonldap::NG::Common
|
||||
---------------------
|
||||
|
@ -140,3 +140,10 @@ set ``*`` in trustedDomains to accept all).
|
|||
XSS attack detected
|
||||
|
||||
→ Some URL parameters contain forbidden characters.
|
||||
|
||||
::
|
||||
|
||||
Detailled error codes list
|
||||
|
||||
→ Corresponding error codes can be found in
|
||||
:doc:`Portal error codes<error_codes>`
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
Error codes list
|
||||
================
|
||||
|
||||
.. note::
|
||||
|
||||
This page references all Portal error codes.
|
||||
|
||||
|
||||
```
|
||||
PE_IDPCHOICE => -5,
|
||||
PE_SENDRESPONSE => -4,
|
||||
PE_INFO => -3,
|
||||
PE_REDIRECT => -2,
|
||||
PE_DONE => -1,
|
||||
PE_OK => 0,
|
||||
PE_SESSIONEXPIRED => 1,
|
||||
PE_FORMEMPTY => 2,
|
||||
PE_WRONGMANAGERACCOUNT => 3,
|
||||
PE_USERNOTFOUND => 4,
|
||||
PE_BADCREDENTIALS => 5,
|
||||
PE_LDAPCONNECTFAILED => 6,
|
||||
PE_LDAPERROR => 7,
|
||||
PE_APACHESESSIONERROR => 8,
|
||||
PE_FIRSTACCESS => 9,
|
||||
PE_BADCERTIFICATE => 10,
|
||||
PE_NO_PASSWORD_BE => 20,
|
||||
PE_PP_ACCOUNT_LOCKED => 21,
|
||||
PE_PP_PASSWORD_EXPIRED => 22,
|
||||
PE_CERTIFICATEREQUIRED => 23,
|
||||
PE_ERROR => 24,
|
||||
PE_PP_CHANGE_AFTER_RESET => 25,
|
||||
PE_PP_PASSWORD_MOD_NOT_ALLOWED => 26,
|
||||
PE_PP_MUST_SUPPLY_OLD_PASSWORD => 27,
|
||||
PE_PP_INSUFFICIENT_PASSWORD_QUALITY => 28,
|
||||
PE_PP_PASSWORD_TOO_SHORT => 29,
|
||||
PE_PP_PASSWORD_TOO_YOUNG => 30,
|
||||
PE_PP_PASSWORD_IN_HISTORY => 31,
|
||||
PE_PP_GRACE => 32,
|
||||
PE_PP_EXP_WARNING => 33,
|
||||
PE_PASSWORD_MISMATCH => 34,
|
||||
PE_PASSWORD_OK => 35,
|
||||
PE_NOTIFICATION => 36,
|
||||
PE_BADURL => 37,
|
||||
PE_NOSCHEME => 38,
|
||||
PE_BADOLDPASSWORD => 39,
|
||||
PE_MALFORMEDUSER => 40,
|
||||
PE_SESSIONNOTGRANTED => 41,
|
||||
PE_CONFIRM => 42,
|
||||
PE_MAILFORMEMPTY => 43,
|
||||
PE_BADMAILTOKEN => 44,
|
||||
PE_MAILERROR => 45,
|
||||
PE_MAILOK => 46,
|
||||
PE_LOGOUT_OK => 47,
|
||||
PE_SAML_ERROR => 48,
|
||||
PE_SAML_LOAD_SERVICE_ERROR => 49,
|
||||
PE_SAML_LOAD_IDP_ERROR => 50,
|
||||
PE_SAML_SSO_ERROR => 51,
|
||||
PE_SAML_UNKNOWN_ENTITY => 52,
|
||||
PE_SAML_DESTINATION_ERROR => 53,
|
||||
PE_SAML_CONDITIONS_ERROR => 54,
|
||||
PE_SAML_IDPSSOINITIATED_NOTALLOWED => 55,
|
||||
PE_SAML_SLO_ERROR => 56,
|
||||
PE_SAML_SIGNATURE_ERROR => 57,
|
||||
PE_SAML_ART_ERROR => 58,
|
||||
PE_SAML_SESSION_ERROR => 59,
|
||||
PE_SAML_LOAD_SP_ERROR => 60,
|
||||
PE_SAML_ATTR_ERROR => 61,
|
||||
PE_OPENID_EMPTY => 62,
|
||||
PE_OPENID_BADID => 63,
|
||||
PE_MISSINGREQATTR => 64,
|
||||
PE_BADPARTNER => 65,
|
||||
PE_MAILCONFIRMATION_ALREADY_SENT => 66,
|
||||
PE_PASSWORDFORMEMPTY => 67,
|
||||
PE_CAS_SERVICE_NOT_ALLOWED => 68,
|
||||
PE_MAILFIRSTACCESS => 69,
|
||||
PE_MAILNOTFOUND => 70,
|
||||
PE_PASSWORDFIRSTACCESS => 71,
|
||||
PE_MAILCONFIRMOK => 72,
|
||||
PE_RADIUSCONNECTFAILED => 73,
|
||||
PE_MUST_SUPPLY_OLD_PASSWORD => 74,
|
||||
PE_FORBIDDENIP => 75,
|
||||
PE_CAPTCHAERROR => 76,
|
||||
PE_CAPTCHAEMPTY => 77,
|
||||
PE_REGISTERFIRSTACCESS => 78,
|
||||
PE_REGISTERFORMEMPTY => 79,
|
||||
PE_REGISTERALREADYEXISTS => 80,
|
||||
PE_NOTOKEN => 81,
|
||||
PE_TOKENEXPIRED => 82,
|
||||
PE_U2FFAILED => 83,
|
||||
PE_UNAUTHORIZEDPARTNER => 84,
|
||||
PE_RENEWSESSION => 85,
|
||||
PE_WAIT => 86,
|
||||
PE_MUSTAUTHN => 87,
|
||||
PE_MUSTHAVEMAIL => 88,
|
||||
PE_SAML_SERVICE_NOT_ALLOWED => 89,
|
||||
PE_OIDC_SERVICE_NOT_ALLOWED => 90,
|
||||
PE_OID_SERVICE_NOT_ALLOWED => 91,
|
||||
PE_GET_SERVICE_NOT_ALLOWED => 92,
|
||||
PE_IMPERSONATION_SERVICE_NOT_ALLOWED => 93,
|
||||
PE_ISSUERMISSINGREQATTR => 94,
|
||||
PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED => 95,
|
||||
PE_BADOTP => 96,
|
||||
PE_RESETCERTIFICATE_INVALID => 97,
|
||||
PE_RESETCERTIFICATE_FORMEMPTY => 98,
|
||||
PE_RESETCERTIFICATE_FIRSTACCESS => 99,
|
||||
PE_PP_NOT_ALLOWED_CHARACTER => 100,
|
||||
PE_PP_NOT_ALLOWED_CHARACTERS => 101,
|
||||
PE_UPGRADESESSION => 102,
|
||||
PE_NO_SECOND_FACTORS => 103,
|
||||
PE_BAD_DEVOPS_FILE => 104,
|
||||
PE_FILENOTFOUND => 105,
|
||||
PE_OIDC_AUTH_ERROR => 106
|
||||
```
|
|
@ -339,14 +339,14 @@ Options
|
|||
- **Authentication Level**: required authentication level to access this application
|
||||
- **Access Rule**: lets you specify a :doc:`Perl rule<rules_examples>` to restrict access to this client
|
||||
|
||||
- **Logout**
|
||||
- **Logout**
|
||||
|
||||
- **Allowed redirection addresses for logout**: A space separated list of
|
||||
URLs that this client can redirect the user to once the logout is done
|
||||
(through ``post_logout_redirect_uri``)
|
||||
- **URL**: Specify the relying party's logout URL
|
||||
- **Type**: Type of Logout to perform (only Front-Channel is implemented for now)
|
||||
- **Session required**: Whether to send the Session ID in the logout request
|
||||
- **Allowed redirection addresses for logout**: A space separated list of
|
||||
URLs that this client can redirect the user to once the logout is done
|
||||
(through ``post_logout_redirect_uri``)
|
||||
- **URL**: Specify the relying party's logout URL
|
||||
- **Type**: Type of Logout to perform (only Front-Channel is implemented for now)
|
||||
- **Session required**: Whether to send the Session ID in the logout request
|
||||
|
||||
Access Rule extra variables
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
@ -4,11 +4,14 @@ Advanced features
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
rbac
|
||||
ssoaas
|
||||
servertoserver
|
||||
riskbased
|
||||
smtp
|
||||
notifications
|
||||
passwordstore
|
||||
cda
|
||||
rbac
|
||||
customfunctions
|
||||
extendedfunctions
|
||||
resetpassword
|
||||
|
@ -16,8 +19,6 @@ Advanced features
|
|||
logoutforward
|
||||
securetoken
|
||||
handlerauthbasic
|
||||
ssoaas
|
||||
servertoserver
|
||||
safejail
|
||||
loginhistory
|
||||
fastcgi
|
||||
|
|
|
@ -12,4 +12,5 @@ Exploitation
|
|||
monitoring
|
||||
logs
|
||||
error
|
||||
error_codes
|
||||
highavailability
|
||||
|
|
|
@ -83,20 +83,19 @@ Then, add the official LL::NG repository
|
|||
::
|
||||
|
||||
# LemonLDAP::NG repository
|
||||
deb https://lemonldap-ng.org/deb stable main
|
||||
deb-src https://lemonldap-ng.org/deb stable main
|
||||
deb https://lemonldap-ng.org/deb 2.0 main
|
||||
|
||||
|
||||
.. tip::
|
||||
|
||||
|
||||
|
||||
- Use the ``stable`` repository to get packages from current major
|
||||
version
|
||||
- Use the ``oldstable`` repository to get packages from previous major
|
||||
version
|
||||
- Use the ``testing`` repository to get packages from next major
|
||||
version
|
||||
- Use the ``2.0`` repository to avoid upgrade to next major version
|
||||
|
||||
- Use the ``2.0`` repository to stay on this major version and avoid
|
||||
upgrade to next major version
|
||||
|
||||
|
||||
Finally update your APT cache:
|
||||
|
|
|
@ -44,7 +44,7 @@ The JSON response fields are:
|
|||
- ``result``: authentication result, ``0`` if it fails, ``1`` if it
|
||||
succeed
|
||||
- ``error``: error code, the corresponding error can be found in
|
||||
``Lemonldap::NG::Portal::Main::Constants``
|
||||
:doc:`Portal error codes<error_codes>`
|
||||
- ``id``: if authentication succeed, the session id is returned in this
|
||||
field
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ Sessions for connected users (used by :doc:`LLNG Proxy<authproxy>`):
|
|||
- GET /session/my/<type> : get session datas
|
||||
- GET /session/my/<type>/key : get session key
|
||||
- DELETE /session/my : ask for logout
|
||||
- DELETE /sessions/my : ask for global logout (if GlobalLogout plugin is on)
|
||||
|
||||
Services for connected users (always enabled):
|
||||
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
Risk-based Authentication
|
||||
=========================
|
||||
|
||||
Our definition
|
||||
--------------
|
||||
|
||||
Risk-based authentication is the ability to take into account the context of
|
||||
the authentication process, and react accordingly, by increasing the
|
||||
authentication challenge (second factor, email confirmation) or trigger out of
|
||||
band actions (email notifications, alerts..).
|
||||
|
||||
.. warning::
|
||||
|
||||
All the features presented on this page are not natively supported by
|
||||
LemonLDAP::NG but can be added through custom plugins or configuration
|
||||
|
||||
The authentication context can include:
|
||||
|
||||
* Source IP address
|
||||
* Access time
|
||||
* Previous authentications (history)
|
||||
* Using the same browser as previous logins
|
||||
|
||||
Reactions can include:
|
||||
|
||||
* Triggering or skipping the second factor
|
||||
* Sending an email to warn the user of a suspicious login
|
||||
* Denying attempt if the suspicion level is too high
|
||||
|
||||
Implementation in LemonLDAP::NG
|
||||
-------------------------------
|
||||
|
||||
LemonLDAP::NG uses the ``_riskLevel`` and ``_riskDetails`` session variables to
|
||||
keep track of the risk associated to the current authentication.
|
||||
|
||||
Detection plugins will raise or lower the risk level, and store fine-grained
|
||||
details in the risk details object.
|
||||
|
||||
Action plugins may use the risk level to trigger certain actions, and can
|
||||
translate the risk detail items into user-friendly messages.
|
||||
|
||||
|
||||
Compatible plugins
|
||||
------------------
|
||||
|
||||
Detection
|
||||
~~~~~~~~~
|
||||
|
||||
New location warning
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
.. versionadded:: 2.0.14
|
||||
|
||||
The :doc:`New Location warning <newlocationwarning>` plugin will increase the risk level by 1 when triggered, and will store the **Session attribute to display** in ``$_riskDetail->{newLocation}``.
|
||||
|
||||
Action
|
||||
~~~~~~
|
||||
|
||||
Forbidding/triggering second factors
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can use the following activation rule to trigger second factors if the risk level is high::
|
||||
|
||||
$_riskLevel > 0
|
||||
|
||||
Or, if you use self registration::
|
||||
|
||||
has2f('TOTP') and $_riskLevel > 0
|
||||
|
||||
Denying login
|
||||
^^^^^^^^^^^^^
|
||||
|
||||
You can use :doc:`session opening conditions <grantsession>` to deny access if the risk level is too high with a rule like this ::
|
||||
|
||||
$_riskLevel < 2
|
||||
|
||||
This will forbid sessions from being opened if the risk level is greater or equal to 2
|
|
@ -43,7 +43,7 @@ Registration on first use
|
|||
If you want to force a 2F registration on first login, you can use the *Force
|
||||
2FA registration at login* option.
|
||||
|
||||
You can use a `rule<writingrulesand_headers>` to enable this behavior only for
|
||||
You can use a :doc:`rule <writingrulesand_headers>` to enable this behavior only for
|
||||
some users.
|
||||
|
||||
Session upgrade through 2FA
|
||||
|
|
|
@ -7,7 +7,7 @@ Our concept of SSOaaS
|
|||
Access management provides 3 services:
|
||||
|
||||
- Global Authentication: Single Sign-On
|
||||
- Authorization: to grant authentication is not enough. User rights
|
||||
- Authorization: Grant authentication is not enough. User rights
|
||||
must be checked
|
||||
- Accounting: SSO logs (access) + application logs *(transactions and
|
||||
results)*
|
||||
|
@ -25,13 +25,13 @@ the ability for an app to manage authorizations and choose user
|
|||
attributes to set. Authentication can not be really ``*aaS``: app must
|
||||
just use it, not manage it.
|
||||
|
||||
LL::NG affords some features that can be used to provide SSO as a
|
||||
service: a web application can manage its rules and headers. Docker or
|
||||
LL::NG affords some features that can be used for providing SSO as a
|
||||
Service: a web application can manage its rules and headers. Docker or
|
||||
VM images (Nginx only) includes LL::NG Nginx configuration that aims to
|
||||
a global
|
||||
:ref:`LL::NG authorization server<platformsoverview-external-servers-for-nginx>`.
|
||||
By default, all authenticated users can access and one header is set:
|
||||
``Auth-User``. If application gives a RULES_URL parameter that refers to
|
||||
``Auth-User``. If application defines a RULES_URL parameter that refers to
|
||||
a JSON file, authorization server will read it, apply specified rules
|
||||
and set required headers (see :doc:`DevOps Handler<devopshandler>`).
|
||||
|
||||
|
@ -41,6 +41,16 @@ There are two different architectures to do this:
|
|||
- Using front reverse-proxies *(some cloud installations use
|
||||
reverse-proxies in front-end)*
|
||||
|
||||
|
||||
.. note::
|
||||
|
||||
Some requests can be dropped by the FastCGI/uWSGI server.
|
||||
Example below with uWSGI server to avoid Load Balancer health check requests
|
||||
being forwarded to DevOps Handler:
|
||||
|
||||
```route-remote-addr = ^127\.0\.0\.25[34]$ break: 403 Forbidden for IP ${REMOTE_ADDR}```
|
||||
|
||||
|
||||
Example of a global FastCGI architecture:
|
||||
|
||||
|image0|
|
||||
|
@ -56,8 +66,9 @@ Using a global FastCGI (or uWSGI) server
|
|||
Nginx
|
||||
^^^^^
|
||||
|
||||
In this example, web server templates (Nginx only) are configured to
|
||||
request authorization from a central FastCGI server:
|
||||
Examples below are web server templates (Nginx only) configured to
|
||||
request authorization from a central FastCGI server.
|
||||
With an uWSGI central server, use 'uwsgi_param' directive (Nginx only):
|
||||
|
||||
.. code::
|
||||
|
||||
|
@ -78,7 +89,11 @@ request authorization from a central FastCGI server:
|
|||
# Keep original request (LLNG server will received /lmauth)
|
||||
fastcgi_param X_ORIGINAL_URI $original_uri;
|
||||
|
||||
# Set dynamically rules (LLNG will poll it every 10 mn)
|
||||
# Set redirection params
|
||||
fastcgi_param HTTPS_REDIRECT "$https";
|
||||
fastcgi_param PORT_REDIRECT $server_port;
|
||||
|
||||
# Set dynamically rules (LL::NG will poll it every 10 mn)
|
||||
fastcgi_param RULES_URL http://rulesserver/my.json;
|
||||
}
|
||||
location /rules.json {
|
||||
|
@ -107,22 +122,22 @@ Apache
|
|||
^^^^^^
|
||||
|
||||
There is an experimental FastCGI client in LL::NG. You just have to
|
||||
install FCGI::Client and add this in the apache2.conf or your web
|
||||
applications or proxies.
|
||||
install LemonLDAP::NG handler and FCGI::Client. Then, add this in
|
||||
your apache2.conf, web applications or reverse-proxies.
|
||||
|
||||
The following configuration example assumes that you are in a "central
|
||||
FastCGI" configuration.
|
||||
|
||||
.. code-block:: apache
|
||||
|
||||
<VirtualHost ...>
|
||||
<VirtualHost port>
|
||||
ServerName app.tls
|
||||
PerlHeaderParserHandler Lemonldap::NG::Handler::ApacheMP2::FCGIClient
|
||||
|
||||
# This must point to the central FastCGI server
|
||||
PerlSetVar LLNG_SERVER 192.0.2.1:9090
|
||||
|
||||
# Declare this vhost as a DevOps vhost, so that we do not have
|
||||
# Declare this vhost as a DevOps protected vhost. So you do not have
|
||||
# to declare it in the LemonLDAP::NG Manager
|
||||
PerlSetVar VHOSTTYPE DevOps
|
||||
|
||||
|
@ -130,6 +145,8 @@ FastCGI" configuration.
|
|||
# used to make the authentication decision about this virtualhost
|
||||
# Make sure the central FastCGI server can reach it
|
||||
PerlSetVar RULES_URL http://app.tld/rules.json
|
||||
PerlSetVar HTTPS_REDIRECT HTTPS
|
||||
PerlSetVar PORT_REDIRECT SERVER_PORT
|
||||
...
|
||||
</VirtualHost>
|
||||
|
||||
|
@ -150,6 +167,8 @@ you can protect also an Express server. Example:
|
|||
port: 9090,
|
||||
PARAMS: {
|
||||
RULES_URL: 'http://my-server/rules.json'
|
||||
HTTPS_REDIRECT: 'ON',
|
||||
PORT_REDIRECT: '443'
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -196,6 +215,8 @@ Simple example:
|
|||
port => '9090',
|
||||
fcgi_auth_params => {
|
||||
RULES_URL => 'https://my-server/my.json',
|
||||
HTTPS_REDIRECT => 'ON',
|
||||
PORT_REDIRECT => 443
|
||||
},
|
||||
# Optional rejection subroutine
|
||||
#on_reject => \&on_reject;
|
||||
|
@ -221,6 +242,7 @@ directory.
|
|||
.. code-block:: nginx
|
||||
|
||||
server {
|
||||
listen <port>;
|
||||
server_name "~^(?<vhost>.+?)\.dev\.sso\.my\.domain$";
|
||||
location = /lmauth {
|
||||
internal;
|
||||
|
@ -235,6 +257,9 @@ directory.
|
|||
fastcgi_param HOST $http_host;
|
||||
# Keep original request (LL::NG server will received /lmauth)
|
||||
fastcgi_param X_ORIGINAL_URI $original_uri;
|
||||
# Set redirection params
|
||||
fastcgi_param HTTPS_REDIRECT "$https";
|
||||
fastcgi_param PORT_REDIRECT $server_port;
|
||||
}
|
||||
location /rules.json {
|
||||
auth_request off;
|
||||
|
@ -253,4 +278,3 @@ directory.
|
|||
}
|
||||
|
||||
.. |image0| image:: /documentation/devops.png
|
||||
|
||||
|
|
|
@ -154,6 +154,11 @@ If you defined the "Register page URL" or the password "Reset page URL" to an ex
|
|||
|
||||
|
||||
|
||||
Manager API
|
||||
~~~~~~~~~~~
|
||||
|
||||
The service parameter set in a request to create or update a CAS application must now be an array, and no more a string.
|
||||
|
||||
Changes impacting plugin developpers
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -1397,7 +1397,7 @@ components:
|
|||
type: object
|
||||
properties:
|
||||
service:
|
||||
type: string
|
||||
type: array
|
||||
userAttribute:
|
||||
type: string
|
||||
default: none
|
||||
|
|
|
@ -5,7 +5,7 @@ use Mouse;
|
|||
use Safe;
|
||||
use constant PE_OK => 0;
|
||||
|
||||
our $VERSION = '2.0.6';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
# Handle "if then else" (used during init)
|
||||
# return a sub that can be called with ($req) to get a [array] of combination
|
||||
|
@ -92,10 +92,12 @@ sub parseAnd {
|
|||
$str{$r}++;
|
||||
}
|
||||
else {
|
||||
return ( $r, $name ) unless ( $r == PE_OK );
|
||||
return ( wantarray ? ( $r, $name ) : $r )
|
||||
unless ( $r == PE_OK );
|
||||
}
|
||||
}
|
||||
return ( ( %str ? join( ',', keys %str ) : PE_OK ), $expr );
|
||||
my $res = %str ? join( ',', keys %str ) : PE_OK;
|
||||
return wantarray ? ( $res, $expr ) : $res;
|
||||
};
|
||||
}
|
||||
return \@res;
|
||||
|
@ -135,7 +137,8 @@ sub parseMod {
|
|||
my ($m) = @mods;
|
||||
return sub {
|
||||
my $sub = shift;
|
||||
return ( $m->$sub(@_), $expr );
|
||||
my $res = $m->$sub(@_);
|
||||
return wantarray ? ( $res, $expr ) : $res;
|
||||
};
|
||||
}
|
||||
return sub {
|
||||
|
@ -149,10 +152,12 @@ sub parseMod {
|
|||
$str{$res}++;
|
||||
}
|
||||
else {
|
||||
return ( $res, $list[$i] ) unless ( $res == PE_OK );
|
||||
return ( wantarray ? ( $res, $list[$i] ) : $res )
|
||||
unless ( $res == PE_OK );
|
||||
}
|
||||
}
|
||||
return ( ( %str ? join( ',', keys %str ) : PE_OK ), $expr );
|
||||
my $res = %str ? join( ',', keys %str ) : PE_OK;
|
||||
return wantarray ? ( $res, $expr ) : $res;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ use MIME::Base64;
|
|||
use Safe;
|
||||
use Encode;
|
||||
|
||||
our $VERSION = '2.0.9';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
my $dataStart = tell(DATA);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ our $VERSION = '2.0.12';
|
|||
# Not that only functions, not methods, can be written here
|
||||
our $functions =
|
||||
[
|
||||
qw(&checkLogonHours &date &dateToTime &checkDate &basic &unicode2iso &iso2unicode &groupMatch &isInNet6 &varIsInUri &has2f)
|
||||
qw(&checkLogonHours &date &dateToTime &checkDate &basic &unicode2iso &iso2unicode &groupMatch &isInNet6 &varIsInUri &has2f_internal)
|
||||
];
|
||||
|
||||
## @function boolean checkLogonHours(string logon_hours, string syntax, string time_correction, boolean default_access)
|
||||
|
@ -244,7 +244,7 @@ sub varIsInUri {
|
|||
|
||||
my $json = JSON::XS->new;
|
||||
|
||||
sub has2f {
|
||||
sub has2f_internal {
|
||||
my ( $session, $type ) = @_;
|
||||
return 0 unless $session->{_2fDevices};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use Mouse;
|
|||
use Lemonldap::NG::Common::Conf::Constants;
|
||||
use JSON qw(from_json to_json);
|
||||
|
||||
our $VERSION = '2.0.9';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
has sessionTypes => ( is => 'rw' );
|
||||
|
||||
|
@ -293,4 +293,9 @@ sub getMod {
|
|||
return $m;
|
||||
}
|
||||
|
||||
sub getGlobal {
|
||||
my ( $self ) = @_;
|
||||
return $self->sessionTypes->{global};
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -10,7 +10,7 @@ use Crypt::URandom;
|
|||
use Digest::HMAC_SHA1 'hmac_sha1_hex';
|
||||
use Lemonldap::NG::Common::Crypto;
|
||||
|
||||
our $VERSION = '2.0.10';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
has 'key' => (
|
||||
is => 'ro',
|
||||
|
|
|
@ -21,7 +21,7 @@ use constant REDIRECT => Apache2::Const::REDIRECT;
|
|||
use constant DECLINED => Apache2::Const::DECLINED;
|
||||
use constant SERVER_ERROR => Apache2::Const::SERVER_ERROR;
|
||||
|
||||
our $VERSION = '2.0.6';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
sub handler {
|
||||
my ( $class, $r ) = @_;
|
||||
|
@ -43,7 +43,7 @@ sub handler {
|
|||
SERVER_PORT => $r->get_server_port,
|
||||
REQUEST_METHOD => $r->method,
|
||||
};
|
||||
foreach (qw(VHOSTTYPE RULES_URL)) {
|
||||
foreach (qw(VHOSTTYPE RULES_URL HTTPS_REDIRECT PORT_REDIRECT)) {
|
||||
if ( my $t = $r->dir_config($_) ) {
|
||||
$env->{$_} = $t;
|
||||
}
|
||||
|
|
|
@ -94,6 +94,10 @@ q"I refuse to compile 'rules.json' when useSafeJail isn't activated! Yes I know,
|
|||
$class->locationRulesInit( undef, { $vhost => $json->{rules} } );
|
||||
$class->headersInit( undef, { $vhost => $json->{headers} } );
|
||||
$class->tsv->{lastVhostUpdate}->{$vhost} = time;
|
||||
$class->tsv->{https}->{$vhost} = uc $req->env->{HTTPS_REDIRECT} eq 'ON'
|
||||
if exists $req->env->{HTTPS_REDIRECT};
|
||||
$class->tsv->{port}->{$vhost} = $req->env->{PORT_REDIRECT}
|
||||
if exists $req->env->{PORT_REDIRECT};
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use Lemonldap::NG::Common::JWT qw(getAccessTokenSessionId);
|
|||
|
||||
use strict;
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
sub retrieveSession {
|
||||
my ( $class, $req, $id ) = @_;
|
||||
|
|
|
@ -5,7 +5,7 @@ use Mouse;
|
|||
|
||||
#use Lemonldap::NG::Handler::Main qw(:jailSharedVars);
|
||||
|
||||
our $VERSION = '2.0.11';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
has protection => ( is => 'rw', isa => 'Str' );
|
||||
has rule => ( is => 'rw', isa => 'Str' );
|
||||
|
@ -128,7 +128,7 @@ sub _authAndTrace {
|
|||
eval "require $type";
|
||||
die $@ if ($@);
|
||||
my ( $res, $session ) = $type->run( $req, $self->{rule} );
|
||||
eval { $self->portal( $type->tsv->{portal}->() ) };
|
||||
eval { $self->portal( $type->tsv->{portal}->() ) } unless $self->portal;
|
||||
$self->logger->warn($@) if $@;
|
||||
$req->userData($session) if ($session);
|
||||
|
||||
|
@ -201,7 +201,7 @@ sub userId {
|
|||
my $userId =
|
||||
$req->userData->{ $Lemonldap::NG::Handler::Main::tsv->{whatToTrace}
|
||||
|| '_whatToTrace' }
|
||||
|| $req->userData->{'_user'} # Fix 2377
|
||||
|| $req->userData->{'_user'} # Fix 2377
|
||||
|| 'anonymous';
|
||||
|
||||
$self->logger->debug("Returned userId: $userId");
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package Lemonldap::NG::Handler::Main::Reload;
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
package Lemonldap::NG::Handler::Main;
|
||||
|
||||
|
@ -65,7 +65,7 @@ sub checkConf {
|
|||
or $class->cfgNum != $conf->{cfgNum}
|
||||
or $class->cfgDate != $conf->{cfgDate} )
|
||||
{
|
||||
$class->logger->debug("Get configuration $conf->{cfgNum}");
|
||||
$class->logger->debug("Get configuration $conf->{cfgNum} aged $conf->{cfgDate}");
|
||||
unless ( $class->cfgNum( $conf->{cfgNum} )
|
||||
&& $class->cfgDate( $conf->{cfgDate} ) )
|
||||
{
|
||||
|
@ -658,7 +658,7 @@ sub substitute {
|
|||
$expr =~ s/\binGroup\(([^)]*)\)/listMatch(\$s->{'hGroups'},$1,1)/g;
|
||||
|
||||
# handle has2f
|
||||
$expr =~ s/\bhas2f\(([^),]*)\)/has2f(\$s,$1)/g;
|
||||
$expr =~ s/\bhas2f\(([^),]*)\)/has2f_internal(\$s,$1)/g;
|
||||
|
||||
return $expr;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ use Lemonldap::NG::Handler::PSGI::Main;
|
|||
|
||||
extends 'Lemonldap::NG::Handler::Lib::PSGI', 'Lemonldap::NG::Common::PSGI';
|
||||
|
||||
our $VERSION = '2.0.10';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
sub init {
|
||||
my ( $self, $args ) = @_;
|
||||
|
|
|
@ -3,7 +3,7 @@ package Lemonldap::NG::Handler::PSGI::Try;
|
|||
use strict;
|
||||
use Mouse;
|
||||
|
||||
our $VERSION = '2.0.6';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends 'Lemonldap::NG::Handler::PSGI::Router';
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ ok(
|
|||
ok( $res = &$code, "Function works" );
|
||||
ok( $res == 1, 'Get good result' );
|
||||
|
||||
$sub = "sub { return(has2f(\$_[0],\$_[1])) }";
|
||||
$sub = "sub { return(has2f_internal(\$_[0],\$_[1])) }";
|
||||
$code = $jail->jail_reval($sub);
|
||||
ok(
|
||||
( defined($code) and ref($code) eq 'CODE' ),
|
||||
|
|
|
@ -62,7 +62,7 @@ ok( ( defined($listMatch) and ref($listMatch) eq 'CODE' ),
|
|||
ok( &$listMatch eq '0', 'Get good result' );
|
||||
|
||||
# Test has2f method
|
||||
my $sub7 = "sub { return(has2f(\$_[0],\$_[1])) }";
|
||||
my $sub7 = "sub { return(has2f_internal(\$_[0],\$_[1])) }";
|
||||
my $has2f = $jail->jail_reval($sub7);
|
||||
ok(
|
||||
( defined($has2f) and ref($has2f) eq 'CODE' ),
|
||||
|
|
|
@ -11,9 +11,11 @@ BEGIN {
|
|||
init(
|
||||
'Lemonldap::NG::Handler::Server',
|
||||
{
|
||||
#logLevel => 'debug',
|
||||
#logLevel => 'debug',
|
||||
vhostOptions => {
|
||||
'test3.example.com' => {
|
||||
vhostHttps => 0,
|
||||
vhostPort => 80,
|
||||
vhostDevOpsRulesUrl =>
|
||||
'http://donotuse.example.com/myfile.json',
|
||||
},
|
||||
|
@ -23,6 +25,42 @@ init(
|
|||
|
||||
my $res;
|
||||
|
||||
# Unauthorized queries
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/', undef,
|
||||
'test3.example.com', undef,
|
||||
VHOSTTYPE => 'DevOps',
|
||||
RULES_URL => 'http://devops.example.com/file.json'
|
||||
),
|
||||
'Unauthorized query'
|
||||
);
|
||||
ok( $res->[0] == 302, 'Code is 302' ) or explain( $res->[0], 302 );
|
||||
${ $res->[1] }[1] =~ m#http://auth\.example\.com/\?url=(.+?)%#;
|
||||
ok( decode_base64 $1 eq 'http://test3.example.com/', 'Redirect URL found' )
|
||||
or explain( decode_base64 $1, 'http://test3.example.com/' );
|
||||
count(3);
|
||||
|
||||
Time::Fake->offset("+700s");
|
||||
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/', undef,
|
||||
'test3.example.com', undef,
|
||||
HTTPS_REDIRECT => 'on',
|
||||
PORT_REDIRECT => 8443,
|
||||
VHOSTTYPE => 'DevOps',
|
||||
RULES_URL => 'http://devops.example.com/file.json'
|
||||
),
|
||||
'Unauthorized query 2'
|
||||
);
|
||||
ok( $res->[0] == 302, 'Code is 302' ) or explain( $res->[0], 302 );
|
||||
${ $res->[1] }[1] =~ m#http://auth\.example\.com/\?url=(.+?)%#;
|
||||
ok( decode_base64 $1 eq 'https://test3.example.com:8443/',
|
||||
'Redirect URL found' )
|
||||
or explain( decode_base64 $1, 'https://test3.example.com:8443/' );
|
||||
count(3);
|
||||
|
||||
# Authorized queries
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package Lemonldap::NG::Manager::Api::Common;
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
package Lemonldap::NG::Manager::Api;
|
||||
|
||||
|
@ -110,6 +110,9 @@ sub _translateValueConfToApi {
|
|||
elsif ( $optionName eq "oidcRPMetaDataOptionsAdditionalAudiences" ) {
|
||||
return [ split( /\s+/, $optionValue, ) ];
|
||||
}
|
||||
elsif ( $optionName eq "casAppMetaDataOptionsService" ) {
|
||||
return [ split( /\s+/, $optionValue, ) ];
|
||||
}
|
||||
else {
|
||||
return $optionValue;
|
||||
}
|
||||
|
@ -134,7 +137,14 @@ sub _translateValueApiToConf {
|
|||
|
||||
# additionalAudiences is handled as an array
|
||||
elsif ( $optionName eq 'additionalAudiences' ) {
|
||||
die "postLogoutRedirectUris is not an array\n"
|
||||
die "additionalAudiences is not an array\n"
|
||||
unless ( ref($optionValue) eq "ARRAY" );
|
||||
return join( ' ', @{$optionValue} );
|
||||
}
|
||||
|
||||
# service is handled as an array
|
||||
elsif ( $optionName eq 'service' ) {
|
||||
die "service is not an array\n"
|
||||
unless ( ref($optionValue) eq "ARRAY" );
|
||||
return join( ' ', @{$optionValue} );
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package Lemonldap::NG::Manager::Api::Providers::CasApp;
|
||||
|
||||
our $VERSION = '2.0.10';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
package Lemonldap::NG::Manager::Api;
|
||||
|
||||
|
@ -109,9 +109,9 @@ sub addCasApp {
|
|||
return $self->sendError( $req, 'Invalid input: service is missing', 400 )
|
||||
unless ( defined $add->{options}->{service} );
|
||||
|
||||
return $self->sendError( $req, 'Invalid input: service is not a string',
|
||||
return $self->sendError( $req, 'Invalid input: service must be an array',
|
||||
400 )
|
||||
if ( ref $add->{options}->{service} );
|
||||
unless ( ref $add->{options}->{service} eq "ARRAY" );
|
||||
|
||||
$self->logger->debug(
|
||||
"[API] Add CAS App with confKey $add->{confKey} requested");
|
||||
|
@ -125,18 +125,18 @@ sub addCasApp {
|
|||
409
|
||||
) if ( defined $self->_getCasAppByConfKey( $conf, $add->{confKey} ) );
|
||||
|
||||
my $res =
|
||||
$self->_getCasAppByServiceUrl( $conf, $add->{options}->{service} );
|
||||
if ( defined $res ) {
|
||||
my $conflict = $res->{options}->{service};
|
||||
return $self->sendError(
|
||||
$req,
|
||||
"Invalid input: A CAS application with service URL $conflict already exists",
|
||||
409
|
||||
);
|
||||
for my $serviceUrl ( @{ $add->{options}->{service} } ) {
|
||||
my $res = $self->_getCasAppByServiceUrl( $conf, $serviceUrl );
|
||||
if ( defined $res ) {
|
||||
return $self->sendError(
|
||||
$req,
|
||||
"Invalid input: A CAS application with service URL $serviceUrl already exists",
|
||||
409
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$res = $self->_pushCasApp( $conf, $add->{confKey}, $add, 1 );
|
||||
my $res = $self->_pushCasApp( $conf, $add->{confKey}, $add, 1 );
|
||||
|
||||
return $self->sendError( $req, $res->{msg}, 400 )
|
||||
unless ( $res->{res} eq 'ok' );
|
||||
|
@ -285,12 +285,19 @@ sub _getCasAppByServiceUrl {
|
|||
|
||||
my ($serviceHost) = $serviceUrl =~ m#^(https?://[^/]+)(?:/.*)?$#;
|
||||
return undef unless $serviceHost;
|
||||
foreach ( keys %{ $conf->{casAppMetaDataOptions} } ) {
|
||||
my $url =
|
||||
$conf->{casAppMetaDataOptions}->{$_}->{casAppMetaDataOptionsService};
|
||||
my ($curHost) = $url =~ m#^(https?://[^/]+)(?:/.*)?$#;
|
||||
if ( $serviceHost eq $curHost ) {
|
||||
return $self->_getCasAppByConfKey( $conf, $_ );
|
||||
for my $confKey ( keys %{ $conf->{casAppMetaDataOptions} } ) {
|
||||
for my $url (
|
||||
split(
|
||||
/\s+/,
|
||||
$conf->{casAppMetaDataOptions}->{$confKey}
|
||||
->{casAppMetaDataOptionsService}
|
||||
)
|
||||
)
|
||||
{
|
||||
my ($curHost) = $url =~ m#^(https?://[^/]+)(?:/.*)?$#;
|
||||
if ( $serviceHost eq $curHost ) {
|
||||
return $self->_getCasAppByConfKey( $conf, $confKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -301,14 +308,29 @@ sub _isNewCasAppServiceUrlUnique {
|
|||
my ( $self, $conf, $confKey, $casApp ) = @_;
|
||||
my $curServiceUrl =
|
||||
$self->_getCasAppByConfKey( $conf, $confKey )->{options}->{service};
|
||||
my $newServiceUrl = $casApp->{options}->{service} || "";
|
||||
if ( $newServiceUrl ne '' && $newServiceUrl ne $curServiceUrl ) {
|
||||
|
||||
# Check service paramater
|
||||
unless ( ref $casApp->{options}->{service} eq "ARRAY" ) {
|
||||
return {
|
||||
res => 'ko',
|
||||
msg =>
|
||||
res => 'ko',
|
||||
msg => "The parameter 'service' must be an array",
|
||||
};
|
||||
}
|
||||
|
||||
my $newService = $casApp->{options}->{service} || [];
|
||||
for my $newServiceUrl (@$newService) {
|
||||
if ( $newServiceUrl ne ''
|
||||
&& !grep( /^$newServiceUrl$/, @$curServiceUrl ) )
|
||||
{
|
||||
return {
|
||||
res => 'ko',
|
||||
msg =>
|
||||
"A CAS application with service URL '$newServiceUrl' already exists"
|
||||
}
|
||||
if ( defined $self->_getCasAppByServiceUrl( $conf, $newServiceUrl ) );
|
||||
}
|
||||
if (
|
||||
defined $self->_getCasAppByServiceUrl( $conf, $newServiceUrl )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return { res => 'ok' };
|
||||
|
|
|
@ -748,7 +748,7 @@ sub attributes {
|
|||
'type' => 'text'
|
||||
},
|
||||
'casAppMetaDataOptionsService' => {
|
||||
'type' => 'url'
|
||||
'type' => 'text'
|
||||
},
|
||||
'casAppMetaDataOptionsUserAttribute' => {
|
||||
'type' => 'text'
|
||||
|
|
|
@ -2526,7 +2526,7 @@ sub attributes {
|
|||
documentation => 'CAS exported variables',
|
||||
},
|
||||
casAppMetaDataOptionsService => {
|
||||
type => 'url',
|
||||
type => 'text',
|
||||
documentation => 'CAS App service',
|
||||
},
|
||||
casAppMetaDataOptionsUserAttribute => {
|
||||
|
|
|
@ -24,7 +24,7 @@ extends qw(
|
|||
Lemonldap::NG::Common::Conf::RESTServer
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
#############################
|
||||
# I. INITIALIZATION METHODS #
|
||||
|
|
|
@ -891,25 +891,32 @@ sub tests {
|
|||
my %casUrl;
|
||||
foreach my $casConfKey ( keys %{ $conf->{casAppMetaDataOptions} } )
|
||||
{
|
||||
my $appUrl =
|
||||
$conf->{casAppMetaDataOptions}->{$casConfKey}
|
||||
->{casAppMetaDataOptionsService}
|
||||
|| "";
|
||||
$appUrl =~ m#^(https?://[^/]+)(/.*)?$#;
|
||||
my $appHost = $1;
|
||||
unless ($appHost) {
|
||||
push @msg, "$casConfKey CAS Application has no Service URL";
|
||||
$res = 0;
|
||||
next;
|
||||
}
|
||||
for my $appUrl (
|
||||
split(
|
||||
/\s+/,
|
||||
$conf->{casAppMetaDataOptions}->{$casConfKey}
|
||||
->{casAppMetaDataOptionsService}
|
||||
)
|
||||
)
|
||||
{
|
||||
$appUrl ||= "";
|
||||
$appUrl =~ m#^(https?://[^/]+)(/.*)?$#;
|
||||
my $appHost = $1;
|
||||
unless ($appHost) {
|
||||
push @msg,
|
||||
"$casConfKey CAS Application has no Service URL";
|
||||
$res = 0;
|
||||
next;
|
||||
}
|
||||
|
||||
if ( defined $casUrl{$appUrl} ) {
|
||||
push @msg,
|
||||
if ( defined $casUrl{$appUrl} ) {
|
||||
push @msg,
|
||||
"$casConfKey and $casUrl{$appUrl} have the same Service URL";
|
||||
$res = 0;
|
||||
next;
|
||||
$res = 0;
|
||||
next;
|
||||
}
|
||||
$casUrl{$appUrl} = $casConfKey;
|
||||
}
|
||||
$casUrl{$appUrl} = $casConfKey;
|
||||
}
|
||||
return ( $res, join( ', ', @msg ) );
|
||||
},
|
||||
|
@ -919,7 +926,9 @@ sub tests {
|
|||
return 1 unless ( $conf->{sfRemovedMsgRule} );
|
||||
return ( 1,
|
||||
'Notification system must be enabled to display a notification if a SF is removed'
|
||||
) if ( $conf->{sfRemovedUseNotif} and not $conf->{notification} );
|
||||
)
|
||||
if ( $conf->{sfRemovedUseNotif}
|
||||
and not $conf->{notification} );
|
||||
return 1;
|
||||
},
|
||||
|
||||
|
@ -936,7 +945,8 @@ sub tests {
|
|||
# Same with SameSite=(auto) and SAML issuer in use
|
||||
SameSiteNoneWithSecure => sub {
|
||||
return ( -1, 'SameSite value = None requires the secured flag' )
|
||||
if ( getSameSite($conf) eq 'None' and !$conf->{securedCookie} );
|
||||
if ( getSameSite($conf) eq 'None'
|
||||
and !$conf->{securedCookie} );
|
||||
return 1;
|
||||
},
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@
|
|||
"casStorage":"CAS oturumları modül adı",
|
||||
"casStorageOptions":"CAS oturumları modül seçenekleri",
|
||||
"casStrictMatching":"Katı URL eşleşmesi kullan",
|
||||
"casTicketExpiration":"Temporary ticket lifetime",
|
||||
"casTicketExpiration":"Geçici bilet ömrü",
|
||||
"categoryName":"Kategori ismi",
|
||||
"cda":"Çoklu alan adları",
|
||||
"certificateMailContent":"E-posta içeriği",
|
||||
|
@ -183,7 +183,7 @@
|
|||
"cfgLog":"Özet",
|
||||
"cfgVersion":"Yapılandırma sürümü",
|
||||
"checkDevOps":"Aktivasyon",
|
||||
"checkDevOpsCheckSessionAttributes":"Check session attributes",
|
||||
"checkDevOpsCheckSessionAttributes":"Oturum niteliklerini kontrol et",
|
||||
"checkDevOpsDisplayNormalizedHeaders":"Normalleştirilmiş başlıkları görüntüle",
|
||||
"checkDevOpsDownload":"Dosyayı indir",
|
||||
"checkState":"Aktivasyon",
|
||||
|
@ -356,7 +356,7 @@
|
|||
"facebookExportedVars":"Dışa aktarılan değişkenler",
|
||||
"facebookParams":"Facebook parametreleri",
|
||||
"facebookUserField":"Alan kullanıcı kimliği içeriyor",
|
||||
"failedLoginNumber":"Max failed logins count",
|
||||
"failedLoginNumber":"Maksimum başarısız giriş sayısı",
|
||||
"fileToUpload":"Yüklenecek dosya",
|
||||
"findUser":"Aktivasyon",
|
||||
"findUserControl":"Parametre kontrolü",
|
||||
|
@ -662,7 +662,7 @@
|
|||
"oidcParams":"OpenID Connect parametreleri",
|
||||
"oidcRP":"OpenID Connect Relying Party",
|
||||
"oidcRPCallbackGetParam":"GET parametresini geri çağır",
|
||||
"oidcRPMetaDataExportedVars":"Exported attributes (claims)",
|
||||
"oidcRPMetaDataExportedVars":"Dışa aktarılan nitelikler (talepler)",
|
||||
"oidcRPMetaDataMacros":"Makrolar",
|
||||
"oidcRPMetaDataNode":"OpenID Connect Relying Parties",
|
||||
"oidcRPMetaDataNodes":"OpenID Connect Relying Parties",
|
||||
|
@ -684,7 +684,7 @@
|
|||
"oidcRPMetaDataOptionsClientSecret":"İstemci sırrı",
|
||||
"oidcRPMetaDataOptionsDisplay":"Görüntüle",
|
||||
"oidcRPMetaDataOptionsDisplayName":"Görüntülenen ad",
|
||||
"oidcRPMetaDataOptionsExtraClaims":"Scope values content",
|
||||
"oidcRPMetaDataOptionsExtraClaims":"Kapsam değerleri içeriği",
|
||||
"oidcRPMetaDataOptionsIDTokenExpiration":"ID Jetonu sona erme",
|
||||
"oidcRPMetaDataOptionsIDTokenForceClaims":"ID Jetonunda özelliklerin yayınlanmasını zorla",
|
||||
"oidcRPMetaDataOptionsIDTokenSignAlg":"ID Token imzalama algoritması",
|
||||
|
@ -1115,7 +1115,7 @@
|
|||
"storePassword":"Kullanıcı parolasını oturumda sakla",
|
||||
"string":"Dize",
|
||||
"subtitle":"Altyazı",
|
||||
"successLoginNumber":"Max successful logins count",
|
||||
"successLoginNumber":"Maksimum başarılı giriş sayısı",
|
||||
"successfullySaved":"Başarıyla kaydedildi",
|
||||
"sympaHandler":"Sympa",
|
||||
"sympaMailKey":"E-posta oturum anahtarı",
|
||||
|
@ -1133,7 +1133,7 @@
|
|||
"totp2fActivation":"Aktivasyon",
|
||||
"totp2fAuthnLevel":"Doğrulama seviyesi",
|
||||
"totp2fDigits":"Rakam sayısı",
|
||||
"totp2fEncryptSecret":"Encrypt TOTP secrets",
|
||||
"totp2fEncryptSecret":"TOTP sırlarını şifreleyin",
|
||||
"totp2fInterval":"Süre aralığı",
|
||||
"totp2fIssuer":"Düzenleyici adı",
|
||||
"totp2fLabel":"Etiket",
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
<div class="col-lg-6 col-md-6 col-sm-8 col-xs-14" >
|
||||
<form class="navbar-form" role="search">
|
||||
<div class="input-group add-on">
|
||||
<input class="form-control" placeholder="{{translate('search')}}" type="text" ng-model="searchString" ng-init="" ng-keyup="search2FA()"/>
|
||||
<input class="form-control" trplaceholder="search" type="text" ng-model="searchString" ng-init="" ng-keyup="search2FA()"/>
|
||||
<div class="input-group-btn">
|
||||
<button class="btn btn-default" ng-click="search2FA(1)"><i class="glyphicon glyphicon-search"></i></button>
|
||||
</div>
|
||||
|
|
|
@ -276,7 +276,7 @@ sub checkFindByProviderId {
|
|||
($gotProviderId) = $result->{metadata} =~ m/entityID=['"](.+?)['"]/i;
|
||||
}
|
||||
elsif ( $providerIdName eq 'serviceUrl' ) {
|
||||
$gotProviderId = $result->{options}->{service};
|
||||
$gotProviderId = shift @{$result->{options}->{service}};
|
||||
}
|
||||
else {
|
||||
$gotProviderId = $result->{$providerIdName};
|
||||
|
@ -646,7 +646,7 @@ my $casApp = {
|
|||
given_name => '$firstName',
|
||||
},
|
||||
options => {
|
||||
service => 'http://mycasapp.example.com',
|
||||
service => [ 'http://mycasapp.example.com', 'http://mycasapp2.example.com/test' ],
|
||||
rule => '$uid eq \'dwho\'',
|
||||
userAttribute => 'uid'
|
||||
}
|
||||
|
@ -654,7 +654,7 @@ my $casApp = {
|
|||
|
||||
$test = "CasApp - Add should succeed";
|
||||
checkAdd( $test, 'cas/app', $casApp );
|
||||
checkGet( $test, 'cas/app', 'myCasApp1', 'options/service',
|
||||
checkGet( $test, 'cas/app', 'myCasApp1', 'options/service/0',
|
||||
'http://mycasapp.example.com' );
|
||||
checkGet( $test, 'cas/app', 'myCasApp1', 'options/userAttribute', 'uid' );
|
||||
checkGet( $test, 'cas/app', 'myCasApp1', 'options/rule', '$uid eq \'dwho\'' );
|
||||
|
@ -663,7 +663,7 @@ $test = "CasApp - Add should fail on duplicate confKey";
|
|||
checkAddFailsIfExists( $test, 'cas/app', $casApp );
|
||||
|
||||
$test = "CasApp - Update should succeed and keep existing values";
|
||||
$casApp->{options}->{service} = 'http://mycasapp.acme.com';
|
||||
$casApp->{options}->{service} = [ 'http://mycasapp.acme.com' ];
|
||||
$casApp->{options}->{userAttribute} = 'cn';
|
||||
delete $casApp->{options}->{rule};
|
||||
delete $casApp->{macros};
|
||||
|
@ -671,8 +671,8 @@ delete $casApp->{exportedVars};
|
|||
$casApp->{macros}->{given_name} = '$givenName';
|
||||
$casApp->{exportedVars}->{cn} = 'uid';
|
||||
checkUpdate( $test, 'cas/app', 'myCasApp1', $casApp );
|
||||
checkGet( $test, 'cas/app', 'myCasApp1', 'options/service',
|
||||
'http://mycasapp.acme.com' );
|
||||
checkGet( $test, 'cas/app', 'myCasApp1', 'options/service/0',
|
||||
'http://mycasapp.acme.com');
|
||||
checkGet( $test, 'cas/app', 'myCasApp1', 'options/userAttribute', 'cn' );
|
||||
checkGet( $test, 'cas/app', 'myCasApp1', 'options/rule', '$uid eq \'dwho\'' );
|
||||
checkGet( $test, 'cas/app', 'myCasApp1', 'exportedVars/cn', 'uid' );
|
||||
|
@ -686,17 +686,17 @@ delete $casApp->{options}->{playingPossum};
|
|||
|
||||
$test = "CasApp - Add should fail on non existing options";
|
||||
$casApp->{confKey} = 'myCasApp2';
|
||||
$casApp->{options}->{service} = 'http://mycasapp.skynet.com';
|
||||
$casApp->{options}->{service} = [ 'http://mycasapp.skynet.com' ];
|
||||
$casApp->{options}->{playingPossum} = 'ElephantInTheRoom';
|
||||
checkAddWithUnknownAttributes( $test, 'cas/app', $casApp );
|
||||
delete $casApp->{options}->{playingPossum};
|
||||
|
||||
$test = "CasApp - Add should fail because service host already exists";
|
||||
$casApp->{options}->{service} = 'http://mycasapp.acme.com/ignoredbyissuer';
|
||||
$casApp->{options}->{service} = [ 'http://mycasapp.acme.com/ignoredbyissuer' ];
|
||||
checkAddFailsIfExists( $test, 'cas/app', $casApp );
|
||||
|
||||
$test = "CasApp - 2nd add should succeed";
|
||||
$casApp->{options}->{service} = 'http://mycasapp.skynet.com';
|
||||
$casApp->{options}->{service} = [ 'http://mycasapp.skynet.com' ];
|
||||
checkAdd( $test, 'cas/app', $casApp );
|
||||
|
||||
$test = "CasApp - Update should fail if confKey not found";
|
||||
|
@ -714,9 +714,13 @@ $test = "CasApp - Replace should fail on non existing or invalid options";
|
|||
$casApp->{options}->{playingPossum} = 'elephant';
|
||||
checkReplaceWithInvalidAttribute( $test, 'cas/app', 'myCasApp2', $casApp );
|
||||
delete $casApp->{options}->{playingPossum};
|
||||
$casApp->{options}->{service} = "XXX";
|
||||
$casApp->{options}->{service} = [ "XXX" ];
|
||||
checkReplaceWithInvalidAttribute( $test, 'cas/app', 'myCasApp2', $casApp );
|
||||
|
||||
$test = "CasApp - Replace should fail if service is not an array";
|
||||
$casApp->{options}->{service} = "http://cas.url.string";
|
||||
check409( $test, update( $test, 'cas/app', 'myCasApp2', $casApp ) );
|
||||
|
||||
$test = "CasApp - Replace should fail if confKey not found";
|
||||
$casApp->{confKey} = 'myCasApp3';
|
||||
checkReplaceNotFound( $test, 'cas/app', 'myCasApp3', $casApp );
|
||||
|
|
|
@ -559,6 +559,7 @@ t/30-SAML-ReAuth-with-choice.t
|
|||
t/30-SAML-ReAuth.t
|
||||
t/30-SAML-RelayState.t
|
||||
t/30-SAML-SP-rule.t
|
||||
t/31-Auth-and-issuer-CAS-declared-app-multiple-urls.t
|
||||
t/31-Auth-and-issuer-CAS-declared-app-userattr.t
|
||||
t/31-Auth-and-issuer-CAS-declared-app.t
|
||||
t/31-Auth-and-issuer-CAS-declared-apps.t
|
||||
|
|
|
@ -23,7 +23,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_NO_SECOND_FACTORS
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
with 'Lemonldap::NG::Portal::Lib::OverConf';
|
||||
|
|
|
@ -5,7 +5,7 @@ use strict;
|
|||
use Mouse;
|
||||
use JSON qw(from_json to_json);
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends qw(
|
||||
Lemonldap::NG::Portal::Main::Plugin
|
||||
|
|
|
@ -187,6 +187,7 @@ sub fail {
|
|||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
AUTH_ERROR => $req->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
SKIN => $self->p->getSkin($req),
|
||||
FAILED => 1
|
||||
}
|
||||
|
|
|
@ -5,10 +5,14 @@ package Lemonldap::NG::Portal::Auth::AD;
|
|||
|
||||
use strict;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Portal::Main::Constants
|
||||
qw(PE_OK PE_PP_PASSWORD_EXPIRED PE_PP_CHANGE_AFTER_RESET PE_BADCREDENTIALS);
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_OK
|
||||
PE_PP_PASSWORD_EXPIRED
|
||||
PE_PP_CHANGE_AFTER_RESET
|
||||
PE_BADCREDENTIALS
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.6';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Auth::LDAP';
|
||||
|
||||
|
@ -158,4 +162,16 @@ sub authenticate {
|
|||
return $res;
|
||||
}
|
||||
|
||||
# Define which error codes will stop Combination process
|
||||
# @param res error code
|
||||
# @return result 1 if stop is needed
|
||||
sub stop {
|
||||
my ( $self, $res ) = @_;
|
||||
|
||||
return 1
|
||||
if ( $res == PE_PP_PASSWORD_EXPIRED
|
||||
or $res == PE_PP_CHANGE_AFTER_RESET );
|
||||
return 0;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -3,12 +3,18 @@ package Lemonldap::NG::Portal::Auth::Combination;
|
|||
use strict;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Common::Combination::Parser;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_ERROR PE_FIRSTACCESS);
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_CONFIRM
|
||||
PE_ERROR
|
||||
PE_FIRSTACCESS
|
||||
PE_FORMEMPTY
|
||||
PE_PASSWORD_OK
|
||||
PE_OK
|
||||
);
|
||||
use Scalar::Util 'weaken';
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
# TODO: See Lib::Wrapper
|
||||
extends 'Lemonldap::NG::Portal::Main::Auth';
|
||||
with 'Lemonldap::NG::Portal::Lib::OverConf';
|
||||
|
||||
|
@ -126,7 +132,7 @@ sub getDisplayType {
|
|||
$req->data->{dataKeep}->{combinationTry},
|
||||
$req->data->{combinationStack}
|
||||
);
|
||||
my ( $res, $name ) = $stack->[$nb]->[0]->( 'getDisplayType', @_ );
|
||||
my $res = $stack->[$nb]->[0]->( 'getDisplayType', @_ );
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
@ -231,13 +237,14 @@ sub try {
|
|||
return PE_ERROR;
|
||||
}
|
||||
|
||||
my $stop = 0;
|
||||
if ( $nb < @$stack - 1 ) {
|
||||
|
||||
# TODO: change logLevel for userLog()
|
||||
( $res, $name ) = $stack->[$nb]->[$type]->( $subname, $req, @args );
|
||||
|
||||
# On error, restart authentication with next scheme
|
||||
if ( $res > PE_OK ) {
|
||||
unless ( $stop = $self->stop( $stack->[$nb]->[$type], $res ) ) {
|
||||
$self->logger->info(qq'Scheme "$name" returned $res, trying next');
|
||||
$req->data->{dataKeep}->{combinationTry}++;
|
||||
$req->steps( [ @{ $req->data->{combinationSteps} } ] );
|
||||
|
@ -251,11 +258,17 @@ sub try {
|
|||
$req->sessionInfo->{ [ '_auth', '_userDB' ]->[$type] } = $name;
|
||||
$req->sessionInfo->{_combinationTry} =
|
||||
$req->data->{dataKeep}->{combinationTry};
|
||||
if ( $res > 0 and $res != PE_FIRSTACCESS ) {
|
||||
$self->userLogger->warn( 'All schemes failed'
|
||||
. ( $req->user ? ' for user ' . $req->user : '' ) . ' ('
|
||||
. $req->address
|
||||
. ')' );
|
||||
if ( $res > 0 ) {
|
||||
if ($stop) {
|
||||
$self->userLogger->info(
|
||||
"Combination stopped by plugin $name (code $res)");
|
||||
}
|
||||
elsif ( $res != PE_FIRSTACCESS ) {
|
||||
$self->userLogger->warn( 'All schemes failed'
|
||||
. ( $req->user ? ' for user ' . $req->user : '' ) . ' ('
|
||||
. $req->address
|
||||
. ')' );
|
||||
}
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
@ -269,6 +282,32 @@ sub name {
|
|||
|| 'Combination';
|
||||
}
|
||||
|
||||
sub stop {
|
||||
my ( $self, $mod, $res ) = @_;
|
||||
return 1
|
||||
if (
|
||||
$res <= 0 # PE_OK
|
||||
or $res == PE_CONFIRM
|
||||
or $res == PE_PASSWORD_OK
|
||||
|
||||
# TODO: adding this may generate behavior change
|
||||
#or $res == PE_FIRSTACCESS
|
||||
#or $res == PE_FORMEMPTY
|
||||
);
|
||||
my ( $ret, $name );
|
||||
$ret = $mod->( 'can', 'stop' );
|
||||
if ($ret) {
|
||||
eval { ( $ret, $name ) = $mod->( 'stop', $res ) };
|
||||
if ($@) {
|
||||
|
||||
$self->logger->error(
|
||||
"Optional ${name}::stop() method failed: " . $@ );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
|
||||
package Lemonldap::NG::Portal::Lib::Combination::UserLogger;
|
||||
|
||||
# This logger rewrite "warn" to "notice"
|
||||
|
|
|
@ -7,11 +7,12 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_DONE
|
||||
PE_ERROR
|
||||
PE_LDAPCONNECTFAILED
|
||||
PE_PP_ACCOUNT_LOCKED
|
||||
PE_PP_PASSWORD_EXPIRED
|
||||
PE_PP_CHANGE_AFTER_RESET
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.10';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
# Inheritance: UserDB::LDAP provides all needed ldap functions
|
||||
extends qw(
|
||||
|
@ -99,4 +100,17 @@ sub authLogout {
|
|||
return PE_OK;
|
||||
}
|
||||
|
||||
# Define which error codes will stop Combination process
|
||||
# @param res error code
|
||||
# @return result 1 if stop is needed
|
||||
sub stop {
|
||||
my ( $self, $res ) = @_;
|
||||
|
||||
return 1
|
||||
if ( $res == PE_PP_PASSWORD_EXPIRED
|
||||
or $res == PE_PP_ACCOUNT_LOCKED
|
||||
or $res == PE_PP_CHANGE_AFTER_RESET );
|
||||
return 0;
|
||||
}
|
||||
|
||||
1;
|
||||
|
|
|
@ -10,7 +10,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_IDPCHOICE
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends qw(
|
||||
Lemonldap::NG::Portal::Main::Auth
|
||||
|
|
|
@ -19,7 +19,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_PASSWORDFORMEMPTY
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.10';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends qw(
|
||||
Lemonldap::NG::Portal::Main::Auth
|
||||
|
|
|
@ -11,7 +11,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
|
||||
extends 'Lemonldap::NG::Portal::Lib::LDAP';
|
||||
|
||||
our $VERSION = '2.0.8';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
# PRIVATE METHOD
|
||||
sub modifCertificate {
|
||||
|
|
|
@ -15,7 +15,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
URIRE
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Issuer',
|
||||
'Lemonldap::NG::Portal::Lib::CAS';
|
||||
|
@ -61,8 +61,12 @@ sub init {
|
|||
|
||||
# Add CAS Services, so we can check service= parameter on logout
|
||||
foreach my $casSrv ( keys %{ $self->casAppList } ) {
|
||||
if ( my $serviceUrl =
|
||||
$self->casAppList->{$casSrv}->{casAppMetaDataOptionsService} )
|
||||
for my $serviceUrl (
|
||||
split(
|
||||
/\s+/,
|
||||
$self->casAppList->{$casSrv}->{casAppMetaDataOptionsService}
|
||||
)
|
||||
)
|
||||
{
|
||||
push @{ $self->p->{additionalTrustedDomains} }, $serviceUrl;
|
||||
$self->logger->debug(
|
||||
|
|
|
@ -20,7 +20,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
);
|
||||
use String::Random qw/random_string/;
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends qw(
|
||||
Lemonldap::NG::Portal::Main::Issuer
|
||||
|
|
|
@ -22,7 +22,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_UNAUTHORIZEDPARTNER
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Issuer',
|
||||
'Lemonldap::NG::Portal::Lib::SAML';
|
||||
|
|
|
@ -7,7 +7,7 @@ use XML::Simple;
|
|||
use Lemonldap::NG::Common::UserAgent;
|
||||
use URI;
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
# PROPERTIES
|
||||
|
||||
|
@ -531,22 +531,28 @@ sub getCasApp {
|
|||
|
||||
for my $app ( keys %{ $self->casAppList } ) {
|
||||
|
||||
my $candidateUri =
|
||||
URI->new( $self->casAppList->{$app}->{casAppMetaDataOptionsService} );
|
||||
my $candidateHost = $candidateUri->authority;
|
||||
my $candidateCanon = $candidateUri->canonical;
|
||||
for my $appservice (
|
||||
split(
|
||||
/\s+/, $self->casAppList->{$app}->{casAppMetaDataOptionsService}
|
||||
)
|
||||
)
|
||||
{
|
||||
my $candidateUri = URI->new($appservice);
|
||||
my $candidateHost = $candidateUri->authority;
|
||||
my $candidateCanon = $candidateUri->canonical;
|
||||
|
||||
# Try to match prefix, remembering the longest match found
|
||||
if ( index( $uriCanon, $candidateCanon ) == 0 ) {
|
||||
if ( length($longestCandidate) < length($candidateCanon) ) {
|
||||
$longestCandidate = $candidateCanon;
|
||||
$prefixConfKey = $app;
|
||||
# Try to match prefix, remembering the longest match found
|
||||
if ( index( $uriCanon, $candidateCanon ) == 0 ) {
|
||||
if ( length($longestCandidate) < length($candidateCanon) ) {
|
||||
$longestCandidate = $candidateCanon;
|
||||
$prefixConfKey = $app;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Try to match host, only if strict matching is disabled
|
||||
unless ( $self->conf->{casStrictMatching} ) {
|
||||
$hostnameConfKey = $app if ( $hostname eq $candidateHost );
|
||||
# Try to match host, only if strict matching is disabled
|
||||
unless ( $self->conf->{casStrictMatching} ) {
|
||||
$hostnameConfKey = $app if ( $hostname eq $candidateHost );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ use Safe;
|
|||
extends 'Lemonldap::NG::Portal::Lib::Wrapper';
|
||||
with 'Lemonldap::NG::Portal::Lib::OverConf';
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
has modules => ( is => 'rw', default => sub { {} } );
|
||||
has rules => ( is => 'rw', default => sub { {} } );
|
||||
|
|
|
@ -45,7 +45,6 @@ sub newLdap {
|
|||
)
|
||||
)
|
||||
{
|
||||
$self->logger->error("LDAP initialization error: $@");
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ sub new {
|
|||
( $conf->{ldapVerify} ? ( verify => $conf->{ldapVerify} ) : () ),
|
||||
);
|
||||
unless ($self) {
|
||||
$portal->logger->error($@);
|
||||
$portal->logger->error("LDAP initialization error: ". $@);
|
||||
return 0;
|
||||
}
|
||||
elsif ( $Net::LDAP::VERSION < '0.64' ) {
|
||||
|
@ -65,7 +65,7 @@ sub new {
|
|||
and $self->socket->errstr < 0 )
|
||||
{
|
||||
$portal->logger->error(
|
||||
"SSL connection error: " . $self->socket->errstr );
|
||||
"LDAP SSL connection failed: " . $self->socket->errstr );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,7 @@ sub new {
|
|||
$h{verify} ||= $conf->{ldapVerify} if ( $conf->{ldapVerify} );
|
||||
my $mesg = $self->start_tls(%h);
|
||||
if ( $mesg->code ) {
|
||||
$portal->logger->error( 'StartTLS failed: ' . $mesg->error );
|
||||
$portal->logger->error( 'LDAP StartTLS failed: ' . $mesg->error );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ use Mouse;
|
|||
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_REDIRECT);
|
||||
|
||||
our $VERSION = '2.0.13';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
# OpenID Connect standard claims
|
||||
use constant PROFILE => [
|
||||
|
|
|
@ -21,7 +21,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_SAML_SLO_ERROR
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
# PROPERTIES
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package Lemonldap::NG::Portal::Main::Auth;
|
|||
use strict;
|
||||
use Mouse;
|
||||
|
||||
our $VERSION = '2.0.0';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
|
||||
|
@ -11,4 +11,6 @@ extends 'Lemonldap::NG::Portal::Main::Plugin';
|
|||
|
||||
has authnLevel => ( is => 'rw' );
|
||||
|
||||
sub stop {0}
|
||||
|
||||
1;
|
||||
|
|
|
@ -85,6 +85,7 @@ sub display {
|
|||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
NOTIFICATION => $notif,
|
||||
HIDDEN_INPUTS => $self->buildHiddenForm($req),
|
||||
AUTH_URL => $req->{data}->{_url},
|
||||
|
@ -108,6 +109,7 @@ sub display {
|
|||
LANGS => $self->conf->{showLanguages},
|
||||
AUTH_ERROR => $req->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
AUTH_URL => $req->{data}->{_url},
|
||||
MSG => $req->info,
|
||||
HIDDEN_INPUTS => $self->buildHiddenForm($req),
|
||||
|
@ -139,6 +141,7 @@ sub display {
|
|||
LANGS => $self->conf->{showLanguages},
|
||||
AUTH_ERROR => $req->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
AUTH_URL => $req->{data}->{_url},
|
||||
HIDDEN_INPUTS => $self->buildHiddenForm($req),
|
||||
ACTIVE_TIMER => $req->data->{activeTimer},
|
||||
|
@ -150,7 +153,7 @@ sub display {
|
|||
ASK_LOGINS => $req->param('checkLogins') || 0,
|
||||
ASK_STAYCONNECTED => $req->param('stayconnected') || 0,
|
||||
CONFIRMKEY => $self->stamp(),
|
||||
LIST => $req->data->{list} || [],
|
||||
LIST => $req->data->{list} || [],
|
||||
(
|
||||
$req->data->{customScript}
|
||||
? ( CUSTOM_SCRIPT => $req->data->{customScript} )
|
||||
|
@ -173,8 +176,9 @@ sub display {
|
|||
LANGS => $self->conf->{showLanguages},
|
||||
AUTH_ERROR => $self->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
MSG => $info,
|
||||
URL => $req->{urldc} || $self->conf->{portal}, # Fix 2158
|
||||
URL => $req->{urldc} || $self->conf->{portal}, # Fix 2158
|
||||
HIDDEN_INPUTS => $self->buildOutgoingHiddenForm( $req, $method ),
|
||||
ACTIVE_TIMER => $req->data->{activeTimer},
|
||||
CHOICE_PARAM => $self->conf->{authChoiceParam},
|
||||
|
@ -206,6 +210,7 @@ sub display {
|
|||
LANGS => $self->conf->{showLanguages},
|
||||
AUTH_ERROR => $self->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
PROVIDERURI => $p,
|
||||
MSG => $req->info(),
|
||||
(
|
||||
|
@ -363,6 +368,7 @@ sub display {
|
|||
LANGS => $self->conf->{showLanguages},
|
||||
AUTH_ERROR => $req->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
LOCKTIME => $req->lockTime(),
|
||||
(
|
||||
$req->data->{customScript}
|
||||
|
@ -381,15 +387,16 @@ sub display {
|
|||
LANGS => $self->conf->{showLanguages},
|
||||
AUTH_ERROR => $req->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
AUTH_URL => $req->{data}->{_url},
|
||||
LOGIN => $login,
|
||||
DONT_STORE_PASSWORD => $self->conf->{browsersDontStorePassword},
|
||||
CHECK_LOGINS => $self->conf->{portalCheckLogins},
|
||||
ASK_LOGINS => $req->param('checkLogins') || 0,
|
||||
ASK_LOGINS => $req->param('checkLogins') || 0,
|
||||
ASK_STAYCONNECTED => $req->param('stayconnected') || 0,
|
||||
DISPLAY_RESETPASSWORD => $self->conf->{portalDisplayResetPassword},
|
||||
DISPLAY_REGISTER => $self->conf->{portalDisplayRegister},
|
||||
DISPLAY_UPDATECERTIF =>
|
||||
DISPLAY_UPDATECERTIF =>
|
||||
$self->conf->{portalDisplayCertificateResetByMail},
|
||||
MAILCERTIF_URL => $self->conf->{certificateResetByMailURL},
|
||||
MAIL_URL => $self->conf->{mailUrl},
|
||||
|
@ -560,12 +567,12 @@ sub display {
|
|||
: 0,
|
||||
DISPLAY_SSL_FORM => $displayType =~ /sslform/ ? 1 : 0,
|
||||
DISPLAY_GPG_FORM => $displayType =~ /gpgform/ ? 1 : 0,
|
||||
DISPLAY_LOGO_FORM => $displayType eq "logo" ? 1 : 0,
|
||||
DISPLAY_LOGO_FORM => $displayType eq "logo" ? 1 : 0,
|
||||
DISPLAY_FINDUSER => scalar @$fields,
|
||||
module => $displayType eq "logo"
|
||||
? $self->getModule( $req, 'auth' )
|
||||
: "",
|
||||
AUTH_LOOP => [],
|
||||
AUTH_LOOP => [],
|
||||
PORTAL_URL =>
|
||||
( $displayType eq "logo" ? $self->conf->{portal} : 0 ),
|
||||
MSG => $req->info(),
|
||||
|
@ -722,8 +729,7 @@ sub mkSessionArray {
|
|||
delete @rememberedData{
|
||||
grep {
|
||||
( not $rememberedData{$_} )
|
||||
or
|
||||
( $rememberedData{$_} eq "__hidden__" )
|
||||
or ( $rememberedData{$_} eq "__hidden__" )
|
||||
} keys %rememberedData
|
||||
};
|
||||
|
||||
|
@ -803,7 +809,8 @@ sub mkOidcConsent {
|
|||
'oidcConsents',
|
||||
params => {
|
||||
partners => [
|
||||
map { {
|
||||
map {
|
||||
{
|
||||
name => $_,
|
||||
epoch => $consents->{$_}->{epoch},
|
||||
scope => $consents->{$_}->{scope},
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
# of lemonldap-ng.ini) and underlying handler configuration
|
||||
package Lemonldap::NG::Portal::Main::Init;
|
||||
|
||||
our $VERSION = '2.0.13';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
package Lemonldap::NG::Portal::Main;
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ sub _redirect {
|
|||
$self->logger->debug(
|
||||
'Add ' . $self->ipath . ', ' . $self->ipath . 'Path in keepPdata' );
|
||||
push @{ $req->pdata->{keepPdata} }, $self->ipath, $self->ipath . 'Path';
|
||||
$req->{urldc} = $self->conf->{portal} . '/' . $self->path;
|
||||
$req->{urldc} = $self->p->buildUrl( $self->path );
|
||||
$req->pdata->{_url} = encode_base64( $req->urldc, '' );
|
||||
$req->pdata->{issuerTs} = time;
|
||||
}
|
||||
|
@ -128,7 +128,7 @@ sub _redirect {
|
|||
$self->restoreRequest( $_[0], $ir );
|
||||
$self->cleanPdata( $_[0] );
|
||||
return $self->run( @_, @path );
|
||||
}
|
||||
}
|
||||
: ()
|
||||
)
|
||||
]
|
||||
|
|
|
@ -7,7 +7,7 @@ use Mouse;
|
|||
use Clone 'clone';
|
||||
use Lemonldap::NG::Portal::Main::Constants 'URIRE';
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends 'Lemonldap::NG::Common::Module';
|
||||
|
||||
|
@ -116,6 +116,7 @@ sub params {
|
|||
$res{DISPLAY_MODULES} = $self->displayModules($req);
|
||||
$res{AUTH_ERROR_TYPE} =
|
||||
$req->error_type( $res{AUTH_ERROR} = $req->menuError );
|
||||
$res{AUTH_ERROR_ROLE} = $req->error_role;
|
||||
|
||||
# Display menu 2fRegisters link only if at least a 2F device is registered and rule
|
||||
$res{sfaManager} =
|
||||
|
@ -298,7 +299,7 @@ sub _buildApplicationHash {
|
|||
my $appuri = $apphash->{options}->{uri} || "";
|
||||
my $appdesc = $apphash->{options}->{description};
|
||||
my $applogo = $apphash->{options}->{logo};
|
||||
my $apptip = $apphash->{options}->{tooltip} || $appname;
|
||||
my $apptip = $apphash->{options}->{tooltip} || $appname;
|
||||
|
||||
# Detect sub applications
|
||||
my $subapphash;
|
||||
|
|
|
@ -11,7 +11,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_ERROR
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends 'Lemonldap::NG::Common::Module';
|
||||
|
||||
|
|
|
@ -85,9 +85,16 @@ has token => ( is => 'rw' );
|
|||
has wantErrorRender => ( is => 'rw' );
|
||||
|
||||
# Error type
|
||||
|
||||
sub error_role {
|
||||
my $req = shift;
|
||||
return $req->error_type(@_) eq 'negative' ? 'alert' : 'status';
|
||||
}
|
||||
|
||||
sub error_type {
|
||||
my $req = shift;
|
||||
my $code = shift || $req->error;
|
||||
$req->error($code);
|
||||
|
||||
# Positive errors
|
||||
return "positive"
|
||||
|
|
|
@ -289,6 +289,7 @@ sub do {
|
|||
params => {
|
||||
AUTH_ERROR => $err,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_BADCREDENTIALS
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.8';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends qw(
|
||||
Lemonldap::NG::Portal::Main::Plugin
|
||||
|
|
|
@ -600,6 +600,7 @@ sub display {
|
|||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
AUTH_ERROR => $req->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
AUTH_URL => $req->data->{_url},
|
||||
CHOICE_VALUE => $req->{_authChoice},
|
||||
EXPMAILDATE => $req->data->{expMailDate},
|
||||
|
|
|
@ -9,7 +9,7 @@ use strict;
|
|||
use Mouse;
|
||||
use Lemonldap::NG::Portal;
|
||||
|
||||
our $VERSION = '2.0.10';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
PE_SENDRESPONSE
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.12';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
extends qw(
|
||||
Lemonldap::NG::Portal::Main::Plugin
|
||||
|
|
|
@ -567,6 +567,7 @@ sub display {
|
|||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
AUTH_ERROR => $req->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
AUTH_URL => $req->data->{_url},
|
||||
CHOICE_VALUE => $req->{_authChoice},
|
||||
EXPMAILDATE => $req->data->{expMailDate},
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
# * GET /session/my/<type> : get session data
|
||||
# * GET /session/my/<type>/key : get session key
|
||||
# * DELETE /session/my : ask for logout
|
||||
# * DELETE /sessions/my : ask for global logout
|
||||
# * DELETE /sessions/my : ask for global logout (if GlobalLogout plugin is on)
|
||||
#
|
||||
# - Authentication
|
||||
# * GET /renewcaptcha : get token and captcha image
|
||||
|
@ -200,9 +200,16 @@ sub init {
|
|||
)
|
||||
|
||||
->addAuthRoute(
|
||||
sessions => { my => { ':sessionType' => 'removeSessions' } },
|
||||
session => { my => 'removeSession' },
|
||||
['DELETE']
|
||||
);
|
||||
|
||||
if ( $self->conf->{globalLogoutRule} ) {
|
||||
$self->addAuthRoute(
|
||||
sessions => { my => 'removeSessions' },
|
||||
['DELETE']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( $self->conf->{restPasswordServer} ) {
|
||||
|
@ -357,7 +364,7 @@ sub updateSession {
|
|||
|
||||
# Get session and store info
|
||||
my $session = $self->getApacheSession( $mod, $id, $infos, $force )
|
||||
or return $self->p->sendError( $req, 'Session id does not exists', 400 );
|
||||
or return $self->p->sendError( $req, 'Session Id does not exist', 400 );
|
||||
|
||||
return $self->p->sendJSONresponse( $req, { result => 1 } );
|
||||
}
|
||||
|
@ -370,7 +377,7 @@ sub delSession {
|
|||
|
||||
# Get session
|
||||
my $session = $self->getApacheSession( $mod, $id )
|
||||
or return $self->p->sendError( $req, 'Session id does not exists', 400 );
|
||||
or return $self->p->sendError( $req, 'Session Id does not exist', 400 );
|
||||
|
||||
# Delete it
|
||||
$self->logger->debug("REST request to delete session $id");
|
||||
|
@ -598,11 +605,30 @@ sub getError {
|
|||
errorNum => $errNum ? $errNum : 'all',
|
||||
errorsFileURL =>
|
||||
"$self->{conf}->{staticPrefix}/languages/$lang.json",
|
||||
( $errNum ? ( errorMsgRef => "PE$errNum" ) : () ),
|
||||
( $errNum ? ( errorMsgRef => "PE$errNum" ) : () )
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub removeSession {
|
||||
my ( $self, $req ) = @_;
|
||||
my $id = $req->userData->{_session_id};
|
||||
return $self->p->sendError( $req, 'ID is required', 400 ) unless ($id);
|
||||
my $mod = $self->getGlobal()
|
||||
or return $self->p->sendError( $req, undef, 400 );
|
||||
|
||||
# Get session
|
||||
my $session = $self->getApacheSession( $mod, $id )
|
||||
or return $self->p->sendError( $req, 'Session Id does not exist', 400 );
|
||||
|
||||
# Delete it
|
||||
$self->logger->debug("REST request to delete global session $id");
|
||||
my $res = $self->p->_deleteSession( $req, $session );
|
||||
$self->logger->debug(" Result is $res");
|
||||
|
||||
return $self->p->sendJSONresponse( $req, { result => $res } );
|
||||
}
|
||||
|
||||
sub removeSessions {
|
||||
my ( $self, $req ) = @_;
|
||||
my $glPlugin =
|
||||
|
@ -749,9 +775,8 @@ sub getUser {
|
|||
|
||||
# Search user in database
|
||||
$req->steps( [
|
||||
'getUser', 'setSessionInfo',
|
||||
'setMacros', 'setGroups',
|
||||
'setLocalGroups'
|
||||
'getUser', 'setSessionInfo',
|
||||
$self->p->groupsAndMacros, 'setLocalGroups'
|
||||
]
|
||||
);
|
||||
my $error = $self->p->process( $req, ( $mail ? ( useMail => 1 ) : () ) );
|
||||
|
@ -783,7 +808,8 @@ sub myApplications {
|
|||
{ Category => $_->{catname}, Applications => \@apps },
|
||||
} @{ $self->p->menu->appslist($req) };
|
||||
|
||||
return $self->p->sendJSONresponse( $req, { result => 1, myapplications => \@appslist } );
|
||||
return $self->p->sendJSONresponse( $req,
|
||||
{ result => 1, myapplications => \@appslist } );
|
||||
}
|
||||
|
||||
sub _checkSecret {
|
||||
|
|
|
@ -436,6 +436,7 @@ sub display {
|
|||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
AUTH_ERROR => $req->error,
|
||||
AUTH_ERROR_TYPE => $req->error_type,
|
||||
AUTH_ERROR_ROLE => $req->error_role,
|
||||
AUTH_URL => $req->data->{_url},
|
||||
CHOICE_PARAM => $self->conf->{authChoiceParam},
|
||||
CHOICE_VALUE => $req->data->{_authChoice},
|
||||
|
|
|
@ -9,7 +9,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
|
|||
|
||||
extends 'Lemonldap::NG::Portal::Register::LDAP';
|
||||
|
||||
our $VERSION = '2.0.10';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
sub createUser {
|
||||
my ( $self, $req ) = @_;
|
||||
|
|
|
@ -14,7 +14,7 @@ extends qw(
|
|||
Lemonldap::NG::Portal::Register::Base
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.10';
|
||||
our $VERSION = '2.0.14';
|
||||
|
||||
# RUNNING METHODS
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ setMsg = (msg, level) ->
|
|||
$('#color').addClass "message-#{level}"
|
||||
level = 'success' if level == 'positive'
|
||||
$('#color').addClass "alert-#{level}"
|
||||
$('#color').attr "role", "status"
|
||||
|
||||
displayError = (j, status, err) ->
|
||||
console.log 'Error', err
|
||||
|
|
|
@ -10,6 +10,7 @@ setMsg = (msg, level) ->
|
|||
$('#color').addClass "message-#{level}"
|
||||
level = 'success' if level == 'positive'
|
||||
$('#color').addClass "alert-#{level}"
|
||||
$('#color').attr "role", "status"
|
||||
|
||||
displayError = (j, status, err) ->
|
||||
setMsg 'notificationRetrieveFailed', 'warning'
|
||||
|
|
|
@ -13,6 +13,20 @@ translationFields = {}
|
|||
# content
|
||||
# - trplaceholder: set result in "placeholder" attribute
|
||||
# - localtime : transform time (in ms)ing translate()
|
||||
|
||||
setDanger = (cond, field) ->
|
||||
result = false
|
||||
if cond
|
||||
$("##{field}").addClass 'fa-check text-success'
|
||||
$("##{field}").removeClass 'fa-times text-danger'
|
||||
$("##{field}").attr 'role', 'status'
|
||||
else
|
||||
$("##{field}").addClass 'fa-times text-danger'
|
||||
$("##{field}").removeClass 'fa-check text-success'
|
||||
$("##{field}").attr 'role', 'alert'
|
||||
result = true
|
||||
result
|
||||
|
||||
translatePage = (lang) ->
|
||||
$.getJSON "#{window.staticPrefix}languages/#{lang}.json", (data) ->
|
||||
translationFields = data
|
||||
|
@ -33,7 +47,9 @@ translatePage = (lang) ->
|
|||
if msg.match /_hide_/
|
||||
$(this).parent().hide()
|
||||
$("[trplaceholder]").each ->
|
||||
$(this).attr 'placeholder', translate($(this).attr('trplaceholder'))
|
||||
tmp = translate($(this).attr('trplaceholder'))
|
||||
$(this).attr 'placeholder', tmp
|
||||
$(this).attr 'aria-label', tmp
|
||||
$("[localtime]").each ->
|
||||
d = new Date $(this).attr('localtime') * 1000
|
||||
$(this).text d.toLocaleString()
|
||||
|
@ -391,40 +407,16 @@ $(window).on 'load', () ->
|
|||
checkpassword = (password) ->
|
||||
result = true
|
||||
if window.datas.ppolicy.minsize > 0
|
||||
if password.length >= window.datas.ppolicy.minsize
|
||||
$('#ppolicy-minsize-feedback').addClass 'fa-check text-success'
|
||||
$('#ppolicy-minsize-feedback').removeClass 'fa-times text-danger'
|
||||
else
|
||||
$('#ppolicy-minsize-feedback').removeClass 'fa-check text-success'
|
||||
$('#ppolicy-minsize-feedback').addClass 'fa-times text-danger'
|
||||
result = false
|
||||
result = false if setDanger( password.length >= window.datas.ppolicy.minsize, 'ppolicy-minsize-feedback' )
|
||||
if window.datas.ppolicy.minupper > 0
|
||||
upper = password.match(/[A-Z]/g)
|
||||
if upper and upper.length >= window.datas.ppolicy.minupper
|
||||
$('#ppolicy-minupper-feedback').addClass 'fa-check text-success'
|
||||
$('#ppolicy-minupper-feedback').removeClass 'fa-times text-danger'
|
||||
else
|
||||
$('#ppolicy-minupper-feedback').removeClass 'fa-check text-success'
|
||||
$('#ppolicy-minupper-feedback').addClass 'fa-times text-danger'
|
||||
result = false
|
||||
result = false if setDanger( upper and upper.length >= window.datas.ppolicy.minupper, 'ppolicy-minupper-feedback' )
|
||||
if window.datas.ppolicy.minlower > 0
|
||||
lower = password.match(/[a-z]/g)
|
||||
if lower and lower.length >= window.datas.ppolicy.minlower
|
||||
$('#ppolicy-minlower-feedback').addClass 'fa-check text-success'
|
||||
$('#ppolicy-minlower-feedback').removeClass 'fa-times text-danger'
|
||||
else
|
||||
$('#ppolicy-minlower-feedback').removeClass 'fa-check text-success'
|
||||
$('#ppolicy-minlower-feedback').addClass 'fa-times text-danger'
|
||||
result = false
|
||||
result = false if setDanger( lower and lower.length >= window.datas.ppolicy.minlower, 'ppolicy-minlower-feedback')
|
||||
if window.datas.ppolicy.mindigit > 0
|
||||
digit = password.match(/[0-9]/g)
|
||||
if digit and digit.length >= window.datas.ppolicy.mindigit
|
||||
$('#ppolicy-mindigit-feedback').addClass 'fa-check text-success'
|
||||
$('#ppolicy-mindigit-feedback').removeClass 'fa-times text-danger'
|
||||
else
|
||||
$('#ppolicy-mindigit-feedback').removeClass 'fa-check text-success'
|
||||
$('#ppolicy-mindigit-feedback').addClass 'fa-times text-danger'
|
||||
result = false
|
||||
result = false if setDanger( digit and digit.length >= window.datas.ppolicy.mindigit, 'ppolicy-mindigit-feedback')
|
||||
|
||||
if window.datas.ppolicy.allowedspechar
|
||||
nonwhitespechar = window.datas.ppolicy.allowedspechar.replace(/\s/g, '')
|
||||
|
@ -436,13 +428,7 @@ $(window).on 'load', () ->
|
|||
if nonwhitespechar.indexOf(password.charAt(i)) < 0
|
||||
hasforbidden = true
|
||||
i++
|
||||
if hasforbidden == false
|
||||
$('#ppolicy-allowedspechar-feedback').addClass 'fa-check text-success'
|
||||
$('#ppolicy-allowedspechar-feedback').removeClass 'fa-times text-danger'
|
||||
else
|
||||
$('#ppolicy-allowedspechar-feedback').removeClass 'fa-check text-success'
|
||||
$('#ppolicy-allowedspechar-feedback').addClass 'fa-times text-danger'
|
||||
result = false
|
||||
result = false if setDanger( hasforbidden == false, 'ppolicy-allowedspechar-feedback' )
|
||||
|
||||
if window.datas.ppolicy.minspechar > 0 and window.datas.ppolicy.allowedspechar
|
||||
numspechar = 0
|
||||
|
@ -452,13 +438,7 @@ $(window).on 'load', () ->
|
|||
if nonwhitespechar.indexOf(password.charAt(i)) >= 0
|
||||
numspechar++
|
||||
i++
|
||||
if numspechar >= window.datas.ppolicy.minspechar
|
||||
$('#ppolicy-minspechar-feedback').addClass 'fa-check text-success'
|
||||
$('#ppolicy-minspechar-feedback').removeClass 'fa-times text-danger'
|
||||
else
|
||||
$('#ppolicy-minspechar-feedback').removeClass 'fa-check text-success'
|
||||
$('#ppolicy-minspechar-feedback').addClass 'fa-times text-danger'
|
||||
result = false
|
||||
result = false if setDanger( numspechar >= window.datas.ppolicy.minspechar, 'ppolicy-minspechar-feedback')
|
||||
|
||||
if window.datas.ppolicy.minspechar > 0 and !window.datas.ppolicy.allowedspechar
|
||||
numspechar = 0
|
||||
|
@ -466,13 +446,7 @@ $(window).on 'load', () ->
|
|||
while i < password.length
|
||||
numspechar++ if !isAlphaNumeric(password.charAt(i))
|
||||
i++
|
||||
if numspechar >= window.datas.ppolicy.minspechar
|
||||
$('#ppolicy-minspechar-feedback').addClass 'fa-check text-success'
|
||||
$('#ppolicy-minspechar-feedback').removeClass 'fa-times text-danger'
|
||||
else
|
||||
$('#ppolicy-minspechar-feedback').removeClass 'fa-check text-success'
|
||||
$('#ppolicy-minspechar-feedback').addClass 'fa-times text-danger'
|
||||
result = false
|
||||
result = false if setDanger( numspechar >= window.datas.ppolicy.minspechar, 'ppolicy-minspechar-feedback')
|
||||
|
||||
if result
|
||||
$('.ppolicy').removeClass('border-danger').addClass 'border-success'
|
||||
|
|
|
@ -9,6 +9,7 @@ setMsg = (msg, level) ->
|
|||
$('#color').addClass "message-#{level}"
|
||||
level = 'success' if level == 'positive'
|
||||
$('#color').addClass "alert-#{level}"
|
||||
$('#msg').attr 'role', (if level == 'danger' then 'alert' else 'status')
|
||||
|
||||
displayError = (j, status, err) ->
|
||||
console.log 'Error', err
|
||||
|
|
|
@ -9,6 +9,7 @@ setMsg = (msg, level) ->
|
|||
$('#color').addClass "message-#{level}"
|
||||
level = 'success' if level == 'positive'
|
||||
$('#color').addClass "alert-#{level}"
|
||||
$('#msg').attr 'role', (if level == 'danger' then 'alert' else 'status')
|
||||
|
||||
displayError = (j, status, err) ->
|
||||
console.log 'Error', err
|
||||
|
|
|
@ -15,7 +15,8 @@ LemonLDAP::NG 2F registration script
|
|||
if (level === 'positive') {
|
||||
level = 'success';
|
||||
}
|
||||
return $('#color').addClass("alert-" + level);
|
||||
$('#color').addClass("alert-" + level);
|
||||
return $('#color').attr("role", "status");
|
||||
};
|
||||
|
||||
displayError = function(j, status, err) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){var e,t,n;n=function(e,r){return $("#msg").attr("trspan",e),$("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning alert-success alert-warning"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r)},t=function(e,r,t){var o;if(console.log("Error",t),(o=JSON.parse(e.responseText))&&o.error)return o=o.error.replace(/.* /,""),console.log("Returned error",o),o.match(/module/)?n("notAuthorized","warning"):n(o,"warning")},e=function(e,r){return"U2F"===e?e="u":"UBK"===e?e="yubikey":"TOTP"===e?e="totp":n("u2fFailed","warning"),$.ajax({type:"POST",url:portal+"2fregisters/"+e+"/delete",data:{epoch:r},dataType:"json",error:t,success:function(e){return e.error?e.error.match(/notAuthorized/)?n("notAuthorized","warning"):n("unknownAction","warning"):e.result?($("#delete-"+r).hide(),n("yourKeyIsUnregistered","positive")):void 0},error:t})},$(document).ready(function(){return $("body").on("click",".remove2f",function(){return e($(this).attr("device"),$(this).attr("epoch"))}),$("#goback").attr("href",portal),$(".data-epoch").each(function(){var e;return e=new Date(1e3*$(this).text()),$(this).text(e.toLocaleString())})})}).call(this);
|
||||
!function(){var o=function(e,r){return $("#msg").attr("trspan",e),$("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning alert-success alert-warning"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r),$("#color").attr("role","status")},t=function(e,r,t){if(console.log("Error",t),(e=JSON.parse(e.responseText))&&e.error)return e=e.error.replace(/.* /,""),console.log("Returned error",e),e.match(/module/)?o("notAuthorized","warning"):o(e,"warning")},e=function(e,r){return"U2F"===e?e="u":"UBK"===e?e="yubikey":"TOTP"===e?e="totp":o("u2fFailed","warning"),$.ajax({type:"POST",url:portal+"2fregisters/"+e+"/delete",data:{epoch:r},dataType:"json",error:t,success:function(e){return e.error?e.error.match(/notAuthorized/)?o("notAuthorized","warning"):o("unknownAction","warning"):e.result?($("#delete-"+r).hide(),o("yourKeyIsUnregistered","positive")):void 0}})};$(document).ready(function(){return $("body").on("click",".remove2f",function(){return e($(this).attr("device"),$(this).attr("epoch"))}),$("#goback").attr("href",portal),$(".data-epoch").each(function(){var e=new Date(1e3*$(this).text());return $(this).text(e.toLocaleString())})})}.call(this);
|
|
@ -1 +1 @@
|
|||
{"version":3,"sources":["2fregistration.js"],"names":["delete2F","displayError","setMsg","msg","level","$","attr","html","window","translate","removeClass","addClass","j","status","err","res","console","log","JSON","parse","responseText","error","replace","match","device","epoch","ajax","type","url","portal","data","dataType","success","resp","result","hide","document","ready","on","this","each","myDate","Date","text","toLocaleString","call"],"mappings":"CAMA,WACE,IAAIA,EAAUC,EAAcC,EAE5BA,EAAS,SAASC,EAAKC,GAQrB,OAPAC,EAAE,QAAQC,KAAK,SAAUH,GACzBE,EAAE,QAAQE,KAAKC,OAAOC,UAAUN,IAChCE,EAAE,UAAUK,YAAY,gEACxBL,EAAE,UAAUM,SAAS,WAAaP,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUM,SAAS,SAAWP,IAGzCH,EAAe,SAASW,EAAGC,EAAQC,GACjC,IAAIC,EAGJ,GAFAC,QAAQC,IAAI,QAASH,IACrBC,EAAMG,KAAKC,MAAMP,EAAEQ,gBACRL,EAAIM,MAGb,OAFAN,EAAMA,EAAIM,MAAMC,QAAQ,MAAO,IAC/BN,QAAQC,IAAI,iBAAkBF,GAC1BA,EAAIQ,MAAM,UACLrB,EAAO,gBAAiB,WAExBA,EAAOa,EAAK,YAKzBf,EAAW,SAASwB,EAAQC,GAU1B,MATe,QAAXD,EACFA,EAAS,IACW,QAAXA,EACTA,EAAS,UACW,SAAXA,EACTA,EAAS,OAETtB,EAAO,YAAa,WAEfG,EAAEqB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,eAAiBL,EAAS,UACxCM,KAAM,CACJL,MAAOA,GAETM,SAAU,OACVV,MAAOpB,EACP+B,QAAS,SAASC,GAChB,OAAIA,EAAKZ,MACHY,EAAKZ,MAAME,MAAM,iBACZrB,EAAO,gBAAiB,WAExBA,EAAO,gBAAiB,WAExB+B,EAAKC,QACd7B,EAAE,WAAaoB,GAAOU,OACfjC,EAAO,wBAAyB,kBAFlC,GAKTmB,MAAOpB,KAIXI,EAAE+B,UAAUC,MAAM,WAKhB,OAJAhC,EAAE,QAAQiC,GAAG,QAAS,YAAa,WACjC,OAAOtC,EAASK,EAAEkC,MAAMjC,KAAK,UAAWD,EAAEkC,MAAMjC,KAAK,YAEvDD,EAAE,WAAWC,KAAK,OAAQuB,QACnBxB,EAAE,eAAemC,KAAK,WAC3B,IAAIC,EAEJ,OADAA,EAAS,IAAIC,KAAsB,IAAjBrC,EAAEkC,MAAMI,QACnBtC,EAAEkC,MAAMI,KAAKF,EAAOG,wBAI9BC,KAAKN"}
|
||||
{"version":3,"sources":["2fregistration.js"],"names":["setMsg","msg","level","$","attr","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","match","delete2F","device","epoch","ajax","type","url","portal","data","dataType","success","resp","result","hide","document","ready","on","this","each","myDate","Date","text","toLocaleString","call"],"mappings":"CAMA,WACE,IAEAA,EAAS,SAASC,EAAKC,GASrB,OARAC,EAAE,QAAQC,KAAK,SAAUH,GACzBE,EAAE,QAAQE,KAAKC,OAAOC,UAAUN,IAChCE,EAAE,UAAUK,YAAY,gEACxBL,EAAE,UAAUM,SAAS,WAAaP,GACpB,aAAVA,IACFA,EAAQ,WAEVC,EAAE,UAAUM,SAAS,SAAWP,GACzBC,EAAE,UAAUC,KAAK,OAAQ,WAGlCM,EAAe,SAASC,EAAGC,EAAQC,GAIjC,GAFAC,QAAQC,IAAI,QAASF,IACrBG,EAAMC,KAAKC,MAAMP,EAAEQ,gBACRH,EAAII,MAGb,OAFAJ,EAAMA,EAAII,MAAMC,QAAQ,MAAO,IAC/BP,QAAQC,IAAI,iBAAkBC,GAC1BA,EAAIM,MAAM,UACLtB,EAAO,gBAAiB,WAExBA,EAAOgB,EAAK,YAKzBO,EAAW,SAASC,EAAQC,GAU1B,MATe,QAAXD,EACFA,EAAS,IACW,QAAXA,EACTA,EAAS,UACW,SAAXA,EACTA,EAAS,OAETxB,EAAO,YAAa,WAEfG,EAAEuB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,eAAiBL,EAAS,UACxCM,KAAM,CACJL,MAAOA,GAETM,SAAU,OANEX,MAoBLV,EAZPsB,QAAS,SAASC,GAChB,OAAIA,EAAKb,MACHa,EAAKb,MAAME,MAAM,iBACZtB,EAAO,gBAAiB,WAExBA,EAAO,gBAAiB,WAExBiC,EAAKC,QACd/B,EAAE,WAAasB,GAAOU,OACfnC,EAAO,wBAAyB,kBAFlC,MASbG,EAAEiC,UAAUC,MAAM,WAKhB,OAJAlC,EAAE,QAAQmC,GAAG,QAAS,YAAa,WACjC,OAAOf,EAASpB,EAAEoC,MAAMnC,KAAK,UAAWD,EAAEoC,MAAMnC,KAAK,YAEvDD,EAAE,WAAWC,KAAK,OAAQyB,QACnB1B,EAAE,eAAeqC,KAAK,WAC3B,IACAC,EAAS,IAAIC,KAAsB,IAAjBvC,EAAEoC,MAAMI,QAC1B,OAAOxC,EAAEoC,MAAMI,KAAKF,EAAOG,uBAI9BC,KAAKN"}
|
|
@ -16,7 +16,8 @@ LemonLDAP::NG Notifications script
|
|||
if (level === 'positive') {
|
||||
level = 'success';
|
||||
}
|
||||
return $('#color').addClass("alert-" + level);
|
||||
$('#color').addClass("alert-" + level);
|
||||
return $('#color').attr("role", "status");
|
||||
};
|
||||
|
||||
displayError = function(j, status, err) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){var t,o,a,i,e,r,n;o=$("#msg").attr("trspan"),a=function(t,e){return $("#msg").html(window.translate(t)),$("#color").removeClass("message-positive message-warning alert-success alert-warning"),$("#color").addClass("message-"+e),"positive"===e&&(e="success"),$("#color").addClass("alert-"+e)},t=function(t,e,n){return a("notificationRetrieveFailed","warning"),console.log("Error:",n,"Status:",e)},r=function(t){return t?($("#icon-explorer-button").removeClass("fa-eye"),$("#icon-explorer-button").addClass("fa-eye-slash")):($("#icon-explorer-button").removeClass("fa-eye-slash"),$("#icon-explorer-button").addClass("fa-eye"))},e=function(t){return t?($("#explorer").hide(),$("#color").hide(),r(0)):($("#explorer").show(),$("#color").show(),r(1))},i=function(t,e,n){return a(o,"positive"),$(".btn-danger").each(function(){return $(this).removeClass("btn-danger"),$(this).addClass("btn-success")}),$(".fa-eye-slash").each(function(){return $(this).removeClass("fa-eye-slash"),$(this).addClass("fa-eye")}),$(".verify").each(function(){return $(this).text(window.translate("verify")),$(this).attr("trspan","verify")}),e&&n?(t.removeClass("btn-success"),t.addClass("btn-danger"),$("#icon-"+e+"-"+n).removeClass("fa-eye"),$("#icon-"+e+"-"+n).addClass("fa-eye-slash"),$("#text-"+e+"-"+n).text(window.translate("hide")),$("#text-"+e+"-"+n).attr("trspan","hide"),$("#myNotification").removeAttr("hidden"),r(1)):($("#myNotification").attr("hidden","true"),$("#explorer-button").attr("hidden","true"))},n=function(n,o,r){return console.log("Ref:",n,"epoch:",o),n&&o?(console.log("Send AJAX request"),$.ajax({type:"GET",url:portal+"mynotifications/"+n,data:{epoch:o},dataType:"json",error:t,success:function(t){var e;return t.result?(console.log("Notification:",t.notification),i(r,n,o),$("#displayNotif").html(t.notification),$("#notifRef").text(n),e=new Date(1e3*o),$("#notifEpoch").text(e.toLocaleString()),$("#explorer-button").removeAttr("hidden")):a("notificationNotFound","warning")}})):a("notificationRetrieveFailed","warning")},$(document).ready(function(){return $(".data-epoch").each(function(){var t;return t=new Date(1e3*$(this).text()),$(this).text(t.toLocaleString())}),$("#goback").attr("href",portal),$("body").on("click",".btn-success",function(){return n($(this).attr("notif"),$(this).attr("epoch"),$(this))}),$("body").on("click",".btn-danger",function(){return i($(this))}),$("body").on("click",".btn-info",function(){return e($("#explorer").is(":visible"))})})}).call(this);
|
||||
!function(){var o=$("#msg").attr("trspan"),r=function(t,e){return $("#msg").html(window.translate(t)),$("#color").removeClass("message-positive message-warning alert-success alert-warning"),$("#color").addClass("message-"+e),"positive"===e&&(e="success"),$("#color").addClass("alert-"+e),$("#color").attr("role","status")},t=function(t,e,n){return r("notificationRetrieveFailed","warning"),console.log("Error:",n,"Status:",e)},a=function(t){return t?($("#icon-explorer-button").removeClass("fa-eye"),$("#icon-explorer-button").addClass("fa-eye-slash")):($("#icon-explorer-button").removeClass("fa-eye-slash"),$("#icon-explorer-button").addClass("fa-eye"))},e=function(t){return t?($("#explorer").hide(),$("#color").hide(),a(0)):($("#explorer").show(),$("#color").show(),a(1))},i=function(t,e,n){return r(o,"positive"),$(".btn-danger").each(function(){return $(this).removeClass("btn-danger"),$(this).addClass("btn-success")}),$(".fa-eye-slash").each(function(){return $(this).removeClass("fa-eye-slash"),$(this).addClass("fa-eye")}),$(".verify").each(function(){return $(this).text(window.translate("verify")),$(this).attr("trspan","verify")}),e&&n?(t.removeClass("btn-success"),t.addClass("btn-danger"),$("#icon-"+e+"-"+n).removeClass("fa-eye"),$("#icon-"+e+"-"+n).addClass("fa-eye-slash"),$("#text-"+e+"-"+n).text(window.translate("hide")),$("#text-"+e+"-"+n).attr("trspan","hide"),$("#myNotification").removeAttr("hidden"),a(1)):($("#myNotification").attr("hidden","true"),$("#explorer-button").attr("hidden","true"))},n=function(e,n,o){return console.log("Ref:",e,"epoch:",n),e&&n?(console.log("Send AJAX request"),$.ajax({type:"GET",url:portal+"mynotifications/"+e,data:{epoch:n},dataType:"json",error:t,success:function(t){return t.result?(console.log("Notification:",t.notification),i(o,e,n),$("#displayNotif").html(t.notification),$("#notifRef").text(e),t=new Date(1e3*n),$("#notifEpoch").text(t.toLocaleString()),$("#explorer-button").removeAttr("hidden")):r("notificationNotFound","warning")}})):r("notificationRetrieveFailed","warning")};$(document).ready(function(){return $(".data-epoch").each(function(){var t=new Date(1e3*$(this).text());return $(this).text(t.toLocaleString())}),$("#goback").attr("href",portal),$("body").on("click",".btn-success",function(){return n($(this).attr("notif"),$(this).attr("epoch"),$(this))}),$("body").on("click",".btn-danger",function(){return i($(this))}),$("body").on("click",".btn-info",function(){return e($("#explorer").is(":visible"))})})}.call(this);
|
|
@ -1 +1 @@
|
|||
{"version":3,"sources":["notifications.js"],"names":["displayError","msg","setMsg","toggle","toggle_explorer","toggle_eye","viewNotif","$","attr","level","html","window","translate","removeClass","addClass","j","status","err","console","log","slash","visible","hide","show","button","notif","epoch","each","this","text","removeAttr","ajax","type","url","portal","data","dataType","error","success","resp","myDate","result","notification","Date","toLocaleString","document","ready","on","is","call"],"mappings":"CAMA,WACE,IAAIA,EAAcC,EAAKC,EAAQC,EAAQC,EAAiBC,EAAYC,EAEpEL,EAAMM,EAAE,QAAQC,KAAK,UAErBN,EAAS,SAASD,EAAKQ,GAOrB,OANAF,EAAE,QAAQG,KAAKC,OAAOC,UAAUX,IAChCM,EAAE,UAAUM,YAAY,gEACxBN,EAAE,UAAUO,SAAS,WAAaL,GACpB,aAAVA,IACFA,EAAQ,WAEHF,EAAE,UAAUO,SAAS,SAAWL,IAGzCT,EAAe,SAASe,EAAGC,EAAQC,GAEjC,OADAf,EAAO,6BAA8B,WAC9BgB,QAAQC,IAAI,SAAUF,EAAK,UAAWD,IAG/CX,EAAa,SAASe,GACpB,OAAIA,GACFb,EAAE,yBAAyBM,YAAY,UAChCN,EAAE,yBAAyBO,SAAS,kBAE3CP,EAAE,yBAAyBM,YAAY,gBAChCN,EAAE,yBAAyBO,SAAS,YAI/CV,EAAkB,SAASiB,GACzB,OAAIA,GACFd,EAAE,aAAae,OACff,EAAE,UAAUe,OACLjB,EAAW,KAElBE,EAAE,aAAagB,OACfhB,EAAE,UAAUgB,OACLlB,EAAW,KAItBF,EAAS,SAASqB,EAAQC,EAAOC,GAc/B,OAbAxB,EAAOD,EAAK,YACZM,EAAE,eAAeoB,KAAK,WAEpB,OADApB,EAAEqB,MAAMf,YAAY,cACbN,EAAEqB,MAAMd,SAAS,iBAE1BP,EAAE,iBAAiBoB,KAAK,WAEtB,OADApB,EAAEqB,MAAMf,YAAY,gBACbN,EAAEqB,MAAMd,SAAS,YAE1BP,EAAE,WAAWoB,KAAK,WAEhB,OADApB,EAAEqB,MAAMC,KAAKlB,OAAOC,UAAU,WACvBL,EAAEqB,MAAMpB,KAAK,SAAU,YAE5BiB,GAASC,GACXF,EAAOX,YAAY,eACnBW,EAAOV,SAAS,cAChBP,EAAE,SAAWkB,EAAQ,IAAMC,GAAOb,YAAY,UAC9CN,EAAE,SAAWkB,EAAQ,IAAMC,GAAOZ,SAAS,gBAC3CP,EAAE,SAAWkB,EAAQ,IAAMC,GAAOG,KAAKlB,OAAOC,UAAU,SACxDL,EAAE,SAAWkB,EAAQ,IAAMC,GAAOlB,KAAK,SAAU,QACjDD,EAAE,mBAAmBuB,WAAW,UACzBzB,EAAW,KAElBE,EAAE,mBAAmBC,KAAK,SAAU,QAC7BD,EAAE,oBAAoBC,KAAK,SAAU,UAIhDF,EAAY,SAASmB,EAAOC,EAAOF,GAEjC,OADAN,QAAQC,IAAI,OAAQM,EAAO,SAAUC,GACjCD,GAASC,GACXR,QAAQC,IAAI,qBACLZ,EAAEwB,KAAK,CACZC,KAAM,MACNC,IAAKC,OAAS,mBAAqBT,EACnCU,KAAM,CACJT,MAAOA,GAETU,SAAU,OACVC,MAAOrC,EACPsC,QAAS,SAASC,GAChB,IAAIC,EACJ,OAAID,EAAKE,QACPvB,QAAQC,IAAI,gBAAiBoB,EAAKG,cAClCvC,EAAOqB,EAAQC,EAAOC,GACtBnB,EAAE,iBAAiBG,KAAK6B,EAAKG,cAC7BnC,EAAE,aAAasB,KAAKJ,GACpBe,EAAS,IAAIG,KAAa,IAARjB,GAClBnB,EAAE,eAAesB,KAAKW,EAAOI,kBACtBrC,EAAE,oBAAoBuB,WAAW,WAEjC5B,EAAO,uBAAwB,eAKrCA,EAAO,6BAA8B,YAIhDK,EAAEsC,UAAUC,MAAM,WAahB,OAZAvC,EAAE,eAAeoB,KAAK,WACpB,IAAIa,EAEJ,OADAA,EAAS,IAAIG,KAAsB,IAAjBpC,EAAEqB,MAAMC,QACnBtB,EAAEqB,MAAMC,KAAKW,EAAOI,oBAE7BrC,EAAE,WAAWC,KAAK,OAAQ0B,QAC1B3B,EAAE,QAAQwC,GAAG,QAAS,eAAgB,WACpC,OAAOzC,EAAUC,EAAEqB,MAAMpB,KAAK,SAAUD,EAAEqB,MAAMpB,KAAK,SAAUD,EAAEqB,SAEnErB,EAAE,QAAQwC,GAAG,QAAS,cAAe,WACnC,OAAO5C,EAAOI,EAAEqB,SAEXrB,EAAE,QAAQwC,GAAG,QAAS,YAAa,WACxC,OAAO3C,EAAgBG,EAAE,aAAayC,GAAG,mBAI5CC,KAAKrB"}
|
||||
{"version":3,"sources":["notifications.js"],"names":["msg","$","attr","setMsg","level","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","toggle_eye","slash","toggle_explorer","visible","hide","show","toggle","button","notif","epoch","each","this","text","removeAttr","viewNotif","ajax","type","url","portal","data","dataType","error","success","resp","result","notification","myDate","Date","toLocaleString","document","ready","on","is","call"],"mappings":"CAMA,WACE,IAEAA,EAAMC,EAAE,QAAQC,KAAK,UAErBC,EAAS,SAASH,EAAKI,GAQrB,OAPAH,EAAE,QAAQI,KAAKC,OAAOC,UAAUP,IAChCC,EAAE,UAAUO,YAAY,gEACxBP,EAAE,UAAUQ,SAAS,WAAaL,GACpB,aAAVA,IACFA,EAAQ,WAEVH,EAAE,UAAUQ,SAAS,SAAWL,GACzBH,EAAE,UAAUC,KAAK,OAAQ,WAGlCQ,EAAe,SAASC,EAAGC,EAAQC,GAEjC,OADAV,EAAO,6BAA8B,WAC9BW,QAAQC,IAAI,SAAUF,EAAK,UAAWD,IAG/CI,EAAa,SAASC,GACpB,OAAIA,GACFhB,EAAE,yBAAyBO,YAAY,UAChCP,EAAE,yBAAyBQ,SAAS,kBAE3CR,EAAE,yBAAyBO,YAAY,gBAChCP,EAAE,yBAAyBQ,SAAS,YAI/CS,EAAkB,SAASC,GACzB,OAAIA,GACFlB,EAAE,aAAamB,OACfnB,EAAE,UAAUmB,OACLJ,EAAW,KAElBf,EAAE,aAAaoB,OACfpB,EAAE,UAAUoB,OACLL,EAAW,KAItBM,EAAS,SAASC,EAAQC,EAAOC,GAc/B,OAbAtB,EAAOH,EAAK,YACZC,EAAE,eAAeyB,KAAK,WAEpB,OADAzB,EAAE0B,MAAMnB,YAAY,cACbP,EAAE0B,MAAMlB,SAAS,iBAE1BR,EAAE,iBAAiByB,KAAK,WAEtB,OADAzB,EAAE0B,MAAMnB,YAAY,gBACbP,EAAE0B,MAAMlB,SAAS,YAE1BR,EAAE,WAAWyB,KAAK,WAEhB,OADAzB,EAAE0B,MAAMC,KAAKtB,OAAOC,UAAU,WACvBN,EAAE0B,MAAMzB,KAAK,SAAU,YAE5BsB,GAASC,GACXF,EAAOf,YAAY,eACnBe,EAAOd,SAAS,cAChBR,EAAE,SAAWuB,EAAQ,IAAMC,GAAOjB,YAAY,UAC9CP,EAAE,SAAWuB,EAAQ,IAAMC,GAAOhB,SAAS,gBAC3CR,EAAE,SAAWuB,EAAQ,IAAMC,GAAOG,KAAKtB,OAAOC,UAAU,SACxDN,EAAE,SAAWuB,EAAQ,IAAMC,GAAOvB,KAAK,SAAU,QACjDD,EAAE,mBAAmB4B,WAAW,UACzBb,EAAW,KAElBf,EAAE,mBAAmBC,KAAK,SAAU,QAC7BD,EAAE,oBAAoBC,KAAK,SAAU,UAIhD4B,EAAY,SAASN,EAAOC,EAAOF,GAEjC,OADAT,QAAQC,IAAI,OAAQS,EAAO,SAAUC,GACjCD,GAASC,GACXX,QAAQC,IAAI,qBACLd,EAAE8B,KAAK,CACZC,KAAM,MACNC,IAAKC,OAAS,mBAAqBV,EACnCW,KAAM,CACJV,MAAOA,GAETW,SAAU,OACVC,MAAO3B,EACP4B,QAAS,SAASC,GAEhB,OAAIA,EAAKC,QACP1B,QAAQC,IAAI,gBAAiBwB,EAAKE,cAClCnB,EAAOC,EAAQC,EAAOC,GACtBxB,EAAE,iBAAiBI,KAAKkC,EAAKE,cAC7BxC,EAAE,aAAa2B,KAAKJ,GACpBkB,EAAS,IAAIC,KAAa,IAARlB,GAClBxB,EAAE,eAAe2B,KAAKc,EAAOE,kBACtB3C,EAAE,oBAAoB4B,WAAW,WAEjC1B,EAAO,uBAAwB,eAKrCA,EAAO,6BAA8B,YAIhDF,EAAE4C,UAAUC,MAAM,WAahB,OAZA7C,EAAE,eAAeyB,KAAK,WACpB,IACAgB,EAAS,IAAIC,KAAsB,IAAjB1C,EAAE0B,MAAMC,QAC1B,OAAO3B,EAAE0B,MAAMC,KAAKc,EAAOE,oBAE7B3C,EAAE,WAAWC,KAAK,OAAQgC,QAC1BjC,EAAE,QAAQ8C,GAAG,QAAS,eAAgB,WACpC,OAAOjB,EAAU7B,EAAE0B,MAAMzB,KAAK,SAAUD,EAAE0B,MAAMzB,KAAK,SAAUD,EAAE0B,SAEnE1B,EAAE,QAAQ8C,GAAG,QAAS,cAAe,WACnC,OAAOzB,EAAOrB,EAAE0B,SAEX1B,EAAE,QAAQ8C,GAAG,QAAS,YAAa,WACxC,OAAO7B,EAAgBjB,EAAE,aAAa+C,GAAG,kBAI5CC,KAAKtB"}
|
|
@ -5,11 +5,27 @@ LemonLDAP::NG Portal jQuery scripts
|
|||
*/
|
||||
|
||||
(function() {
|
||||
var datas, delKey, getCookie, getQueryParam, getValues, isHiddenFormValueSet, ping, removeOidcConsent, restoreOrder, setCookie, setKey, setOrder, setSelector, translate, translatePage, translationFields,
|
||||
var datas, delKey, getCookie, getQueryParam, getValues, isHiddenFormValueSet, ping, removeOidcConsent, restoreOrder, setCookie, setDanger, setKey, setOrder, setSelector, translate, translatePage, translationFields,
|
||||
indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
translationFields = {};
|
||||
|
||||
setDanger = function(cond, field) {
|
||||
var result;
|
||||
result = false;
|
||||
if (cond) {
|
||||
$("#" + field).addClass('fa-check text-success');
|
||||
$("#" + field).removeClass('fa-times text-danger');
|
||||
$("#" + field).attr('role', 'status');
|
||||
} else {
|
||||
$("#" + field).addClass('fa-times text-danger');
|
||||
$("#" + field).removeClass('fa-check text-success');
|
||||
$("#" + field).attr('role', 'alert');
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
translatePage = function(lang) {
|
||||
return $.getJSON(window.staticPrefix + "languages/" + lang + ".json", function(data) {
|
||||
var k, ref, ref1, v;
|
||||
|
@ -45,7 +61,10 @@ LemonLDAP::NG Portal jQuery scripts
|
|||
}
|
||||
});
|
||||
$("[trplaceholder]").each(function() {
|
||||
return $(this).attr('placeholder', translate($(this).attr('trplaceholder')));
|
||||
var tmp;
|
||||
tmp = translate($(this).attr('trplaceholder'));
|
||||
$(this).attr('placeholder', tmp);
|
||||
return $(this).attr('aria-label', tmp);
|
||||
});
|
||||
return $("[localtime]").each(function() {
|
||||
var d;
|
||||
|
@ -411,45 +430,25 @@ LemonLDAP::NG Portal jQuery scripts
|
|||
var digit, hasforbidden, i, len, lower, nonwhitespechar, numspechar, ref3, ref4, result, upper;
|
||||
result = true;
|
||||
if (window.datas.ppolicy.minsize > 0) {
|
||||
if (password.length >= window.datas.ppolicy.minsize) {
|
||||
$('#ppolicy-minsize-feedback').addClass('fa-check text-success');
|
||||
$('#ppolicy-minsize-feedback').removeClass('fa-times text-danger');
|
||||
} else {
|
||||
$('#ppolicy-minsize-feedback').removeClass('fa-check text-success');
|
||||
$('#ppolicy-minsize-feedback').addClass('fa-times text-danger');
|
||||
if (setDanger(password.length >= window.datas.ppolicy.minsize, 'ppolicy-minsize-feedback')) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
if (window.datas.ppolicy.minupper > 0) {
|
||||
upper = password.match(/[A-Z]/g);
|
||||
if (upper && upper.length >= window.datas.ppolicy.minupper) {
|
||||
$('#ppolicy-minupper-feedback').addClass('fa-check text-success');
|
||||
$('#ppolicy-minupper-feedback').removeClass('fa-times text-danger');
|
||||
} else {
|
||||
$('#ppolicy-minupper-feedback').removeClass('fa-check text-success');
|
||||
$('#ppolicy-minupper-feedback').addClass('fa-times text-danger');
|
||||
if (setDanger(upper && upper.length >= window.datas.ppolicy.minupper, 'ppolicy-minupper-feedback')) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
if (window.datas.ppolicy.minlower > 0) {
|
||||
lower = password.match(/[a-z]/g);
|
||||
if (lower && lower.length >= window.datas.ppolicy.minlower) {
|
||||
$('#ppolicy-minlower-feedback').addClass('fa-check text-success');
|
||||
$('#ppolicy-minlower-feedback').removeClass('fa-times text-danger');
|
||||
} else {
|
||||
$('#ppolicy-minlower-feedback').removeClass('fa-check text-success');
|
||||
$('#ppolicy-minlower-feedback').addClass('fa-times text-danger');
|
||||
if (setDanger(lower && lower.length >= window.datas.ppolicy.minlower, 'ppolicy-minlower-feedback')) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
if (window.datas.ppolicy.mindigit > 0) {
|
||||
digit = password.match(/[0-9]/g);
|
||||
if (digit && digit.length >= window.datas.ppolicy.mindigit) {
|
||||
$('#ppolicy-mindigit-feedback').addClass('fa-check text-success');
|
||||
$('#ppolicy-mindigit-feedback').removeClass('fa-times text-danger');
|
||||
} else {
|
||||
$('#ppolicy-mindigit-feedback').removeClass('fa-check text-success');
|
||||
$('#ppolicy-mindigit-feedback').addClass('fa-times text-danger');
|
||||
if (setDanger(digit && digit.length >= window.datas.ppolicy.mindigit, 'ppolicy-mindigit-feedback')) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
@ -466,12 +465,7 @@ LemonLDAP::NG Portal jQuery scripts
|
|||
}
|
||||
i++;
|
||||
}
|
||||
if (hasforbidden === false) {
|
||||
$('#ppolicy-allowedspechar-feedback').addClass('fa-check text-success');
|
||||
$('#ppolicy-allowedspechar-feedback').removeClass('fa-times text-danger');
|
||||
} else {
|
||||
$('#ppolicy-allowedspechar-feedback').removeClass('fa-check text-success');
|
||||
$('#ppolicy-allowedspechar-feedback').addClass('fa-times text-danger');
|
||||
if (setDanger(hasforbidden === false, 'ppolicy-allowedspechar-feedback')) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
@ -485,12 +479,7 @@ LemonLDAP::NG Portal jQuery scripts
|
|||
}
|
||||
i++;
|
||||
}
|
||||
if (numspechar >= window.datas.ppolicy.minspechar) {
|
||||
$('#ppolicy-minspechar-feedback').addClass('fa-check text-success');
|
||||
$('#ppolicy-minspechar-feedback').removeClass('fa-times text-danger');
|
||||
} else {
|
||||
$('#ppolicy-minspechar-feedback').removeClass('fa-check text-success');
|
||||
$('#ppolicy-minspechar-feedback').addClass('fa-times text-danger');
|
||||
if (setDanger(numspechar >= window.datas.ppolicy.minspechar, 'ppolicy-minspechar-feedback')) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
@ -503,12 +492,7 @@ LemonLDAP::NG Portal jQuery scripts
|
|||
}
|
||||
i++;
|
||||
}
|
||||
if (numspechar >= window.datas.ppolicy.minspechar) {
|
||||
$('#ppolicy-minspechar-feedback').addClass('fa-check text-success');
|
||||
$('#ppolicy-minspechar-feedback').removeClass('fa-times text-danger');
|
||||
} else {
|
||||
$('#ppolicy-minspechar-feedback').removeClass('fa-check text-success');
|
||||
$('#ppolicy-minspechar-feedback').addClass('fa-times text-danger');
|
||||
if (setDanger(numspechar >= window.datas.ppolicy.minspechar, 'ppolicy-minspechar-feedback')) {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -15,7 +15,8 @@ LemonLDAP::NG TOTP registration script
|
|||
if (level === 'positive') {
|
||||
level = 'success';
|
||||
}
|
||||
return $('#color').addClass("alert-" + level);
|
||||
$('#color').addClass("alert-" + level);
|
||||
return $('#msg').attr('role', (level === 'danger' ? 'alert' : 'status'));
|
||||
};
|
||||
|
||||
displayError = function(j, status, err) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){var r,e,s,o,t;s=function(e,r){return $("#msg").attr("trspan",e),$("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning message-danger alert-success alert-warning alert-danger"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r)},r=function(e,r,t){var o;if(console.log("Error",t),(o=JSON.parse(e.responseText))&&o.error)return o=o.error.replace(/.* /,""),console.log("Returned error",o),s(o,"warning")},o="",e=function(){return s("yourTotpKey","warning"),$.ajax({type:"POST",url:portal+"/2fregisters/totp/getkey",dataType:"json",error:r,success:function(e){var r,t;return e.error?(e.error.match(/totpExistingKey/)&&$("#divToHide").hide(),s(e.error,"warning")):e.portal&&e.user&&e.secret?($("#divToHide").show(),r="otpauth://totp/"+escape(e.portal)+":"+escape(e.user)+"?secret="+e.secret+"&issuer="+escape(e.portal),6!==e.digits&&(r+="&digits="+e.digits),30!==e.interval&&(r+="&period="+e.interval),new QRious({element:document.getElementById("qr"),value:r,size:150}),t=e.secret||"",$("#secret").text(t.toUpperCase().replace(/(.{4})/g,"$1 ").trim()),e.newkey?s("yourNewTotpKey","warning"):s("yourTotpKey","success"),o=e.token):s("PE24","danger")}})},t=function(){var e;return(e=$("#code").val())?$.ajax({type:"POST",url:portal+"/2fregisters/totp/verify",dataType:"json",data:{token:o,code:e,TOTPName:$("#TOTPName").val()},error:r,success:function(e){return e.error?e.error.match(/bad(Code|Name)/)?s(e.error,"warning"):s(e.error,"danger"):s("yourKeyIsRegistered","success")}}):(s("totpMissingCode","warning"),$("#code").focus())},$(document).ready(function(){return e(),$("#verify").on("click",function(){return t()})})}).call(this);
|
||||
!function(){var s=function(e,r){return $("#msg").attr("trspan",e),$("#msg").html(window.translate(e)),$("#color").removeClass("message-positive message-warning message-danger alert-success alert-warning alert-danger"),$("#color").addClass("message-"+r),"positive"===r&&(r="success"),$("#color").addClass("alert-"+r),$("#msg").attr("role","danger"===r?"alert":"status")},r=function(e,r,t){if(console.log("Error",t),(e=JSON.parse(e.responseText))&&e.error)return e=e.error.replace(/.* /,""),console.log("Returned error",e),s(e,"warning")},t="",e=function(){return s("yourTotpKey","warning"),$.ajax({type:"POST",url:portal+"/2fregisters/totp/getkey",dataType:"json",error:r,success:function(e){var r;return e.error?(e.error.match(/totpExistingKey/)&&$("#divToHide").hide(),s(e.error,"warning")):e.portal&&e.user&&e.secret?($("#divToHide").show(),r="otpauth://totp/"+escape(e.portal)+":"+escape(e.user)+"?secret="+e.secret+"&issuer="+escape(e.portal),6!==e.digits&&(r+="&digits="+e.digits),30!==e.interval&&(r+="&period="+e.interval),new QRious({element:document.getElementById("qr"),value:r,size:150}),r=e.secret||"",$("#secret").text(r.toUpperCase().replace(/(.{4})/g,"$1 ").trim()),e.newkey?s("yourNewTotpKey","warning"):s("yourTotpKey","success"),t=e.token):s("PE24","danger")}})},o=function(){var e=$("#code").val();return e?$.ajax({type:"POST",url:portal+"/2fregisters/totp/verify",dataType:"json",data:{token:t,code:e,TOTPName:$("#TOTPName").val()},error:r,success:function(e){return e.error?e.error.match(/bad(Code|Name)/)?s(e.error,"warning"):s(e.error,"danger"):s("yourKeyIsRegistered","success")}}):(s("totpMissingCode","warning"),$("#code").focus())};$(document).ready(function(){return e(),$("#verify").on("click",o)})}.call(this);
|
|
@ -1 +1 @@
|
|||
{"version":3,"sources":["totpregistration.js"],"names":["displayError","getKey","setMsg","token","verify","msg","level","$","attr","html","window","translate","removeClass","addClass","j","status","err","res","console","log","JSON","parse","responseText","error","replace","ajax","type","url","portal","dataType","success","data","s","secret","match","hide","user","show","escape","digits","interval","QRious","element","document","getElementById","value","size","text","toUpperCase","trim","newkey","val","code","TOTPName","focus","ready","on","call","this"],"mappings":"CAMA,WACE,IAAIA,EAAcC,EAAQC,EAAQC,EAAOC,EAEzCF,EAAS,SAASG,EAAKC,GAQrB,OAPAC,EAAE,QAAQC,KAAK,SAAUH,GACzBE,EAAE,QAAQE,KAAKC,OAAOC,UAAUN,IAChCE,EAAE,UAAUK,YAAY,4FACxBL,EAAE,UAAUM,SAAS,WAAaP,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUM,SAAS,SAAWP,IAGzCN,EAAe,SAASc,EAAGC,EAAQC,GACjC,IAAIC,EAGJ,GAFAC,QAAQC,IAAI,QAASH,IACrBC,EAAMG,KAAKC,MAAMP,EAAEQ,gBACRL,EAAIM,MAGb,OAFAN,EAAMA,EAAIM,MAAMC,QAAQ,MAAO,IAC/BN,QAAQC,IAAI,iBAAkBF,GACvBf,EAAOe,EAAK,YAIvBd,EAAQ,GAERF,EAAS,WAEP,OADAC,EAAO,cAAe,WACfK,EAAEkB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVN,MAAOvB,EACP8B,QAAS,SAASC,GAChB,IAAQC,EAAGC,EACX,OAAIF,EAAKR,OACHQ,EAAKR,MAAMW,MAAM,oBACnB3B,EAAE,cAAc4B,OAEXjC,EAAO6B,EAAKR,MAAO,YAEtBQ,EAAKH,QAAUG,EAAKK,MAAQL,EAAKE,QAGvC1B,EAAE,cAAc8B,OAChBL,EAAI,kBAAqBM,OAAOP,EAAKH,QAAW,IAAOU,OAAOP,EAAKK,MAAS,WAAaL,EAAKE,OAAS,WAAcK,OAAOP,EAAKH,QAC7G,IAAhBG,EAAKQ,SACPP,GAAK,WAAaD,EAAKQ,QAEH,KAAlBR,EAAKS,WACPR,GAAK,WAAaD,EAAKS,UAEpB,IAAIC,OAAO,CACdC,QAASC,SAASC,eAAe,MACjCC,MAAOb,EACPc,KAAM,MAERb,EAASF,EAAKE,QAAU,GACxB1B,EAAE,WAAWwC,KAAKd,EAAOe,cAAcxB,QAAQ,UAAW,OAAOyB,QAC7DlB,EAAKmB,OACPhD,EAAO,iBAAkB,WAEzBA,EAAO,cAAe,WAEjBC,EAAQ4B,EAAK5B,OAtBXD,EAAO,OAAQ,cA2B9BE,EAAS,WACP,IAAI+C,EAEJ,OADAA,EAAM5C,EAAE,SAAS4C,OAKR5C,EAAEkB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVE,KAAM,CACJ5B,MAAOA,EACPiD,KAAMD,EACNE,SAAU9C,EAAE,aAAa4C,OAE3B5B,MAAOvB,EACP8B,QAAS,SAASC,GAChB,OAAIA,EAAKR,MACHQ,EAAKR,MAAMW,MAAM,kBACZhC,EAAO6B,EAAKR,MAAO,WAEnBrB,EAAO6B,EAAKR,MAAO,UAGrBrB,EAAO,sBAAuB,eArB3CA,EAAO,kBAAmB,WACnBK,EAAE,SAAS+C,UA2BtB/C,EAAEoC,UAAUY,MAAM,WAEhB,OADAtD,IACOM,EAAE,WAAWiD,GAAG,QAAS,WAC9B,OAAOpD,UAIVqD,KAAKC"}
|
||||
{"version":3,"sources":["totpregistration.js"],"names":["setMsg","msg","level","$","attr","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","token","getKey","ajax","type","url","portal","dataType","success","data","secret","match","hide","user","show","s","escape","digits","interval","QRious","element","document","getElementById","value","size","text","toUpperCase","trim","newkey","verify","val","code","TOTPName","focus","ready","on","call","this"],"mappings":"CAMA,WACE,IAEAA,EAAS,SAASC,EAAKC,GASrB,OARAC,EAAE,QAAQC,KAAK,SAAUH,GACzBE,EAAE,QAAQE,KAAKC,OAAOC,UAAUN,IAChCE,EAAE,UAAUK,YAAY,4FACxBL,EAAE,UAAUM,SAAS,WAAaP,GACpB,aAAVA,IACFA,EAAQ,WAEVC,EAAE,UAAUM,SAAS,SAAWP,GACzBC,EAAE,QAAQC,KAAK,OAAmB,WAAVF,EAAqB,QAAU,WAGhEQ,EAAe,SAASC,EAAGC,EAAQC,GAIjC,GAFAC,QAAQC,IAAI,QAASF,IACrBG,EAAMC,KAAKC,MAAMP,EAAEQ,gBACRH,EAAII,MAGb,OAFAJ,EAAMA,EAAII,MAAMC,QAAQ,MAAO,IAC/BP,QAAQC,IAAI,iBAAkBC,GACvBhB,EAAOgB,EAAK,YAIvBM,EAAQ,GAERC,EAAS,WAEP,OADAvB,EAAO,cAAe,WACfG,EAAEqB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVR,MAAOV,EACPmB,QAAS,SAASC,GAChB,IAAWC,EACX,OAAID,EAAKV,OACHU,EAAKV,MAAMY,MAAM,oBACnB7B,EAAE,cAAc8B,OAEXjC,EAAO8B,EAAKV,MAAO,YAEtBU,EAAKH,QAAUG,EAAKI,MAAQJ,EAAKC,QAGvC5B,EAAE,cAAcgC,OAChBC,EAAI,kBAAqBC,OAAOP,EAAKH,QAAW,IAAOU,OAAOP,EAAKI,MAAS,WAAaJ,EAAKC,OAAS,WAAcM,OAAOP,EAAKH,QAC7G,IAAhBG,EAAKQ,SACPF,GAAK,WAAaN,EAAKQ,QAEH,KAAlBR,EAAKS,WACPH,GAAK,WAAaN,EAAKS,UAEpB,IAAIC,OAAO,CACdC,QAASC,SAASC,eAAe,MACjCC,MAAOR,EACPS,KAAM,MAERd,EAASD,EAAKC,QAAU,GACxB5B,EAAE,WAAW2C,KAAKf,EAAOgB,cAAc1B,QAAQ,UAAW,OAAO2B,QAC7DlB,EAAKmB,OACPjD,EAAO,iBAAkB,WAEzBA,EAAO,cAAe,WAEjBsB,EAAQQ,EAAKR,OAtBXtB,EAAO,OAAQ,cA2B9BkD,EAAS,WACP,IACAC,EAAMhD,EAAE,SAASgD,MACjB,OAAKA,EAIIhD,EAAEqB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVE,KAAM,CACJR,MAAOA,EACP8B,KAAMD,EACNE,SAAUlD,EAAE,aAAagD,OAE3B/B,MAAOV,EACPmB,QAAS,SAASC,GAChB,OAAIA,EAAKV,MACHU,EAAKV,MAAMY,MAAM,kBACZhC,EAAO8B,EAAKV,MAAO,WAEnBpB,EAAO8B,EAAKV,MAAO,UAGrBpB,EAAO,sBAAuB,eArB3CA,EAAO,kBAAmB,WACnBG,EAAE,SAASmD,UA2BtBnD,EAAEuC,UAAUa,MAAM,WAEhB,OADAhC,IACOpB,EAAE,WAAWqD,GAAG,QACdN,MAIVO,KAAKC"}
|
|
@ -15,7 +15,8 @@ LemonLDAP::NG U2F registration script
|
|||
if (level === 'positive') {
|
||||
level = 'success';
|
||||
}
|
||||
return $('#color').addClass("alert-" + level);
|
||||
$('#color').addClass("alert-" + level);
|
||||
return $('#msg').attr('role', (level === 'danger' ? 'alert' : 'status'));
|
||||
};
|
||||
|
||||
displayError = function(j, status, err) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
(function(){var n,r,t,e;t=function(r,e){return $("#msg").attr("trspan",r),$("#msg").html(window.translate(r)),$("#color").removeClass("message-positive message-warning message-danger alert-success alert-warning alert-danger"),$("#color").addClass("message-"+e),"positive"===e&&(e="success"),$("#color").addClass("alert-"+e)},n=function(r,e,n){var s;if(console.log("Error",n),(s=JSON.parse(r.responseText))&&s.error)return s=s.error.replace(/.* /,""),console.log("Returned error",s),t(s,"warning")},r=function(){return $.ajax({type:"POST",url:portal+"2fregisters/u/register",data:{},dataType:"json",error:n,success:function(e){var r;return r=[{challenge:e.challenge,version:e.version}],t("touchU2fDevice","positive"),$("#u2fPermission").show(),u2f.register(e.appId,r,[],function(r){return $("#u2fPermission").hide(),r.errorCode?t(r.error,"warning"):$.ajax({type:"POST",url:portal+"2fregisters/u/registration",data:{registration:JSON.stringify(r),challenge:JSON.stringify(e),keyName:$("#keyName").val()},dataType:"json",success:function(r){return r.error?r.error.match(/badName/)?t(r.error,"warning"):t("u2fFailed","danger"):r.result?t("yourKeyIsRegistered","positive"):void 0},error:n})})}})},e=function(){return $.ajax({type:"POST",url:portal+"2fregisters/u/verify",data:{},dataType:"json",error:n,success:function(e){return t("touchU2fDevice","positive"),u2f.sign(e.appId,e.challenge,e.registeredKeys,function(r){return r.errorCode?t("unableToGetKey","warning"):$.ajax({type:"POST",url:portal+"2fregisters/u/signature",data:{signature:JSON.stringify(r),challenge:e.challenge},dataType:"json",success:function(r){return r.error?t("u2fFailed","danger"):r.result?t("yourKeyIsVerified","positive"):void 0},error:function(r,e,n){return console.log("error",n)}})})}})},$(document).ready(function(){return $("#u2fPermission").hide(),$("#register").on("click",r),$("#verify").on("click",e),$("#goback").attr("href",portal)})}).call(this);
|
||||
!function(){var s=function(r,e){return $("#msg").attr("trspan",r),$("#msg").html(window.translate(r)),$("#color").removeClass("message-positive message-warning message-danger alert-success alert-warning alert-danger"),$("#color").addClass("message-"+e),"positive"===e&&(e="success"),$("#color").addClass("alert-"+e),$("#msg").attr("role","danger"===e?"alert":"status")},t=function(r,e,t){if(console.log("Error",t),(r=JSON.parse(r.responseText))&&r.error)return r=r.error.replace(/.* /,""),console.log("Returned error",r),s(r,"warning")},r=function(){return $.ajax({type:"POST",url:portal+"2fregisters/u/register",data:{},dataType:"json",error:t,success:function(e){var r=[{challenge:e.challenge,version:e.version}];return s("touchU2fDevice","positive"),$("#u2fPermission").show(),u2f.register(e.appId,r,[],function(r){return $("#u2fPermission").hide(),r.errorCode?s(r.error,"warning"):$.ajax({type:"POST",url:portal+"2fregisters/u/registration",data:{registration:JSON.stringify(r),challenge:JSON.stringify(e),keyName:$("#keyName").val()},dataType:"json",success:function(r){return r.error?r.error.match(/badName/)?s(r.error,"warning"):s("u2fFailed","danger"):r.result?s("yourKeyIsRegistered","positive"):void 0},error:t})})}})},e=function(){return $.ajax({type:"POST",url:portal+"2fregisters/u/verify",data:{},dataType:"json",error:t,success:function(e){return s("touchU2fDevice","positive"),u2f.sign(e.appId,e.challenge,e.registeredKeys,function(r){return r.errorCode?s("unableToGetKey","warning"):$.ajax({type:"POST",url:portal+"2fregisters/u/signature",data:{signature:JSON.stringify(r),challenge:e.challenge},dataType:"json",success:function(r){return r.error?s("u2fFailed","danger"):r.result?s("yourKeyIsVerified","positive"):void 0},error:function(r,e,t){return console.log("error",t)}})})}})};$(document).ready(function(){return $("#u2fPermission").hide(),$("#register").on("click",r),$("#verify").on("click",e),$("#goback").attr("href",portal)})}.call(this);
|
|
@ -1 +1 @@
|
|||
{"version":3,"sources":["u2fregistration.js"],"names":["displayError","register","setMsg","verify","msg","level","$","attr","html","window","translate","removeClass","addClass","j","status","err","res","console","log","JSON","parse","responseText","error","replace","ajax","type","url","portal","data","dataType","success","ch","request","challenge","version","show","u2f","appId","hide","errorCode","registration","stringify","keyName","val","resp","match","result","sign","registeredKeys","signature","document","ready","on","call","this"],"mappings":"CAMA,WACE,IAAIA,EAAcC,EAAUC,EAAQC,EAEpCD,EAAS,SAASE,EAAKC,GAQrB,OAPAC,EAAE,QAAQC,KAAK,SAAUH,GACzBE,EAAE,QAAQE,KAAKC,OAAOC,UAAUN,IAChCE,EAAE,UAAUK,YAAY,4FACxBL,EAAE,UAAUM,SAAS,WAAaP,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUM,SAAS,SAAWP,IAGzCL,EAAe,SAASa,EAAGC,EAAQC,GACjC,IAAIC,EAGJ,GAFAC,QAAQC,IAAI,QAASH,IACrBC,EAAMG,KAAKC,MAAMP,EAAEQ,gBACRL,EAAIM,MAGb,OAFAN,EAAMA,EAAIM,MAAMC,QAAQ,MAAO,IAC/BN,QAAQC,IAAI,iBAAkBF,GACvBd,EAAOc,EAAK,YAIvBf,EAAW,WACT,OAAOK,EAAEkB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,yBACdC,KAAM,GACNC,SAAU,OACVP,MAAOtB,EACP8B,QAAS,SAASC,GAChB,IAAIC,EASJ,OARAA,EAAU,CACR,CACEC,UAAWF,EAAGE,UACdC,QAASH,EAAGG,UAGhBhC,EAAO,iBAAkB,YACzBI,EAAE,kBAAkB6B,OACbC,IAAInC,SAAS8B,EAAGM,MAAOL,EAAS,GAAI,SAASJ,GAElD,OADAtB,EAAE,kBAAkBgC,OAChBV,EAAKW,UACArC,EAAO0B,EAAKN,MAAO,WAEnBhB,EAAEkB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,6BACdC,KAAM,CACJY,aAAcrB,KAAKsB,UAAUb,GAC7BK,UAAWd,KAAKsB,UAAUV,GAC1BW,QAASpC,EAAE,YAAYqC,OAEzBd,SAAU,OACVC,QAAS,SAASc,GAChB,OAAIA,EAAKtB,MACHsB,EAAKtB,MAAMuB,MAAM,WACZ3C,EAAO0C,EAAKtB,MAAO,WAEnBpB,EAAO,YAAa,UAEpB0C,EAAKE,OACP5C,EAAO,sBAAuB,iBADhC,GAIToB,MAAOtB,UAQnBG,EAAS,WACP,OAAOG,EAAEkB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,uBACdC,KAAM,GACNC,SAAU,OACVP,MAAOtB,EACP8B,QAAS,SAASC,GAEhB,OADA7B,EAAO,iBAAkB,YAClBkC,IAAIW,KAAKhB,EAAGM,MAAON,EAAGE,UAAWF,EAAGiB,eAAgB,SAASpB,GAClE,OAAIA,EAAKW,UACArC,EAAO,iBAAkB,WAEzBI,EAAEkB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,0BACdC,KAAM,CACJqB,UAAW9B,KAAKsB,UAAUb,GAC1BK,UAAWF,EAAGE,WAEhBJ,SAAU,OACVC,QAAS,SAASc,GAChB,OAAIA,EAAKtB,MACApB,EAAO,YAAa,UAClB0C,EAAKE,OACP5C,EAAO,oBAAqB,iBAD9B,GAIToB,MAAO,SAAST,EAAGC,EAAQC,GACzB,OAAOE,QAAQC,IAAI,QAASH,YAS1CT,EAAE4C,UAAUC,MAAM,WAIhB,OAHA7C,EAAE,kBAAkBgC,OACpBhC,EAAE,aAAa8C,GAAG,QAASnD,GAC3BK,EAAE,WAAW8C,GAAG,QAASjD,GAClBG,EAAE,WAAWC,KAAK,OAAQoB,YAGlC0B,KAAKC"}
|
||||
{"version":3,"sources":["u2fregistration.js"],"names":["setMsg","msg","level","$","attr","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","register","ajax","type","url","portal","data","dataType","success","ch","request","challenge","version","show","u2f","appId","hide","errorCode","registration","stringify","keyName","val","resp","match","result","verify","sign","registeredKeys","signature","document","ready","on","call","this"],"mappings":"CAMA,WACE,IAEAA,EAAS,SAASC,EAAKC,GASrB,OARAC,EAAE,QAAQC,KAAK,SAAUH,GACzBE,EAAE,QAAQE,KAAKC,OAAOC,UAAUN,IAChCE,EAAE,UAAUK,YAAY,4FACxBL,EAAE,UAAUM,SAAS,WAAaP,GACpB,aAAVA,IACFA,EAAQ,WAEVC,EAAE,UAAUM,SAAS,SAAWP,GACzBC,EAAE,QAAQC,KAAK,OAAmB,WAAVF,EAAqB,QAAU,WAGhEQ,EAAe,SAASC,EAAGC,EAAQC,GAIjC,GAFAC,QAAQC,IAAI,QAASF,IACrBG,EAAMC,KAAKC,MAAMP,EAAEQ,gBACRH,EAAII,MAGb,OAFAJ,EAAMA,EAAII,MAAMC,QAAQ,MAAO,IAC/BP,QAAQC,IAAI,iBAAkBC,GACvBhB,EAAOgB,EAAK,YAIvBM,EAAW,WACT,OAAOnB,EAAEoB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,yBACdC,KAAM,GACNC,SAAU,OACVR,MAAOV,EACPmB,QAAS,SAASC,GAChB,IACAC,EAAU,CACR,CACEC,UAAWF,EAAGE,UACdC,QAASH,EAAGG,UAKhB,OAFAjC,EAAO,iBAAkB,YACzBG,EAAE,kBAAkB+B,OACbC,IAAIb,SAASQ,EAAGM,MAAOL,EAAS,GAAI,SAASJ,GAElD,OADAxB,EAAE,kBAAkBkC,OAChBV,EAAKW,UACAtC,EAAO2B,EAAKP,MAAO,WAEnBjB,EAAEoB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,6BACdC,KAAM,CACJY,aAActB,KAAKuB,UAAUb,GAC7BK,UAAWf,KAAKuB,UAAUV,GAC1BW,QAAStC,EAAE,YAAYuC,OAEzBd,SAAU,OACVC,QAAS,SAASc,GAChB,OAAIA,EAAKvB,MACHuB,EAAKvB,MAAMwB,MAAM,WACZ5C,EAAO2C,EAAKvB,MAAO,WAEnBpB,EAAO,YAAa,UAEpB2C,EAAKE,OACP7C,EAAO,sBAAuB,iBADhC,GAIToB,MAAOV,UAQnBoC,EAAS,WACP,OAAO3C,EAAEoB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,uBACdC,KAAM,GACNC,SAAU,OACVR,MAAOV,EACPmB,QAAS,SAASC,GAEhB,OADA9B,EAAO,iBAAkB,YAClBmC,IAAIY,KAAKjB,EAAGM,MAAON,EAAGE,UAAWF,EAAGkB,eAAgB,SAASrB,GAClE,OAAIA,EAAKW,UACAtC,EAAO,iBAAkB,WAEzBG,EAAEoB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,0BACdC,KAAM,CACJsB,UAAWhC,KAAKuB,UAAUb,GAC1BK,UAAWF,EAAGE,WAEhBJ,SAAU,OACVC,QAAS,SAASc,GAChB,OAAIA,EAAKvB,MACApB,EAAO,YAAa,UAClB2C,EAAKE,OACP7C,EAAO,oBAAqB,iBAD9B,GAIToB,MAAO,SAAST,EAAGC,EAAQC,GACzB,OAAOC,QAAQC,IAAI,QAASF,YAS1CV,EAAE+C,UAAUC,MAAM,WAIhB,OAHAhD,EAAE,kBAAkBkC,OACpBlC,EAAE,aAAaiD,GAAG,QAAS9B,GAC3BnB,EAAE,WAAWiD,GAAG,QAASN,GAClB3C,EAAE,WAAWC,KAAK,OAAQsB,WAGlC2B,KAAKC"}
|
|
@ -337,4 +337,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"Your TOTP key",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -337,4 +337,4 @@
|
|||
"yourProfile":"Know your profile",
|
||||
"yourTotpKey":"Your TOTP key",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -337,4 +337,4 @@
|
|||
"yourProfile":"Conozca su perfil",
|
||||
"yourTotpKey":"Su llave TOTP",
|
||||
"yubikey2f":"Yubikey"
|
||||
}
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue