Merge branch 'v2.0' into 2589

This commit is contained in:
Christophe Maudoux 2021-08-20 20:06:22 +02:00
commit 017408d005
85 changed files with 661 additions and 374 deletions

View File

@ -1,3 +1,26 @@
lemonldap-ng (2.0.13) focal; urgency=medium
* Bugs:
* #2428: Correctly report the number of purged sessions when using deleteIfLowerThan
* #2566: No configuration available in fresh LemonLDAP 2.0.12
* #2567: CORS headers not sent in userinfo endpoint error response
* #2568: SafeJail does not report errors correctly
* #2573: convertConfig does not work when target backend is empty
* #2589: FindUser plugin: minor improvements and several issues
* Improvements:
* #2558: Add a new portal error code for Auth::OIDC issues
* #2564: Missing options to use text emails for some features
* #2585: RGAA: to use autocomplete when possible
* #2589: FindUser plugin: minor improvements and several issues
* #2592: Bad error reporting during portal init
* Templates:
* #2585: RGAA: to use autocomplete when possible
* #2589: FindUser plugin: minor improvements and several issues
-- Clément <clem.oudot@gmail.com> Fri, 20 Aug 2021 18:30:23 +0200
lemonldap-ng (2.0.12) focal; urgency=medium
* Bugs:

7
debian/changelog vendored
View File

@ -1,3 +1,10 @@
lemonldap-ng (2.0.13-1) unstable; urgency=medium
* New release. See changes on our website:
https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng
-- Clement OUDOT <clement@oodo.net> Fri, 20 Aug 2021 22:00:00 +0100
lemonldap-ng (2.0.12-1) unstable; urgency=medium
* New release. See changes on our website:

View File

@ -445,8 +445,10 @@ radiusServer
randomPasswordRegexp Regular expression to create a random password ✔
redirectFormMethod HTTP method for redirect page form ✔
refreshSessions Refresh sessions plugin ✔
registerConfirmBody Mail body for register confirmation ✔
registerConfirmSubject Mail subject for register confirmation ✔
registerDB Register module ✔
registerDoneBody Mail body when register is done ✔
registerDoneSubject Mail subject when register is done ✔
registerTimeout Register session timeout ✔
registerUrl URL of register page ✔

View File

@ -11,9 +11,9 @@ Main Logo
~~~~~~~~~
You can change the default Main Logo in Manager: General Parameters >
Portal > Customization > Main Logo.
Portal > Customization > Main logo.
A blank value disables Main Logo display.
A blank value disables Main logo display.
.. tip::
@ -44,14 +44,14 @@ Custom CSS file
~~~~~~~~~~~~~~~
You can define a custom CSS file, for example ``custom.css``, which will
be loaded after default CSS files. This file needs to be created in the
be loaded after default CSS files. This file must be created in the
static repository
(``/usr/share/lemonldap-ng/portal/htdocs/static/bootstrap/css``).
Then set this value in Custom CSS parameter :
Then set this value in Custom CSS parameter:
``bootstrap/css/custom.css``.
Sample CSS file, to remove white background of main logo:
CSS file example to remove white background of main logo:
.. code-block:: css
@ -65,9 +65,9 @@ Sample CSS file, to remove white background of main logo:
Skin
----
LemonLDAP::NG is shipped with bootstrap skin.
LemonLDAP::NG is shipped with a bootstrap skin.
But you can make your own. See Skin customization below.
But you can provide your own. See Skin customization below.
Default skin
~~~~~~~~~~~~
@ -83,8 +83,7 @@ Skin background
Go in ``General Parameters`` > ``Portal`` > ``Customization`` >
``Skin background``. You can define a background by selecting one of the
available image. Use ``None`` to use the default skin background
configuration.
available image. Select ``None`` to use the default skin background configuration.
|image0|
@ -112,7 +111,7 @@ user.
To achieve this, you can create a rule in the Manager: select
``General Parameters`` > ``Portal`` > ``Customization`` >
``Skin display rules`` on click on "New key". Then fill the two fields;
``Skin display rules`` and click on "New entry". Then fill the two fields;
- **Key**: a Perl expression (you can use ``%ENV`` hash to get environment
variables, or ``$_url`` to get URL called before redirection, or ``$ipAddr``
@ -216,9 +215,9 @@ lemonldap-ng-cli:
Messages
~~~~~~~~
Messages are defined in source code. If they really do not please you,
Messages are defined in source code. If they really do not suit you,
override them! You just need to know the ID of the message (look at
Portal/Simple.pm).
Portal/Main/Constants.pm).
There are two methods to do this:
@ -240,7 +239,7 @@ boxes by using the bareword ``_hide_`` :
.. code-block:: ini
error_en_0 = Big brother is watching you, authenticated user
error_fr_0 = Souriez vous êtes surveillés !
error_fr_0 = Souriez, vous êtes surveillés !
msg_fr_lastLogins = Dernières connexions
error_9 = _hide_
@ -309,28 +308,26 @@ You can also display environment variables, with the prefix ``env_``:
Your IP is <TMPL_VAR NAME="env_REMOTE_ADDR">
Buttons
-------
Buttons on login page
---------------------
This node allows one to enable/disable buttons on the login page:
- **Check last logins**: display a checkbox on login form, allowing
user to check his login history right after opening session
- **Register new account**: display a link to :doc:`register page<register>` (for
password based authentication backends)
- **Reset your certificate**: display a link to :doc:`reset certificate page<resetcertificate>` (for
password based authentication backends)
- **Reset password**: display a link to
:doc:`reset your password page<resetpassword>` (for password based
authentication backends). Number of allowed retries can be set (3
times by default)
- **Register**: display a link to :doc:`register page<register>` (for
password based authentication backends)
- **Reset certificate**: display a link to :doc:`reset certificate page<resetcertificate>` (for
password based authentication backends)
- **Max reset password retries**: number of retries allowed for resetting password
Password management
-------------------
General
~~~~~~~
- **Require old password**: used only in the password changing module
of the menu, will check the old password before updating it
- **Hide old password**: used only if the password need to be reset by
@ -343,26 +340,27 @@ General
revealed. Disabled by default.
Password Policy
~~~~~~~~~~~~~~~
---------------
.. tip::
Available since version 2.0.6
- **Activation**: enable/disable password policy. You can set a rule
to enable policy for specific users only
- **Display policy in password form**: enable this option to display an
information message about password policy constraints
- **Minimal size**: leave 0 to bypass the check
- **Minimal lower characters**: leave 0 to bypass the check
- **Minimal upper characters**: leave 0 to bypass the check
- **Minimal digit characters**: leave 0 to bypass the check
- **Minimal special characters**: leave 0 to bypass the check
- **Allowed special characters**: set '__ALL__' value to allow ALL special characters. A blanck value forbids ALL special characters (Note that ``_`` is not a special character)
- **Display policy in password form**: enable this to display an
information message about password policy constraints
.. _portalcustom-other-parameters:
Other parameters
----------------
Other
-----
- **User attribute**: which session attribute will be used to display
``Connected as`` in the menu
@ -379,6 +377,7 @@ Other parameters
- **Show error on mail not found**: Display error if provided mail is
not found in password reset by mail process. Disabled by default to
prevent mail enumeration from this page.
- **Display rights refresh link**: Enable/disable link in Portal menu to allow users to refresh their rights
.. |image0| image:: /documentation/manager-skin-background.png
:class: align-center

View File

@ -4,30 +4,43 @@ Register a new account
Presentation
------------
This feature is a page that allows a user to create an account. The
steps are the following:
This feature is a page that allows a user to create an account.
Following steps are performed:
#. User click on the button "Create a new account"
#. He enters first name, last name and email
#. He gets a mail with a confirmation link
#. After clicking, his entry is added
#. He gets a mail with his login and his password
#. They enter first name, last name and email
#. They receive an email with a confirmation link
#. After clicking, their account is created
#. An email with his login and password is sent
Configuration
-------------
You can enable the "Create your account" button in
:doc:`portal customization parameters<portalcustom>`.
The "Create your account" button can be enabled in
:doc:`Portal customization parameters<portalcustom>`.
Then, go in ``Portal`` > ``Advanced parameters`` >
``Register new account``:
Then, go in ``General Parameters`` > ``Plugins`` > ``Register new account``:
- **Module**: Choose the backend to use to create the new account.
- **Module**: Backend used for creating new account.
- **Page URL**: URL of register page
- **Validity time of a register request**: duration in seconds of a new
- **Validity time of a register request**: Duration in seconds of a new
account request. The request will be deleted after this time if user
do not click on the link.
- **Subject for confirmation mail**: Subject of the mail containing the
- **Subject for confirmation mail**: Subject of the email containing the
confirmation link
- **Subject for done mail**: Subject of the mail giving login and
password
- **Body for confirmation mail**: The plain text content of the confirmation email the user will
receive. If you leave it blank, the ``mail_register_confirm`` HTML template will be used.
Confirmation link is stored in the ``$url`` variable
- **Subject for done mail**: Subject of the email providing login and password.
- **Body for done mail**: The plain text content of the done email the user will
receive. If you leave it blank, the ``mail_register_done`` HTML template will be used.
Login and generated password are stored in the corresponding ``$login`` and ``$password`` variables
.. note::
Following variables are available in:
\* Register email body => ``$expMailDate``, ``$expMailTime``, ``$url``, ``$mail``, ``$firstname``, ``$lastname`` and ``$ipAddr``
\* Done email body => ``$login``, ``$password`` and ``$url``

View File

@ -26,6 +26,14 @@ Known regressions in the latest released version
None
2.0.13
------
Portal templates changes
~~~~~~~~~~~~~~~~~~~~~~~~
Some ``autocomplete`` attributes have been added to improve accessibility in the following files: ``checkdevops.tpl``, ``checkuser.tpl``, ``register.tpl``, ``ext2fcheck.tpl``, ``totp2fcheck.tpl``, ``utotp2fcheck.tpl``.
2.0.12
------

View File

@ -4,7 +4,7 @@
"Xavier Guimard <x.guimard@free.fr>, Clément Oudot <clement@oodo.net>"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010",
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
"license" : [
"open_source"
],
@ -78,6 +78,6 @@
],
"x_MailingList" : "mailto:lemonldap-ng-dev@ow2.org"
},
"version" : "v2.0.12",
"version" : "v2.0.13",
"x_serialization_backend" : "JSON::PP version 4.04"
}

View File

@ -10,7 +10,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010'
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
license: open_source
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@ -54,5 +54,5 @@ resources:
bugtracker: https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues
homepage: http://lemonldap-ng.org/
license: http://opensource.org/licenses/GPL-2.0
version: v2.0.12
version: v2.0.13
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'

View File

@ -1,6 +1,6 @@
package Lemonldap::NG::Common;
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
1;
__END__

View File

@ -119,7 +119,6 @@ sub saveConf {
my ( $self, $conf, %args ) = @_;
my $last = $self->lastCfg;
return UNKNOWN_ERROR if $last < 1;
# If configuration was modified, return an error
if ( not $args{force} ) {

View File

@ -5,7 +5,7 @@ use strict;
use Exporter 'import';
use base qw(Exporter);
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
# CONSTANTS

View File

@ -1,7 +1,7 @@
# This file is generated by Lemonldap::NG::Manager::Build. Don't modify it by hand
package Lemonldap::NG::Common::Conf::DefaultValues;
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
sub defaultValues {
return {

View File

@ -5,7 +5,7 @@ use strict;
use Exporter 'import';
use base qw(Exporter);
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
our %EXPORT_TAGS = ( 'all' => [qw($simpleHashKeys $doubleHashKeys $specialNodeKeys $casAppMetaDataNodeKeys $casSrvMetaDataNodeKeys $oidcOPMetaDataNodeKeys $oidcRPMetaDataNodeKeys $samlIDPMetaDataNodeKeys $samlSPMetaDataNodeKeys $virtualHostKeys $specialNodeHash $authParameters $issuerParameters $samlServiceParameters $oidcServiceParameters $casServiceParameters)] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

View File

@ -4,7 +4,7 @@
"Xavier Guimard <x.guimard@free.fr>, Clément Oudot <clement@oodo.net>"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010",
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
"license" : [
"open_source"
],
@ -45,7 +45,7 @@
},
"requires" : {
"LWP::UserAgent" : "0",
"Lemonldap::NG::Common" : "v2.0.12",
"Lemonldap::NG::Common" : "v2.0.13",
"Mouse" : "0",
"URI" : "0"
}
@ -63,6 +63,6 @@
],
"x_MailingList" : "mailto:lemonldap-ng-dev@ow2.org"
},
"version" : "v2.0.12",
"version" : "v2.0.13",
"x_serialization_backend" : "JSON::PP version 4.04"
}

View File

@ -13,7 +13,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010'
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
license: open_source
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@ -30,7 +30,7 @@ recommends:
SOAP::Lite: '0'
requires:
LWP::UserAgent: '0'
Lemonldap::NG::Common: v2.0.12
Lemonldap::NG::Common: v2.0.13
Mouse: '0'
URI: '0'
resources:
@ -39,5 +39,5 @@ resources:
bugtracker: https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues
homepage: http://lemonldap-ng.org/
license: http://opensource.org/licenses/GPL-2.0
version: v2.0.12
version: v2.0.13
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'

View File

@ -39,7 +39,7 @@ WriteMakefile(
},
},
PREREQ_PM => {
'Lemonldap::NG::Common' => '2.0.12',
'Lemonldap::NG::Common' => '2.0.13',
'LWP::UserAgent' => 0,
'Mouse' => 0,
'URI' => 0,

View File

@ -3,7 +3,7 @@ package Lemonldap::NG::Handler;
# Use the appropriate handler
# For Apache, use Lemonldap::NG::Handler::ApacheMP2
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
1;

View File

@ -4,7 +4,7 @@ package Lemonldap::NG::Handler::Lib::StatusConstants;
use strict;
use Exporter 'import';
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
sub portalConsts {
return {

View File

@ -639,6 +639,7 @@ sub oauth2Init {
sub substitute {
my ( $class, $expr ) = @_;
$expr ||= '';
# substitute special vars, just for retro-compatibility
$expr =~ s/\$date\b/&date/sg;

View File

@ -140,7 +140,7 @@ sub run {
# Try to recover cookie and user session
$id = $class->fetchId($req);
$class->data( {} ) unless($id);
$class->data( {} ) unless ($id);
if ( $id
and $session = $class->retrieveSession( $req, $id ) )
{
@ -321,7 +321,7 @@ sub getLevel {
$i++
)
{
if ( $uri =~ $class->tsv->{locationRegexp}->{$vhost}->[$i] ) {
if ( $uri && $uri =~ $class->tsv->{locationRegexp}->{$vhost}->[$i] ) {
$level = $class->tsv->{locationAuthnLevel}->{$vhost}->[$i];
last;
}

View File

@ -45,7 +45,7 @@ ok( &$checkDate == "1",
my $sub4 =
"sub { return(checkDate('20000101000000+0100','21000101000000+0100')) }";
my $checkDate = $jail->jail_reval($sub4);
$checkDate = $jail->jail_reval($sub4);
ok( &$checkDate == "1",
'checkDate extended function working without Safe Jail' );

View File

@ -4,7 +4,7 @@
"Xavier Guimard <x.guimard@free.fr>, Clément Oudot <clement@oodo.net>"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010",
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
"license" : [
"open_source"
],
@ -41,8 +41,8 @@
"Convert::PEM" : "0",
"Crypt::OpenSSL::RSA" : "0",
"LWP::UserAgent" : "0",
"Lemonldap::NG::Common" : "v2.0.12",
"Lemonldap::NG::Handler" : "v2.0.12"
"Lemonldap::NG::Common" : "v2.0.13",
"Lemonldap::NG::Handler" : "v2.0.13"
}
}
},
@ -58,6 +58,6 @@
],
"x_MailingList" : "mailto:lemonldap-ng-dev@ow2.org"
},
"version" : "v2.0.12",
"version" : "v2.0.13",
"x_serialization_backend" : "JSON::PP version 4.04"
}

View File

@ -10,7 +10,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010'
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
license: open_source
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@ -26,13 +26,13 @@ requires:
Convert::PEM: '0'
Crypt::OpenSSL::RSA: '0'
LWP::UserAgent: '0'
Lemonldap::NG::Common: v2.0.12
Lemonldap::NG::Handler: v2.0.12
Lemonldap::NG::Common: v2.0.13
Lemonldap::NG::Handler: v2.0.13
resources:
MailingList: mailto:lemonldap-ng-dev@ow2.org
X_twitter: https://twitter.com/lemonldapng
bugtracker: https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues
homepage: http://lemonldap-ng.org/
license: http://opensource.org/licenses/GPL-2.0
version: v2.0.12
version: v2.0.13
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'

View File

@ -34,8 +34,8 @@ WriteMakefile(
PREREQ_PM => {
'Convert::PEM' => 0,
'Crypt::OpenSSL::RSA' => 0,
'Lemonldap::NG::Common' => '2.0.12',
'Lemonldap::NG::Handler' => '2.0.12',
'Lemonldap::NG::Common' => '2.0.13',
'Lemonldap::NG::Handler' => '2.0.13',
'LWP::UserAgent' => 0,
}, # e.g., Module::Name => 1.1
(

View File

@ -17,7 +17,7 @@ use JSON;
use Lemonldap::NG::Common::Conf::Constants;
use Lemonldap::NG::Common::PSGI::Constants;
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
extends qw(
Lemonldap::NG::Handler::PSGI::Router

View File

@ -1,7 +1,7 @@
# This file is generated by Lemonldap::NG::Manager::Build. Don't modify it by hand
package Lemonldap::NG::Manager::Attributes;
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
sub perlExpr {
my ( $val, $conf ) = @_;
@ -3021,6 +3021,9 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
'refreshSessions' => {
'type' => 'bool'
},
'registerConfirmBody' => {
'type' => 'longtext'
},
'registerConfirmSubject' => {
'type' => 'text'
},
@ -3049,6 +3052,9 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
],
'type' => 'select'
},
'registerDoneBody' => {
'type' => 'longtext'
},
'registerDoneSubject' => {
'type' => 'text'
},

View File

@ -6,7 +6,7 @@
package Lemonldap::NG::Manager::Build::Attributes;
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
use strict;
use Regexp::Common qw/URI/;
@ -1750,6 +1750,28 @@ sub attributes {
type => 'text',
documentation => 'Mail subject for register confirmation',
},
registerConfirmBody => {
type => 'longtext',
documentation => 'Mail body for register confirmation',
},
registerDoneSubject => {
type => 'text',
documentation => 'Mail subject when register is done',
},
registerDoneBody => {
type => 'longtext',
documentation => 'Mail body when register is done',
},
registerTimeout => {
default => 0,
type => 'int',
documentation => 'Register session timeout',
},
registerUrl => {
type => 'text',
default => 'http://auth.example.com/register',
documentation => 'URL of register page',
},
registerDB => {
type => 'select',
select => [
@ -1762,20 +1784,6 @@ sub attributes {
default => 'Null',
documentation => 'Register module',
},
registerDoneSubject => {
type => 'text',
documentation => 'Mail subject when register is done',
},
registerTimeout => {
default => 0,
type => 'int',
documentation => 'Register session timeout',
},
registerUrl => {
type => 'text',
default => 'http://auth.example.com/register',
documentation => 'URL of register page',
},
# Upgrade session
upgradeSession => {

View File

@ -17,7 +17,7 @@
package Lemonldap::NG::Manager::Build::Tree;
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
# TODO: Missing:
# * activeTimer
@ -64,10 +64,10 @@ sub tree {
form => 'simpleInputContainer',
nodes => [
'portalCheckLogins',
'portalDisplayResetPassword',
'passwordResetAllowedRetries',
'portalDisplayRegister',
'portalDisplayCertificateResetByMail'
'portalDisplayCertificateResetByMail',
'portalDisplayResetPassword',
'passwordResetAllowedRetries'
]
},
{
@ -752,7 +752,9 @@ sub tree {
'registerUrl',
'registerTimeout',
'registerConfirmSubject',
'registerDoneSubject'
'registerConfirmBody',
'registerDoneSubject',
'registerDoneBody'
]
},
{

View File

@ -406,7 +406,9 @@ sub tests {
},
samlSignatureOverrideNeedsCertificate => sub {
return 1 if $conf->{samlServicePublicKeySig} =~ /CERTIFICATE/;
return 1
if $conf->{samlServicePublicKeySig}
&& $conf->{samlServicePublicKeySig} =~ /CERTIFICATE/;
my @offenders;
for my $idp ( keys %{ $conf->{samlIDPMetaDataOptions} } ) {
@ -693,7 +695,7 @@ sub tests {
abs $_;
}
grep { /\d+/ }
split /\s*,\s*/, $conf->{bruteForceProtectionLockTimes};
split /\s*,\s*/, $conf->{bruteForceProtectionLockTimes} || '';
$conf->{bruteForceProtectionLockTimes} = join ', ', @lockTimes
if scalar @lockTimes;
return 1 unless ( $conf->{bruteForceProtection} );

View File

@ -841,8 +841,10 @@
"regexp":"التعبير النمطي",
"regexps":"التعبير النمطي",
"register":"تسجيل حساب جديد",
"registerConfirmBody":"Body for verification mail",
"registerConfirmSubject":"عنوان رسالة التأكيد",
"registerDB":"Register module",
"registerDoneBody":"Body for credentials mail",
"registerDoneSubject":"عنوان البريد الذي تم القيام به",
"registerTimeout":"مدة صلاحية طلب التسجيل",
"registerUrl":"Register page URL",

View File

@ -841,9 +841,11 @@
"regexp":"Regular expression",
"regexps":"Regular expressions",
"register":"Register new account",
"registerConfirmSubject":"Subject for confirmation mail",
"registerConfirmBody":"Body for verification mail",
"registerConfirmSubject":"Subject for verification mail",
"registerDB":"Register module",
"registerDoneSubject":"Subject for done mail",
"registerDoneBody":"Body for credentials mail",
"registerDoneSubject":"Subject for credentials mail",
"registerTimeout":"Validity time of a register request",
"registerUrl":"Register page URL",
"reloadParams":"Configuration reload",

View File

@ -791,17 +791,17 @@
"portalErrorOnMailNotFound":"Show error on mail not found",
"portalForceAuthn":"Force authentication",
"portalForceAuthnInterval":"Force authentication interval",
"portalMainLogo":"Main Logo",
"portalMainLogo":"Main logo",
"portalMenu":"Menu",
"portalModules":"Modules activation",
"portalOpenLinkInNewWindow":"New window",
"portalOther":"Other",
"portalParams":"Portal",
"portalPingInterval":"Ping Interval",
"portalPingInterval":"Ping interval",
"portalRedirection":"Portal redirections",
"portalRequireOldPassword":"Require old password",
"portalServers":"Portal servers",
"portalSkin":"Default Skin",
"portalSkin":"Default skin",
"portalSkinBackground":"Skin background",
"portalSkinRules":"Skin display rules",
"portalStatus":"Publish portal status",
@ -841,9 +841,11 @@
"regexp":"Regular expression",
"regexps":"Regular expressions",
"register":"Register new account",
"registerConfirmSubject":"Subject for confirmation mail",
"registerConfirmBody":"Body for verification mail",
"registerConfirmSubject":"Subject for verification mail",
"registerDB":"Register module",
"registerDoneSubject":"Subject for done mail",
"registerDoneBody":"Body for credentials mail",
"registerDoneSubject":"Subject for credentials mail",
"registerTimeout":"Validity time of a register request",
"registerUrl":"Register page URL",
"reloadParams":"Configuration reload",

View File

@ -841,9 +841,11 @@
"regexp":"Expresión regular",
"regexps":"Expresiones regulares",
"register":"Registrar nueva cuenta",
"registerConfirmSubject":"Subject para el correo de confirmación",
"registerConfirmBody":"Body for verification mail",
"registerConfirmSubject":"Subject for verification mail",
"registerDB":"Register module",
"registerDoneSubject":"Subject para el correo ",
"registerDoneBody":"Body for credentials mail",
"registerDoneSubject":"Subject for credentials mail",
"registerTimeout":"Tiempo de validez para una solicitud de registro",
"registerUrl":"URL de la página de registro",
"reloadParams":"Recargar configuración",

View File

@ -841,9 +841,11 @@
"regexp":"Expression régulière",
"regexps":"Expressions régulières",
"register":"Créer un nouveau compte",
"registerConfirmSubject":"Sujet du mail de confirmation",
"registerConfirmBody":"Contenu du mail de vérification",
"registerConfirmSubject":"Sujet du mail de vérification",
"registerDB":"Module d'auto-enregistrement",
"registerDoneSubject":"Sujet du mail de prise en compte",
"registerDoneBody":"Contenu du mail d'envoi du mot de passe",
"registerDoneSubject":"Sujet du mail d'envoi du mot de passe",
"registerTimeout":"Durée de validité d'une requête de création",
"registerUrl":"URL de la page de création",
"reloadParams":"Mise à jour de la configuration",

View File

@ -841,9 +841,11 @@
"regexp":"Espressione regolare",
"regexps":"Espressioni regolari",
"register":"Registra nuovo account",
"registerConfirmSubject":"Oggetto per la mail di conferma",
"registerConfirmBody":"Body for verification mail",
"registerConfirmSubject":"Subject for verification mail",
"registerDB":"Modulo di autoregistrazione",
"registerDoneSubject":"Oggetto per la mail inviata",
"registerDoneBody":"Body for credentials mail",
"registerDoneSubject":"Subject for credentials mail",
"registerTimeout":"Tempo di validità di una richiesta di registrazione",
"registerUrl":"URL della pagina di registrazione",
"reloadParams":"Ricarica di configurazione",

View File

@ -841,9 +841,11 @@
"regexp":"Wyrażenie regularne",
"regexps":"Wyrażenia regularne",
"register":"Zarejestruj nowe konto",
"registerConfirmSubject":"Temat wiadomości potwierdzającej",
"registerConfirmBody":"Body for verification mail",
"registerConfirmSubject":"Subject for verification mail",
"registerDB":"Moduł rejestracji",
"registerDoneSubject":"Temat dla wiadomości o wykonaniu",
"registerDoneBody":"Body for credentials mail",
"registerDoneSubject":"Subject for credentials mail",
"registerTimeout":"Termin ważności wniosku o rejestrację",
"registerUrl":"Zarejestruj adres URL strony",
"reloadParams":"Załaduj ponownie konfigurację",

View File

@ -841,9 +841,11 @@
"regexp":"Düzenli ifade",
"regexps":"Düzenli ifadeler",
"register":"Yeni hesap kaydet",
"registerConfirmSubject":"Doğrulama e-postası için konu",
"registerConfirmBody":"Body for verification mail",
"registerConfirmSubject":"Subject for verification mail",
"registerDB":"Kayıt modülü",
"registerDoneSubject":"Tamamlanmış e-posta için konu",
"registerDoneBody":"Body for credentials mail",
"registerDoneSubject":"Subject for credentials mail",
"registerTimeout":"Kayıt isteğinin geçerlilik süresi",
"registerUrl":"Kayıt sayfası URL'si",
"reloadParams":"Yapılandırma yeniden yüklendi",

View File

@ -841,9 +841,11 @@
"regexp":"Biểu thức chính quy",
"regexps":"Biểu thức thông thường",
"register":"Đăng ký tài khoản mới",
"registerConfirmSubject":"Tiêu đề cho thư xác nhận",
"registerConfirmBody":"Body for verification mail",
"registerConfirmSubject":"Subject for verification mail",
"registerDB":"Register module",
"registerDoneSubject":"Tiêu đề cho thư đã hoàn tất",
"registerDoneBody":"Body for credentials mail",
"registerDoneSubject":"Subject for credentials mail",
"registerTimeout":"Thời hạn hiệu lực của yêu cầu đăng ký",
"registerUrl":"Register page URL",
"reloadParams":"Tải lại cấu hình",

View File

@ -841,9 +841,11 @@
"regexp":"Regular expression",
"regexps":"Regular expressions",
"register":"Register new account",
"registerConfirmSubject":"Subject for confirmation mail",
"registerConfirmBody":"Body for verification mail",
"registerConfirmSubject":"Subject for verification mail",
"registerDB":"Register module",
"registerDoneSubject":"Subject for done mail",
"registerDoneBody":"Body for credentials mail",
"registerDoneSubject":"Subject for credentials mail",
"registerTimeout":"Validity time of a register request",
"registerUrl":"Register page URL",
"reloadParams":"Configuration reload",

View File

@ -841,9 +841,11 @@
"regexp":"正規表示式",
"regexps":"正規表示式",
"register":"註冊新帳號",
"registerConfirmSubject":"確認電子郵件的主旨",
"registerConfirmBody":"Body for verification mail",
"registerConfirmSubject":"Subject for verification mail",
"registerDB":"註冊模組",
"registerDoneSubject":"完成電子郵件的主旨",
"registerDoneBody":"Body for credentials mail",
"registerDoneSubject":"Subject for credentials mail",
"registerTimeout":"註冊請求的有效時間",
"registerUrl":"註冊 URL",
"reloadParams":"設定重新載入",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -631,6 +631,7 @@ t/41-Captcha.t
t/41-Token-with-global-storage.t
t/41-Token.t
t/42-Register-Demo-with-captcha.t
t/42-Register-Demo-with-CustomBody.t
t/42-Register-Demo-with-token.t
t/42-Register-Demo.t
t/42-Register-LDAP.t

View File

@ -4,7 +4,7 @@
"Xavier Guimard <x.guimard@free.fr>, Clément Oudot <clement@oodo.net>"
],
"dynamic_config" : 1,
"generated_by" : "ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010",
"generated_by" : "ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010",
"license" : [
"open_source"
],
@ -67,7 +67,7 @@
},
"requires" : {
"Clone" : "0",
"Lemonldap::NG::Handler" : "v2.0.12",
"Lemonldap::NG::Handler" : "v2.0.13",
"Regexp::Assemble" : "0"
}
}
@ -84,6 +84,6 @@
],
"x_MailingList" : "mailto:lemonldap-ng-dev@ow2.org"
},
"version" : "v2.0.12",
"version" : "v2.0.13",
"x_serialization_backend" : "JSON::PP version 4.04"
}

View File

@ -18,7 +18,7 @@ build_requires:
configure_requires:
ExtUtils::MakeMaker: '0'
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 7.44, CPAN::Meta::Converter version 2.150010'
generated_by: 'ExtUtils::MakeMaker version 7.34, CPAN::Meta::Converter version 2.150010'
license: open_source
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@ -52,7 +52,7 @@ recommends:
Web::ID: '0'
requires:
Clone: '0'
Lemonldap::NG::Handler: v2.0.12
Lemonldap::NG::Handler: v2.0.13
Regexp::Assemble: '0'
resources:
MailingList: mailto:lemonldap-ng-dev@ow2.org
@ -60,5 +60,5 @@ resources:
bugtracker: https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues
homepage: http://lemonldap-ng.org/
license: http://opensource.org/licenses/GPL-2.0
version: v2.0.12
version: v2.0.13
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'

View File

@ -61,7 +61,7 @@ WriteMakefile(
},
PREREQ_PM => {
'Clone' => 0,
'Lemonldap::NG::Handler' => '2.0.12',
'Lemonldap::NG::Handler' => '2.0.13',
'Regexp::Assemble' => 0,
},
(

View File

@ -1,7 +1,7 @@
# Alias for Lemonldap::NG::Portal::Main
package Lemonldap::NG::Portal;
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
use Lemonldap::NG::Portal::Main;
use base 'Lemonldap::NG::Portal::Main';

View File

@ -4,7 +4,7 @@ package Lemonldap::NG::Portal::Main::Constants;
use strict;
use Exporter 'import';
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
use constant HANDLER => 'Lemonldap::NG::Handler::PSGI::Main';
use constant URIRE =>

View File

@ -576,14 +576,14 @@ sub updateSession {
if ($id) {
# Update sessionInfo data
## sessionInfo updated if $id defined : quite strange !!
## sessionInfo updated if $id defined : quite strange!!
## See https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/430
$self->logger->debug("Update session $id");
foreach ( keys %$infos ) {
$self->logger->debug("Update sessionInfo $_");
$self->_dump( $infos->{$_} );
$req->{sessionInfo}->{$_} = $infos->{$_};
if ( $id eq $self->HANDLER->data->{_session_id} ) {
if ( $self->HANDLER->data->{_session_id} && $id eq $self->HANDLER->data->{_session_id} ) {
$self->HANDLER->data->{$_} = $infos->{$_};
}
}

View File

@ -22,7 +22,7 @@ use Lemonldap::NG::Portal::Main::Constants qw(
PE_MAILCONFIRMATION_ALREADY_SENT
);
our $VERSION = '2.0.12';
our $VERSION = '2.0.13';
extends qw(
Lemonldap::NG::Portal::Lib::SMTP
@ -134,7 +134,7 @@ sub _register {
if ( $req->data->{register_token} ) {
$self->logger->debug(
"Token given for register: " . $req->data->{register_token} );
"Token provided for register: " . $req->data->{register_token} );
# Get the corresponding session
if ( my $data =
@ -262,7 +262,7 @@ sub _register {
# Mail session expiration date
my $expTimestamp =
( $self->{conf}->{registerTimeout} || $self->conf->{timeout} ) + time;
( $self->conf->{registerTimeout} || $self->conf->{timeout} ) + time;
$self->logger->debug("Register expiration timestamp: $expTimestamp");
@ -303,24 +303,40 @@ sub _register {
my $tr = $self->translate($req);
my $subject = $self->conf->{registerConfirmSubject};
unless ($subject) {
$self->logger->debug('Use default confirm subject');
$subject = 'registerConfirmSubject';
$tr->( \$subject );
}
my $body;
my $html = 1;
my ( $body, $html );
if ( $self->conf->{registerConfirmBody} ) {
# Use HTML template
$body = $self->loadMailTemplate(
$req,
'mail_register_confirm',
filter => $tr,
params => {
expMailDate => $req->data->{expMailDate},
expMailTime => $req->data->{expMailTime},
url => $url,
%{ $req->data->{registerInfo} || {} },
},
);
# We use a specific text message, no html
$self->logger->debug('Use specific confirm body message');
$body = $self->conf->{registerConfirmBody};
# Replace variables in body
$body =~ s/\$url/$url/g;
$body =~ s/\$expMailDate/$req->{data}->{expMailDate}/g;
$body =~ s/\$expMailTime/$req->{data}->{expMailTime}/g;
$body =~ s/\$(\w+)/$req->{data}->{registerInfo}->{$1} || ''/ge;
}
else {
# Use HTML template
$self->logger->debug('Use default confirm HTML template body');
$body = $self->loadMailTemplate(
$req,
'mail_register_confirm',
filter => $tr,
params => {
expMailDate => $req->data->{expMailDate},
expMailTime => $req->data->{expMailTime},
url => $url,
%{ $req->data->{registerInfo} || {} },
},
);
$html = 1;
}
# Send mail
return PE_MAILERROR
@ -357,16 +373,6 @@ sub _register {
return $result;
}
# Build mail content
my $tr = $self->translate($req);
my $subject = $self->conf->{registerDoneSubject};
unless ($subject) {
$subject = 'registerDoneSubject';
$tr->( \$subject );
}
my $body;
my $html = 1;
# Build portal url
my $url = $self->conf->{portal};
$url =~ s#/*$##;
@ -378,16 +384,40 @@ sub _register {
( $req_url ? ( url => $req_url ) : () ),
);
# Use HTML template
$body = $self->loadMailTemplate(
$req,
'mail_register_done',
filter => $tr,
params => {
url => $url,
%{ $req->data->{registerInfo} || {} },
},
);
# Build mail content
my $tr = $self->translate($req);
my $subject = $self->conf->{registerDoneSubject};
unless ($subject) {
$self->logger->debug('Use default done subject');
$subject = 'registerDoneSubject';
$tr->( \$subject );
}
my ( $body, $html );
if ( $self->conf->{registerDoneBody} ) {
# We use a specific text message, no html
$self->logger->debug('Use specific done body message');
$body = $self->conf->{registerDoneBody};
# Replace variables in body
$body =~ s/\$url/$url/g;
$body =~ s/\$(\w+)/$req->{data}->{registerInfo}->{$1} || ''/ge;
}
else {
# Use HTML template
$self->logger->debug('Use default done HTML template body');
$body = $self->loadMailTemplate(
$req,
'mail_register_done',
filter => $tr,
params => {
url => $url,
%{ $req->data->{registerInfo} || {} },
},
);
$html = 1;
}
# Send mail
return PE_MAILERROR

View File

@ -1 +1 @@
!function(){var o=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){if(console.log("Error",t),(e=JSON.parse(e.responseText))&&e.error)return e=e.error.replace(/.* /,""),console.log("Returned error",e),o(e,"warning")},t="",e=function(){return o("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(),o(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?o("yourNewTotpKey","warning"):o("yourTotpKey","success"),t=e.token):o("PE24","danger")}})},s=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)/)?o(e.error,"warning"):o(e.error,"danger"):o("yourKeyIsRegistered","success")}}):(o("totpMissingCode","warning"),$("#code").focus())};$(document).ready(function(){return e(),$("#verify").on("click",s)})}.call(this);
(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);

View File

@ -1 +1 @@
{"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,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,IAGzCQ,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"}
{"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"}

View File

@ -5,7 +5,7 @@
<!-- //endif -->
<div class="form-group">
<img class="renewcaptchaclick" src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/arrow_refresh.png" alt="Renew Captcha" title="Renew Captcha" class="img-thumbnail mb-3" autocomplete="one-time-code" />
<img class="renewcaptchaclick" src="<TMPL_VAR NAME="STATIC_PREFIX">common/icons/arrow_refresh.png" alt="Renew Captcha" title="Renew Captcha" class="img-thumbnail mb-3" />
<img id="captcha" src="<TMPL_VAR NAME=CAPTCHA_SRC>" class="img-thumbnail" />
</div>
<div class="input-group mb-3">

View File

@ -16,7 +16,7 @@
<div class="input-group-prepend">
<span class="input-group-text"><label for="extcode" class="mb-0"><i class="fa fa-lock"></i></label></span>
</div>
<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />
<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />
</div>
</div>
<div class="buttons">

View File

@ -37,7 +37,7 @@
<div class="input-group-prepend">
<span class="input-group-text"><label for="mailfield" class="mb-0"><i class="fa fa-envelope"></i></label></span>
</div>
<input id="mailfield" name="mail" type="text" value="<TMPL_VAR NAME="MAIL">" class="form-control" trplaceholder="mail" required aria-required="true" />
<input id="mailfield" name="mail" type="text" value="<TMPL_VAR NAME="MAIL">" class="form-control" trplaceholder="mail" required aria-required="true" autocomplete="email" />
</div>
<TMPL_IF NAME=CAPTCHA_SRC>

View File

@ -16,7 +16,7 @@
<div class="input-group-prepend">
<span class="input-group-text"><label for="extcode" class="mb-0"><i class="fa fa-lock"></i></label></span>
</div>
<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />
<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />
</div>
</div>
<div class="buttons mb-3">

View File

@ -50,7 +50,7 @@
<div class="input-group-prepend">
<span class="input-group-text"><label for="extcode" class="mb-0"><i class="fa fa-lock"></i></label></span>
</div>
<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />
<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />
</div>
</div>
<div class="buttons mb-3">

View File

@ -11,7 +11,8 @@ BEGIN {
require 't/saml-lib.pm';
}
my $debug = 'error';
my $debug = 'error';
my $maintests = 132;
my ( $issuer, $sp, $res );
# Redefine LWP methods for tests
@ -19,7 +20,6 @@ LWP::Protocol::PSGI->register(
sub {
my $req = Plack::Request->new(@_);
fail('POST should not launch SOAP requests');
count(1);
return [ 500, [], [] ];
}
);
@ -41,7 +41,6 @@ sub runTest {
),
'Unauth SP request'
);
count(1);
expectOK($res);
my ( $host, $url, $s ) =
@ -64,7 +63,6 @@ sub runTest {
),
'Post SAML request to IdP'
);
count(1);
expectOK($res);
my $pdata = 'lemonldappdata=' . expectCookie( $res, 'lemonldappdata' );
@ -80,20 +78,18 @@ sub runTest {
),
'Post authentication'
);
count(1);
my $idpId = expectCookie($res);
# Expect pdata to be cleared
$pdata = expectCookie( $res, 'lemonldappdata' );
ok( $pdata !~ 'issuerRequestsaml', 'SAML request cleared from pdata' )
or explain( $pdata, 'not issuerRequestsaml' );
count(1);
( $host, $url, $s ) =
expectAutoPost( $res, 'auth.sp.com', '/saml/proxySingleSignOnPost',
'SAMLResponse' );
my ($sr) = expectSamlResponse($s);
$sr = expectSamlResponse($s);
expectXPath(
$sr, '/samlp:Response/saml:Assertion/saml:Subject/saml:NameID/@Format',
$expect_res_nif, 'Found expected NameID Format in response',
@ -114,7 +110,7 @@ sub runTest {
SKIP: {
eval "use Lasso";
if ($@) {
skip 'Lasso not found';
skip( 'Lasso not found', $maintests );
}
# Default settings use the email NIF
@ -221,9 +217,9 @@ SKIP: {
);
}
count($maintests);
clean_sessions();
done_testing();
done_testing( count() );
sub issuer {
my ( $res_nif, $force_attr ) = @_;

View File

@ -91,7 +91,7 @@ SKIP: {
),
'Query IdP to access to SP'
);
my ( $host, $url, $query ) =
( $host, $url, $query ) =
expectAutoPost( $res, 'auth.sp.com', '/saml/proxySingleSignOnPost',
'SAMLResponse' );

View File

@ -82,7 +82,7 @@ SKIP: {
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
@ -211,7 +211,7 @@ qr%<input name="code" value="" type="text" class="form-control" id="extcode" trp
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );

View File

@ -94,7 +94,7 @@ SKIP: {
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );

View File

@ -156,7 +156,7 @@ $pdata = expectCookie( $res, 'lemonldappdata' );
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);
@ -261,7 +261,7 @@ $pdata = expectCookie( $res, 'lemonldappdata' );
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -128,7 +128,7 @@ $pdata = expectCookie( $res, 'lemonldappdata' );
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -120,7 +120,7 @@ is( ref( $payload->{email} ),
is( ref( $payload->{nickname} ),
"ARRAY", "Multi valued attribute exposed as array" );
my $query = "token=$access_token";
$query = "token=$access_token";
ok(
$res = $op->_post(
"/oauth2/introspect",

View File

@ -95,7 +95,7 @@ $pdata = expectCookie( $res, 'lemonldappdata' );
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -6,11 +6,10 @@ use LWP::UserAgent;
use LWP::Protocol::PSGI;
use MIME::Base64;
# ------------ ----------------------------- ----------------
# | SAML SP | <-> |SAML IDP + SAML SP (proxy) | <-> | SAML IdP |
# ------------ ----------------------------- ----------------
#
#
# Use case:
# - login from SP up to SAML IdP
# - logout asked from SP, and propagated up to SAML IdP
@ -30,7 +29,8 @@ my ( $sp, $proxy, $idp, $res );
LWP::Protocol::PSGI->register(
sub {
my $req = Plack::Request->new(@_);
ok( $req->uri =~ m#http://auth.((?:sp|proxy|idp)).com(.*)#, ' REST request' );
ok( $req->uri =~ m#http://auth.((?:sp|proxy|idp)).com(.*)#,
' REST request' );
my $host = $1;
my $url = $2;
my ( $res, $client );
@ -74,16 +74,18 @@ LWP::Protocol::PSGI->register(
);
}
ok( $res->[0] == 200, ' Response is 200' );
ok( getHeader( $res, 'Content-Type' ) =~ m#^(application/json|text/xml)#,
' Content is JSON|XML' )
or explain( $res->[1], 'Content-Type => (application/json|text/xml)' );
ok(
getHeader( $res, 'Content-Type' ) =~
m#^(application/json|text/xml)#,
' Content is JSON|XML'
)
or
explain( $res->[1], 'Content-Type => (application/json|text/xml)' );
count(4);
return $res;
}
);
SKIP: {
eval "use Lasso";
if ($@) {
@ -91,11 +93,10 @@ SKIP: {
}
# Initialization
$idp = register( 'idp', \&idp );
$sp = register( 'sp', \&sp );
$idp = register( 'idp', \&idp );
$sp = register( 'sp', \&sp );
$proxy = register( 'proxy', \&proxy );
# LOGIN PROCESS ############################################################
# Query SP for auth
@ -120,14 +121,16 @@ SKIP: {
# Try to authenticate to IdP
ok(
$res = $idp->_get( $urlidp, query => $queryidp, accept => 'text/html'),
"SAML Authentication on idp, endpoint $urlidp" );
$res = $idp->_get( $urlidp, query => $queryidp, accept => 'text/html' ),
"SAML Authentication on idp, endpoint $urlidp"
);
my $pdataidp = expectCookie( $res, 'lemonldappdata' );
my ( $host, $tmp );
# expectForm (result, host, uri, @requiredfield)
( $host, $tmp, $query ) = expectForm( $res, '#', undef,
( 'url', 'timezone', 'skin', 'user', 'password' ) );
( 'url', 'timezone', 'skin', 'user', 'password' ) );
$query =~ s/user=/user=dwho/;
$query =~ s/password=/password=dwho/;
@ -166,18 +169,23 @@ SKIP: {
$pdataproxy = expectCookie( $res, 'lemonldappdata' );
my $cookieproxy = expectCookie( $res, 'lemonldap' );
( $url, $query ) = expectRedirection( $res, qr#^http://auth.proxy.com(/saml)\?*(.*)$# );
( $url, $query ) =
expectRedirection( $res, qr#^http://auth.proxy.com(/saml)\?*(.*)$# );
ok(
$res = $proxy->_get( $url,
query => $query,
accept => 'text/html',
cookie => "lemonldappdata=$pdataproxy; lemonldap=$cookieproxy" ),
"internal redirection to PROXY, endpoint $url" );
$res = $proxy->_get(
$url,
query => $query,
accept => 'text/html',
cookie => "lemonldappdata=$pdataproxy; lemonldap=$cookieproxy"
),
"internal redirection to PROXY, endpoint $url"
);
( $host, $url, $query ) =
expectForm( $res, 'auth.sp.com', '/saml/proxySingleSignOnPost', 'SAMLResponse' );
expectForm( $res, 'auth.sp.com', '/saml/proxySingleSignOnPost',
'SAMLResponse' );
my ($resp) = $query =~ qr/SAMLResponse=([^&]*)/;
($resp) = $query =~ qr/SAMLResponse=([^&]*)/;
# Post SAML response to PROXY
switch ('sp');
@ -192,48 +200,58 @@ SKIP: {
my $cookiesp = expectCookie( $res, 'lemonldap' );
# Authentication done on SP + PROXY + IDP
# LOGOUT PROCESS ###########################################################
$url = '/';
$url = '/';
$query = 'logout=1';
ok( $res = $sp->_get( $url, query => $query,
accept => 'text/html',
cookie => "lemonldap=$cookiesp",
),
'Call logout from SP' );
ok(
$res = $sp->_get(
$url,
query => $query,
accept => 'text/html',
cookie => "lemonldap=$cookiesp",
),
'Call logout from SP'
);
# lemonldap cookie set to "0"
$cookiesp = expectCookie( $res, 'lemonldap' );
ok( $cookiesp eq "0", 'Test empty cookie on SP' );
ok ( $res->[2]->[0] =~ /trmsg="47"/, 'Test disconnexion message on SP' );
ok( $res->[2]->[0] =~ /trmsg="47"/, 'Test disconnexion message on SP' );
# test connexion on PROXY
switch('proxy');
ok( $res = $proxy->_get( '/', query => '',
accept => 'text/html',
cookie => "lemonldap=$cookieproxy",
),
'Test if still logged on PROXY' );
switch ('proxy');
ok(
$res = $proxy->_get(
'/',
query => '',
accept => 'text/html',
cookie => "lemonldap=$cookieproxy",
),
'Test if still logged on PROXY'
);
my ( $urlidp, $queryidp ) =
( $urlidp, $queryidp ) =
expectRedirection( $res,
qr#http://auth.idp.com(/saml/singleSignOn)\?(.*)$# );
# test connexion on IDP
switch('idp');
ok( $res = $idp->_get( '/', query => '',
accept => 'text/html',
cookie => "lemonldap=$cookieidp",
),
'Test if still logged on IDP' );
switch ('idp');
ok(
$res = $idp->_get(
'/',
query => '',
accept => 'text/html',
cookie => "lemonldap=$cookieidp",
),
'Test if still logged on IDP'
);
like( $res->[2]->[0], qr/userfield/,
'test presence of user field in form (prove successful logout)' );
like( $res->[2]->[0],
qr/userfield/,
'test presence of user field in form (prove successful logout)' );
}
@ -259,80 +277,83 @@ sub proxy {
samlServicePublicKeyEnc => saml_key_proxy_public_enc,
samlServicePublicKeySig => saml_key_proxy_public_sig,
samlIDPSSODescriptorWantAuthnRequestsSigned => 1,
samlSPSSODescriptorWantAssertionsSigned => 1,
samlIDPMetaDataXML => {
samlSPSSODescriptorWantAssertionsSigned => 1,
samlIDPMetaDataXML => {
'idp' => {
samlIDPMetaDataXML =>
samlIDPComplexMetaDataXML( 'idp', 'HTTP-Redirect', 'SOAP' )
samlIDPMetaDataXML => samlIDPComplexMetaDataXML(
'idp', 'HTTP-Redirect', 'SOAP'
)
},
},
samlIDPMetaDataOptions => {
'idp' => {
'samlIDPMetaDataOptionsAdaptSessionUtime' => 0,
'samlIDPMetaDataOptionsAllowLoginFromIDP' => 0,
'samlIDPMetaDataOptionsAllowProxiedAuthn' => 0,
'samlIDPMetaDataOptionsCheckAudience' => 1,
'samlIDPMetaDataOptionsAdaptSessionUtime' => 0,
'samlIDPMetaDataOptionsAllowLoginFromIDP' => 0,
'samlIDPMetaDataOptionsAllowProxiedAuthn' => 0,
'samlIDPMetaDataOptionsCheckAudience' => 1,
'samlIDPMetaDataOptionsCheckSLOMessageSignature' => 1,
'samlIDPMetaDataOptionsCheckSSOMessageSignature' => 1,
'samlIDPMetaDataOptionsCheckTime' => 1,
'samlIDPMetaDataOptionsDisplayName' => 'idp',
'samlIDPMetaDataOptionsEncryptionMode' => 'none',
'samlIDPMetaDataOptionsForceAuthn' => 0,
'samlIDPMetaDataOptionsForceUTF8' => 0,
'samlIDPMetaDataOptionsIcon' => '',
'samlIDPMetaDataOptionsIsPassive' => 0,
'samlIDPMetaDataOptionsNameIDFormat' => '',
'samlIDPMetaDataOptionsRelayStateURL' => 0,
'samlIDPMetaDataOptionsCheckTime' => 1,
'samlIDPMetaDataOptionsDisplayName' => 'idp',
'samlIDPMetaDataOptionsEncryptionMode' => 'none',
'samlIDPMetaDataOptionsForceAuthn' => 0,
'samlIDPMetaDataOptionsForceUTF8' => 0,
'samlIDPMetaDataOptionsIcon' => '',
'samlIDPMetaDataOptionsIsPassive' => 0,
'samlIDPMetaDataOptionsNameIDFormat' => '',
'samlIDPMetaDataOptionsRelayStateURL' => 0,
'samlIDPMetaDataOptionsRequestedAuthnContext' => '',
'samlIDPMetaDataOptionsResolutionRule' => '',
'samlIDPMetaDataOptionsResolutionRule' => '',
'samlIDPMetaDataOptionsSLOBinding' => 'http-soap',
'samlIDPMetaDataOptionsSSOBinding' => 'http-redirect',
'samlIDPMetaDataOptionsSignSLOMessage' => 1,
'samlIDPMetaDataOptionsSignSSOMessage' => 1,
'samlIDPMetaDataOptionsSignSLOMessage' => 1,
'samlIDPMetaDataOptionsSignSSOMessage' => 1,
'samlIDPMetaDataOptionsSignatureMethod' => '',
'samlIDPMetaDataOptionsStoreSAMLToken' => 0
'samlIDPMetaDataOptionsStoreSAMLToken' => 0
}
},
samlIDPMetaDataExportedAttributes => {
'idp' => {
'cn' => '1;cn',
'uid' => '1;uid',
'mail' => '1;mail',
}
'idp' => {
'cn' => '1;cn',
'uid' => '1;uid',
'mail' => '1;mail',
}
},
issuerDBSAMLActivation => 1,
restSessionServer => 1,
samlSPMetaDataOptions => {
issuerDBSAMLActivation => 1,
restSessionServer => 1,
samlSPMetaDataOptions => {
sp => {
'samlSPMetaDataOptionsCheckSLOMessageSignature' => 1,
'samlSPMetaDataOptionsCheckSSOMessageSignature' => 1,
'samlSPMetaDataOptionsEnableIDPInitiatedURL' => 0,
'samlSPMetaDataOptionsEncryptionMode' => 'none',
'samlSPMetaDataOptionsForceUTF8' => 1,
'samlSPMetaDataOptionsNameIDFormat' => '',
'samlSPMetaDataOptionsEnableIDPInitiatedURL' => 0,
'samlSPMetaDataOptionsEncryptionMode' => 'none',
'samlSPMetaDataOptionsForceUTF8' => 1,
'samlSPMetaDataOptionsNameIDFormat' => '',
'samlSPMetaDataOptionsNotOnOrAfterTimeout' => 72000,
'samlSPMetaDataOptionsOneTimeUse' => 0,
'samlSPMetaDataOptionsSessionNotOnOrAfterTimeout' => 72000,
'samlSPMetaDataOptionsSignSLOMessage' => -1,
'samlSPMetaDataOptionsSignSSOMessage' => 1,
'samlSPMetaDataOptionsOneTimeUse' => 0,
'samlSPMetaDataOptionsSessionNotOnOrAfterTimeout' =>
72000,
'samlSPMetaDataOptionsSignSLOMessage' => -1,
'samlSPMetaDataOptionsSignSSOMessage' => 1,
'samlSPMetaDataOptionsSignatureMethod' => ''
}
},
samlSPMetaDataXML => {
sp => {
samlSPMetaDataXML =>
samlSPComplexMetaDataXML( 'sp', 'HTTP-Redirect', 'SOAP' ),
'samlSPSSODescriptorAuthnRequestsSigned' => 1,
samlSPMetaDataXML => samlSPComplexMetaDataXML(
'sp', 'HTTP-Redirect', 'SOAP'
),
'samlSPSSODescriptorAuthnRequestsSigned' => 1,
'samlSPSSODescriptorWantAssertionsSigned' => 1,
}
},
samlSPMetaDataExportedAttributes => {
'sp' => {
'cn' => '1;cn',
'uid' => '1;uid',
'mail' => '1;mail',
}
'sp' => {
'cn' => '1;cn',
'uid' => '1;uid',
'mail' => '1;mail',
}
},
samlSPSSODescriptorAuthnRequestsSigned => 1,
},
@ -349,54 +370,55 @@ sub sp {
authentication => 'SAML',
userDB => 'Same',
issuerDBOpenIDConnectActivation => "1",
samlOrganizationDisplayName => "SP",
samlOrganizationName => "SP",
samlOrganizationURL => "http://www.sp.com/",
samlServicePrivateKeyEnc => saml_key_sp_private_enc,
samlServicePrivateKeySig => saml_key_sp_private_sig,
samlServicePublicKeyEnc => saml_key_sp_public_enc,
samlServicePublicKeySig => saml_key_sp_public_sig,
samlOrganizationDisplayName => "SP",
samlOrganizationName => "SP",
samlOrganizationURL => "http://www.sp.com/",
samlServicePrivateKeyEnc => saml_key_sp_private_enc,
samlServicePrivateKeySig => saml_key_sp_private_sig,
samlServicePublicKeyEnc => saml_key_sp_public_enc,
samlServicePublicKeySig => saml_key_sp_public_sig,
samlIDPSSODescriptorWantAuthnRequestsSigned => 1,
samlSPSSODescriptorWantAssertionsSigned => 1,
samlIDPMetaDataXML => {
samlSPSSODescriptorWantAssertionsSigned => 1,
samlIDPMetaDataXML => {
'proxy' => {
samlIDPMetaDataXML =>
samlProxyComplexMetaDataXML( 'proxy', 'HTTP-Redirect', 'SOAP' )
samlIDPMetaDataXML => samlProxyComplexMetaDataXML(
'proxy', 'HTTP-Redirect', 'SOAP'
)
},
},
samlIDPMetaDataOptions => {
'proxy' => {
'samlIDPMetaDataOptionsAdaptSessionUtime' => 0,
'samlIDPMetaDataOptionsAllowLoginFromIDP' => 0,
'samlIDPMetaDataOptionsAllowProxiedAuthn' => 0,
'samlIDPMetaDataOptionsCheckAudience' => 1,
'samlIDPMetaDataOptionsAdaptSessionUtime' => 0,
'samlIDPMetaDataOptionsAllowLoginFromIDP' => 0,
'samlIDPMetaDataOptionsAllowProxiedAuthn' => 0,
'samlIDPMetaDataOptionsCheckAudience' => 1,
'samlIDPMetaDataOptionsCheckSLOMessageSignature' => 1,
'samlIDPMetaDataOptionsCheckSSOMessageSignature' => 1,
'samlIDPMetaDataOptionsCheckTime' => 1,
'samlIDPMetaDataOptionsDisplayName' => 'proxy',
'samlIDPMetaDataOptionsCheckTime' => 1,
'samlIDPMetaDataOptionsDisplayName' => 'proxy',
'samlIDPMetaDataOptionsEncryptionMode' => 'none',
'samlIDPMetaDataOptionsForceAuthn' => 0,
'samlIDPMetaDataOptionsForceUTF8' => 0,
'samlIDPMetaDataOptionsIcon' => '',
'samlIDPMetaDataOptionsIsPassive' => 0,
'samlIDPMetaDataOptionsNameIDFormat' => '',
'samlIDPMetaDataOptionsRelayStateURL' => 0,
'samlIDPMetaDataOptionsForceAuthn' => 0,
'samlIDPMetaDataOptionsForceUTF8' => 0,
'samlIDPMetaDataOptionsIcon' => '',
'samlIDPMetaDataOptionsIsPassive' => 0,
'samlIDPMetaDataOptionsNameIDFormat' => '',
'samlIDPMetaDataOptionsRelayStateURL' => 0,
'samlIDPMetaDataOptionsRequestedAuthnContext' => '',
'samlIDPMetaDataOptionsResolutionRule' => '',
'samlIDPMetaDataOptionsResolutionRule' => '',
'samlIDPMetaDataOptionsSLOBinding' => 'http-soap',
'samlIDPMetaDataOptionsSSOBinding' => 'http-redirect',
'samlIDPMetaDataOptionsSignSLOMessage' => 1,
'samlIDPMetaDataOptionsSignSSOMessage' => 1,
'samlIDPMetaDataOptionsSignSLOMessage' => 1,
'samlIDPMetaDataOptionsSignSSOMessage' => 1,
'samlIDPMetaDataOptionsSignatureMethod' => '',
'samlIDPMetaDataOptionsStoreSAMLToken' => 0
'samlIDPMetaDataOptionsStoreSAMLToken' => 0
}
},
samlIDPMetaDataExportedAttributes => {
'proxy' => {
'cn' => '1;cn',
'uid' => '1;uid',
'mail' => '1;mail',
}
'proxy' => {
'cn' => '1;cn',
'uid' => '1;uid',
'mail' => '1;mail',
}
},
}
}
@ -406,43 +428,45 @@ sub sp {
sub idp {
return LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',
userDB => 'Same',
issuerDBSAMLActivation => 1,
restSessionServer => 1,
samlSPMetaDataOptions => {
logLevel => $debug,
domain => 'idp.com',
portal => 'http://auth.idp.com',
authentication => 'Demo',
userDB => 'Same',
issuerDBSAMLActivation => 1,
restSessionServer => 1,
samlSPMetaDataOptions => {
proxy => {
'samlSPMetaDataOptionsCheckSLOMessageSignature' => 1,
'samlSPMetaDataOptionsCheckSSOMessageSignature' => 1,
'samlSPMetaDataOptionsEnableIDPInitiatedURL' => 0,
'samlSPMetaDataOptionsEncryptionMode' => 'none',
'samlSPMetaDataOptionsForceUTF8' => 1,
'samlSPMetaDataOptionsNameIDFormat' => '',
'samlSPMetaDataOptionsEnableIDPInitiatedURL' => 0,
'samlSPMetaDataOptionsEncryptionMode' => 'none',
'samlSPMetaDataOptionsForceUTF8' => 1,
'samlSPMetaDataOptionsNameIDFormat' => '',
'samlSPMetaDataOptionsNotOnOrAfterTimeout' => 72000,
'samlSPMetaDataOptionsOneTimeUse' => 0,
'samlSPMetaDataOptionsSessionNotOnOrAfterTimeout' => 72000,
'samlSPMetaDataOptionsSignSLOMessage' => -1,
'samlSPMetaDataOptionsSignSSOMessage' => 1,
'samlSPMetaDataOptionsOneTimeUse' => 0,
'samlSPMetaDataOptionsSessionNotOnOrAfterTimeout' =>
72000,
'samlSPMetaDataOptionsSignSLOMessage' => -1,
'samlSPMetaDataOptionsSignSSOMessage' => 1,
'samlSPMetaDataOptionsSignatureMethod' => ''
}
},
samlSPMetaDataXML => {
proxy => {
samlSPMetaDataXML =>
samlProxyComplexMetaDataXML( 'proxy', 'HTTP-Redirect', 'SOAP' ),
'samlSPSSODescriptorAuthnRequestsSigned' => 1,
samlSPMetaDataXML => samlProxyComplexMetaDataXML(
'proxy', 'HTTP-Redirect', 'SOAP'
),
'samlSPSSODescriptorAuthnRequestsSigned' => 1,
'samlSPSSODescriptorWantAssertionsSigned' => 1,
}
},
samlSPMetaDataExportedAttributes => {
'proxy' => {
'cn' => '1;cn',
'uid' => '1;uid',
'mail' => '1;mail',
}
'proxy' => {
'cn' => '1;cn',
'uid' => '1;uid',
'mail' => '1;mail',
}
},
samlOrganizationDisplayName => "IDP",
samlOrganizationName => "IDP",

View File

@ -134,7 +134,7 @@ m%<input[^>]*name="password"%,
' New captcha image inserted' );
ok(
$res->[2]->[0] =~
m#<img class="renewcaptchaclick" src="/static/common/icons/arrow_refresh.png" alt="Renew Captcha" title="Renew Captcha" class="img-thumbnail mb-3" autocomplete="one-time-code" />#,
m#<img class="renewcaptchaclick" src="/static/common/icons/arrow_refresh.png" alt="Renew Captcha" title="Renew Captcha" class="img-thumbnail mb-3" />#,
' Renew Captcha button found'
) or explain( $res->[2]->[0], 'Renew captcha button not found' );
ok( $res->[2]->[0] =~ /captcha\.(?:min\.)?js/, 'Get captcha javascript' );

View File

@ -0,0 +1,130 @@
use Test::More;
use strict;
use IO::String;
BEGIN {
eval {
require 't/test-lib.pm';
require 't/smtp.pm';
};
}
my $maintests = 16;
my ( $res, $user, $pwd, $mail, $subject, $email, $ipAddr );
SKIP: {
eval 'require Email::Sender::Simple; use Text::Unidecode';
if ($@) {
skip 'Missing dependencies', $maintests;
}
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
useSafeJail => 1,
portalDisplayRegister => 1,
authentication => 'Demo',
userDB => 'Same',
registerDB => 'Demo',
registerTimeout => '600',
registerConfirmSubject => 'Registration demonstration',
registerConfirmBody =>
'Hello $firstname $lastname, follows this link to register your account $url
Expired time: $expMailDate $expMailTime',
registerDoneSubject => 'Registration successful',
registerDoneBody =>
'Congratulations! Your account has been succesfully created with $mail from [$ipAddr]...
Login=$login & Password=$password - Thanks to LemonLDAP::NG team.
Go to Portal $url',
captcha_register_enabled => 0,
}
}
);
# Test normal first access
# ------------------------
ok(
$res = $client->_get( '/register', accept => 'text/html' ),
'Unauth request',
);
my ( $host, $url, $query ) =
expectForm( $res, '#', undef, 'firstname', 'lastname', 'mail' );
ok(
$res = $client->_post(
'/register',
IO::String->new(
'firstname=Fôo&lastname=Bà Bar&mail=foobar%40badwolf.org'),
length => 53,
accept => 'text/html'
),
'Ask to create account'
);
expectOK($res);
$subject = subject();
$mail = mail();
ok(
$subject eq 'Registration demonstration',
'Found custom registration subject'
) or explain( $subject, 'Custom registration subject' );
ok(
$mail =~
m#Hello Fôo Bà Bar, follows this link to register your account http://auth\.example\.com/register#s,
'Found custom body'
) or explain( $mail, 'Custom body (link)' );
ok( $mail =~ /[?&](register_token=\w+)/s, 'Found register_token' );
$query = $1;
ok( $mail =~ /Fôo/, 'UTF-8 works' ) or explain( $mail, 'Fôo' );
ok( $mail =~ m#Expired time: \d{2}/\d{2}/\d{4} \d{2}:\d{2}#s, 'Found time' )
or explain( $mail, 'Custom body (expired time)' );
ok(
$res =
$client->_get( '/register', query => $query, accept => 'text/html' ),
'Push register_token'
);
expectOK($res);
$subject = subject();
$mail = mail();
ok( $subject eq 'Registration successful', 'Found custom done subject' )
or explain( $subject, 'Custom done subject' );
ok(
$mail =~
m#Congratulations! Your account has been succesfully created with (.+?) from \[(.+?)\]...#s,
'Found email and ipAddr'
) or explain( $mail, 'Custom done body' );
$email = $1;
$ipAddr = $2;
ok( $email eq 'foobar@badwolf', 'Get good email' )
or explain( $email, 'email' );
ok( $ipAddr eq '127.0.0.1', 'Get good ipAddr' )
or explain( $ipAddr, 'ipAddr' );
ok(
$mail =~
m#Login=(\w+?) & Password=(.+?)- Thanks to LemonLDAP::NG team\.#s,
'Found user and password'
) or explain( $mail, 'Custom done body ($login & $password)' );
$user = $1;
$pwd = $2;
ok( $user eq 'fbabar', 'Get good login' );
ok( $mail =~ m#Go to Portal http://auth.example.com/\?skin=bootstrap#s,
'Custom done body (Portal $url)' )
or explain( $mail, 'Custom done body' );
ok(
$res = $client->_post(
'/', IO::String->new("user=fbabar&password=fbabar"),
length => 27,
accept => 'text/html'
),
'Try to authenticate'
);
expectCookie($res);
}
count($maintests);
clean_sessions();
done_testing( count() );

View File

@ -9,8 +9,8 @@ BEGIN {
};
}
my $maintests = 9;
my ( $res, $user, $pwd );
my $maintests = 11;
my ( $res, $user, $pwd, $mail, $subject );
SKIP: {
eval 'require Email::Sender::Simple; use Text::Unidecode';
@ -26,6 +26,7 @@ SKIP: {
authentication => 'Demo',
userDB => 'Same',
registerDB => 'Demo',
registerConfirmSubject => 'Demonstration',
captcha_register_enabled => 0,
}
}
@ -52,9 +53,12 @@ SKIP: {
);
expectOK($res);
my $mail = mail();
ok( $mail =~ m#a href="http://auth.example.com/register\?(.*?)"#,
'Found register token' );
$mail = mail();
$subject = subject();
ok( $subject eq 'Demonstration', 'Found subject' )
or explain( $subject, 'Custom subject' );
ok( $mail =~ m#a href="http://auth.example.com/register\?(.+?)"#,
'Found register token' ) or explain( $mail, 'Confirm body' );
$query = $1;
ok( $query =~ /register_token=/, 'Found register_token' );
ok( $mail =~ /Fôo/, 'UTF-8 works' ) or explain( $mail, 'Fôo' );
@ -66,11 +70,15 @@ SKIP: {
);
expectOK($res);
$mail = mail();
$subject = subject();
ok( $subject eq '[LemonLDAP::NG] Your new account', 'Found subject' )
or explain( $subject, 'Default subject' );
ok(
mail() =~
$mail =~
m#Your login is.+?<b>(\w+)</b>.*?Your password is.+?<b>(.*?)</b>#s,
'Found user and password'
);
) or explain( $mail, 'Done body' );
$user = $1;
$pwd = $2;
ok( $user eq 'fbabar', 'Get good login' );
@ -89,5 +97,4 @@ count($maintests);
clean_sessions();
done_testing( count() );
done_testing( count() );

View File

@ -383,7 +383,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
'Code' );
ok( $code =~ /^\d{6}$/, 'Code contains 6 digits' );
my $s = "code=$code&token=$token&TOTPName=myTOTP";
$s = "code=$code&token=$token&TOTPName=myTOTP";
my $epoch = time();
ok(
$res = $client->_post(
@ -411,7 +411,6 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
ok( $res->[2]->[0] =~ /<span id="msg" trspan="choose2f">/,
'Found choose 2F' )
or print STDERR Dumper( $res->[2]->[0] );
my $devices;
ok(
$devices = $res->[2]->[0] =~ s%<span device=\'TOTP\' epoch=\'\d{10}\'%%g,
'2F device found'

View File

@ -121,7 +121,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );

View File

@ -40,7 +40,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -42,7 +42,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -82,7 +82,7 @@ ok(
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );

View File

@ -61,7 +61,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);
@ -144,7 +144,7 @@ count(1);
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -42,7 +42,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -39,7 +39,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -38,7 +38,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -143,7 +143,7 @@ $pdata = expectCookie( $res, 'lemonldappdata' );
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -114,7 +114,7 @@ $pdata = expectCookie( $res, 'lemonldappdata' );
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -138,7 +138,7 @@ $pdata = expectCookie( $res, 'lemonldappdata' );
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -65,7 +65,7 @@ my ( $host, $url, $query ) =
ok(
$res->[2]->[0] =~
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="off" />%,
qr%<input name="code" value="" type="text" class="form-control" id="extcode" trplaceholder="code" autocomplete="one-time-code" />%,
'Found EXTCODE input'
) or print STDERR Dumper( $res->[2]->[0] );
count(1);

View File

@ -1,7 +1,6 @@
package main;
my $mail;
my $mail_envelope;
my ($mail, $mail_envelope, $mail_subject);
sub mail {
return $mail;
@ -11,6 +10,11 @@ sub envelope {
return $mail_envelope;
}
sub subject {
my $subject = ($mail_subject =~ /=\?utf-8\?B\?(.+?)\?=/)[0];
return decode_base64($subject);
}
package Email::Sender::Transport::LLNG::Test;
use Mouse;
@ -22,6 +26,7 @@ extends 'Email::Sender::Transport';
sub send_email {
my ( $self, $email, $envelope ) = @_;
$mail = $email->get_body;
$mail_subject = $email->get_header("Subject");
$mail_envelope = $envelope;
return $self->success;
}

View File

@ -34,7 +34,7 @@
# Main package
#==============================================================================
Name: lemonldap-ng
Version: 2.0.12
Version: 2.0.13
Release: %{?pre_release:0.}1%{?pre_release:.%{pre_release}}%{?dist}
Summary: LemonLDAP-NG WebSSO
License: GPLv2+
@ -747,6 +747,9 @@ fi
# Changelog
#==============================================================================
%changelog
* Fri Aug 20 2021 Clement Oudot <clem.oudot@gmail.com> - 2.0.13-1
- Update to 2.0.13
* Thu Jul 22 2021 Clement Oudot <clem.oudot@gmail.com> - 2.0.12-1
- Update to 2.0.12

View File

@ -12,7 +12,7 @@
use LWP::UserAgent;
use JSON;
my $milestone = '2.0.12';
my $milestone = '2.0.13';
my @cat = ( 'Bug', 'New feature', 'Improvement', 'Template', 'WebServer Conf' );
open F, "$ENV{HOME}/.ow2-token" or die "Unable to get OW2 token ($!)";