Merge branch 'v2.0'
This commit is contained in:
commit
937bdd4e8b
|
@ -257,6 +257,16 @@ To set a parameter, for example domain:
|
|||
|
||||
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli set domain example.org
|
||||
|
||||
To delete a parameter, for example portalSkinBackground:
|
||||
|
||||
::
|
||||
|
||||
/usr/share/lemonldap-ng/bin/lemonldap-ng-cli del portalSkinBackground
|
||||
|
||||
.. tip::
|
||||
|
||||
Use addKey and delKey actions to manage values of hash configuration parameters
|
||||
|
||||
You can use accessors (options) to change the behavior:
|
||||
|
||||
- -sep: separator of hierarchical values (by default: /).
|
||||
|
|
|
@ -168,7 +168,7 @@ Execute an unit test :
|
|||
# and execute the unit test:
|
||||
prove -v t/67-CheckUser.t
|
||||
|
||||
Launch tests with LDAP backend, for example with OpenLDAP LTB package:
|
||||
Launch tests with LDAP backend, for example with OpenLDAP LTB package (https://ltb-project.org/documentation):
|
||||
|
||||
::
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ backups and a rollback plan ready!
|
|||
-----
|
||||
|
||||
- | Bad default value to display OIDC Consents tab has been fixed.
|
||||
| The default value is ``$_oidcConsents``
|
||||
| The default value is ``$_oidcConsents && $_oidcConsents =~ /\w+/``
|
||||
- Some user log messages have been modified, check :doc:`logs documentation <logs>`
|
||||
(see also `#2244 <https://gitlab.ow2.org/lemonldap-ng/lemonldap-ng/issues/2244>`__)
|
||||
- SAML SOAP calls are now using ``text/xml`` instead of ``application/xml`` as the MIME Content Type, as required by `the SOAP standard <https://www.w3.org/TR/2000/NOTE-SOAP-20000508/#_Toc478383526>`__
|
||||
|
@ -36,6 +36,8 @@ backups and a rollback plan ready!
|
|||
- This release fixes several issues when using ``SameSite=None``. The new
|
||||
default value of the SameSite configuration parameter will set SameSite to
|
||||
``Lax`` unless you are using SAML, which requires ``None``
|
||||
- Incremental lock times values can now be set by using Manager.
|
||||
It must a list of comma separated values. Default values are ``5, 15, 60, 300, 600``
|
||||
|
||||
2.0.8
|
||||
-----
|
||||
|
|
|
@ -22,7 +22,7 @@ for ( my $i = 0 ; $i < @ARGV ; $i++ ) {
|
|||
|
||||
$action ||= "help";
|
||||
|
||||
if ( $action =~ /^(?:[gs]et|(?:add|del)Key|save|restore|rollback)$/ ) {
|
||||
if ( $action =~ /^(?:[gs]et|del|(?:add|del)Key|save|restore|rollback)$/ ) {
|
||||
eval { require Lemonldap::NG::Manager::Cli; };
|
||||
die "Manager libraries not available, aborting ($@)" if ($@);
|
||||
Lemonldap::NG::Manager::Cli->run(@ARGV);
|
||||
|
@ -45,6 +45,7 @@ Available actions:
|
|||
- update-cache : force configuration cache to be updated
|
||||
- get <keys> : get values of parameters
|
||||
- set <key> <value> : set parameter(s) value(s)
|
||||
- del <keys> : delete parameters
|
||||
- addKey <key> <subkey> <value> : add or set a subkey in a parameter
|
||||
- delKey <key> <subkey> : delete subkey of a parameter
|
||||
- save : export configuration to STDOUT
|
||||
|
@ -58,6 +59,8 @@ Options:
|
|||
- safe <0|1> : fail in case the requested configuration is invalid
|
||||
- force <0|1> : allow overwrite of existing config number
|
||||
- cfgNum <num> : set new configuration number (requires -force 1)
|
||||
- sep <char> : separator of hierarchical values (by default: /)
|
||||
- iniFile <file> : path to an alternate lemonldap-ng.ini file
|
||||
|
||||
See Lemonldap::NG::Manager::Cli(3) for more
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@ use strict;
|
|||
use Crypt::URandom;
|
||||
use Mouse;
|
||||
use Data::Dumper;
|
||||
use JSON;
|
||||
use Lemonldap::NG::Common::Conf::ReConstants;
|
||||
|
||||
our $VERSION = '2.1.0';
|
||||
|
@ -83,6 +84,43 @@ sub set {
|
|||
return $self->_save($new);
|
||||
}
|
||||
|
||||
sub del {
|
||||
my ( $self, @keys ) = @_;
|
||||
die 'del requires at least one key' unless (@keys);
|
||||
my $oldValues = {};
|
||||
foreach my $key (@keys) {
|
||||
my $value = $self->_getKey($key);
|
||||
if ( ref $value eq 'HASH' ) {
|
||||
print STDERR "$key seems to be a hash, delete refused\n";
|
||||
next;
|
||||
}
|
||||
unless ( defined $value ) {
|
||||
print STDERR "$key does not exists, skip it\n";
|
||||
next;
|
||||
}
|
||||
$oldValues->{$key} = $value;
|
||||
}
|
||||
return unless keys %$oldValues;
|
||||
unless ( $self->yes ) {
|
||||
print "Proposed changes:\n";
|
||||
printf "%-25s | %-25s\n", 'Key', 'Old value';
|
||||
foreach ( keys %$oldValues ) {
|
||||
printf "%-25s | %-25s\n", $_, $oldValues->{$_};
|
||||
}
|
||||
print "Confirm (N/y)? ";
|
||||
my $c = <STDIN>;
|
||||
unless ( $c =~ /^y(?:es)?$/ ) {
|
||||
die "Aborting";
|
||||
}
|
||||
}
|
||||
require Clone;
|
||||
my $new = Clone::clone( $self->mgr->hLoadedPlugins->{conf}->currentConf );
|
||||
foreach ( keys %$oldValues ) {
|
||||
delete $new->{$_};
|
||||
}
|
||||
return $self->_save($new);
|
||||
}
|
||||
|
||||
sub addKey {
|
||||
my $self = shift;
|
||||
unless ( @_ % 3 == 0 ) {
|
||||
|
@ -348,10 +386,22 @@ sub _save {
|
|||
printf STDERR "Modifications rejected: %s:\n", $parser->{message}
|
||||
if $parser->{message};
|
||||
}
|
||||
|
||||
# Open "en" lang file to get default messages
|
||||
my $langFile = $self->mgr->templateDir . "/languages/en.json";
|
||||
$langFile =~ s/templates/static/;
|
||||
my $langMessages;
|
||||
if ( open my $json, "<", $langFile ) {
|
||||
local $/ = undef;
|
||||
$langMessages = JSON::from_json(<$json>);
|
||||
}
|
||||
|
||||
# Display result
|
||||
foreach (qw(errors warnings status)) {
|
||||
if ( $parser->{$_} and @{ $parser->{$_} } ) {
|
||||
my $s = Dumper( $parser->{$_} );
|
||||
$s =~ s/\$VAR1\s*=\s*//;
|
||||
$s =~ s/__(\w+)__/$langMessages->{$1}/ if ( defined $langMessages );
|
||||
printf STDERR "%-8s: %s", ucfirst($_), $s;
|
||||
}
|
||||
}
|
||||
|
@ -383,8 +433,11 @@ sub run {
|
|||
}
|
||||
$self->cfgNum( $self->lastCfg ) unless ( $self->cfgNum );
|
||||
my $action = shift;
|
||||
unless ( $action =~ /^(?:get|set|addKey|delKey|save|restore|rollback)$/ ) {
|
||||
die "Unknown action $action. Only get, set, addKey or delKey allowed";
|
||||
unless (
|
||||
$action =~ /^(?:get|set|del|addKey|delKey|save|restore|rollback)$/ )
|
||||
{
|
||||
die
|
||||
"Unknown action $action. Only get, set, del, addKey, delKey, save, restore, rollback allowed";
|
||||
}
|
||||
|
||||
$self->$action(@_);
|
||||
|
|
|
@ -226,7 +226,7 @@ sub tests {
|
|||
eval { tied(%h)->delete; };
|
||||
return ( -1, "Unable to delete session ($@)" ) if ($@);
|
||||
return ( -1,
|
||||
'All sessions may be lost and you must restart all your Apache servers'
|
||||
'All sessions may be lost and you must restart all your web servers'
|
||||
) if ( $gc and $conf->{globalStorage} ne $gc );
|
||||
return 1;
|
||||
},
|
||||
|
|
|
@ -132,7 +132,7 @@
|
|||
<h3 id="mtitle" class="modal-title" trspan="{{elem('message').title}}" />
|
||||
<TMPL_IF NAME="INSTANCE_NAME"><h4><TMPL_VAR NAME="INSTANCE_NAME"></h4></TMPL_IF>
|
||||
</div>
|
||||
<div ng-if="elem('message').message" id="mbody" class="modal-body">
|
||||
<div ng-if="elem('message').items[0] || elem('message').message" id="mbody" class="modal-body">
|
||||
<div class="modal-p">{{translateP(elem('message').message)}}</div>
|
||||
<ul class="main-modal-ul" ng-model="elem('message').items">
|
||||
<li ng-repeat="item in elem('message').items" ng-include="'messageitem.html'"/>
|
||||
|
|
|
@ -40,7 +40,7 @@ has unrestrictedUsersRule => ( is => 'rw', default => sub { 0 } );
|
|||
|
||||
sub init {
|
||||
my ($self) = @_;
|
||||
$self->addAuthRoute( switchcontext => 'run', ['POST'] )
|
||||
$self->addAuthRoute( switchcontext => 'run', ['POST'] )
|
||||
->addAuthRoute( switchcontext => 'display', ['GET'] );
|
||||
|
||||
# Parse ContextSwitching rules
|
||||
|
@ -193,7 +193,7 @@ sub run {
|
|||
$self->userLogger->notice(
|
||||
"ContextSwitching: Update \"$realId\" session with \"$spoofId\" session data"
|
||||
);
|
||||
|
||||
|
||||
$req->mustRedirect(1);
|
||||
return $self->p->do( $req, [ sub { $statut } ] );
|
||||
}
|
||||
|
|
|
@ -2,8 +2,11 @@ package Lemonldap::NG::Portal::Plugins::Impersonation;
|
|||
|
||||
use strict;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Portal::Main::Constants
|
||||
qw( PE_OK PE_BADCREDENTIALS PE_IMPERSONATION_SERVICE_NOT_ALLOWED PE_MALFORMEDUSER );
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_OK PE_BADCREDENTIALS
|
||||
PE_IMPERSONATION_SERVICE_NOT_ALLOWED
|
||||
PE_MALFORMEDUSER
|
||||
);
|
||||
|
||||
our $VERSION = '2.1.0';
|
||||
|
||||
|
@ -77,7 +80,7 @@ sub run {
|
|||
|
||||
return $req->authResult
|
||||
if $req->authResult >
|
||||
PE_OK; # Skip Impersonation if error during Auth process
|
||||
PE_OK; # Skip Impersonation if an error occurs during Auth process
|
||||
|
||||
my $statut = PE_OK;
|
||||
my $unUser = 0;
|
||||
|
@ -86,7 +89,7 @@ sub run {
|
|||
$req->{user} ||= $req->{sessionInfo}->{_impUser}; # If 2FA is enabled
|
||||
my $spoofId = $req->param('spoofId') # Impersonation required
|
||||
|| $req->{sessionInfo}->{_impSpoofId} # If 2FA is enabled
|
||||
|| $req->{user}; # NO Impersonation required
|
||||
|| $req->{user}; # Impersonation not required
|
||||
|
||||
$self->logger->debug("No impersonation required")
|
||||
if ( $spoofId eq $req->{user} );
|
||||
|
|
|
@ -7,7 +7,7 @@ require 't/test-lib.pm';
|
|||
use lib 't/lib';
|
||||
|
||||
my $res;
|
||||
my $maintests = 24;
|
||||
my $maintests = 36;
|
||||
|
||||
SKIP: {
|
||||
skip( 'LLNGTESTLDAP is not set', $maintests ) unless ( $ENV{LLNGTESTLDAP} );
|
||||
|
@ -28,6 +28,13 @@ SKIP: {
|
|||
managerPassword => 'lemonldapng',
|
||||
ldapAllowResetExpiredPassword => 1,
|
||||
ldapPpolicyControl => 1,
|
||||
passwordPolicyMinSize => 4,
|
||||
passwordPolicyMinLower => 1,
|
||||
passwordPolicyMinUpper => 1,
|
||||
passwordPolicyMinDigit => 1,
|
||||
passwordPolicyMinSpeChar => 1,
|
||||
passwordPolicySpecialChar => '@',
|
||||
portalDisplayPasswordPolicy => 1
|
||||
}
|
||||
}
|
||||
);
|
||||
|
@ -67,10 +74,28 @@ SKIP: {
|
|||
my ( $host, $url, $query ) =
|
||||
expectForm( $res, '#', undef, 'user', 'oldpassword', 'newpassword',
|
||||
'confirmpassword' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="passwordPolicyMinSize">%,
|
||||
' passwordPolicyMinSize' )
|
||||
or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinSize' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="passwordPolicyMinLower">%,
|
||||
' passwordPolicyMinLower' )
|
||||
or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinLower' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="passwordPolicyMinUpper">%,
|
||||
' passwordPolicyMinUpper' )
|
||||
or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinUpper' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="passwordPolicyMinDigit">%,
|
||||
' passwordPolicyMinDigit' )
|
||||
or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinDigit' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="passwordPolicyMinSpeChar">%,
|
||||
' passwordPolicyMinSpeChar' )
|
||||
or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinSpeChar' );
|
||||
ok( $res->[2]->[0] =~ m%<span trspan="passwordPolicySpecialChar">%,
|
||||
' passwordPolicySpecialChar' )
|
||||
or print STDERR Dumper( $res->[2]->[0], 'passwordPolicySpecialChar' );
|
||||
ok( $query =~ /user=$user/, "User is $user" )
|
||||
or explain( $query, "user=$user" );
|
||||
$query =~ s/(oldpassword)=/$1=$user/g;
|
||||
$query =~ s/((?:confirm|new)password)=/$1=newp/g;
|
||||
$query =~ s/((?:confirm|new)password)=/$1=Newp1@/g;
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/', IO::String->new($query),
|
||||
|
@ -82,7 +107,7 @@ SKIP: {
|
|||
$match = 'trmsg="' . PE_PASSWORD_OK . '"';
|
||||
ok( $res->[2]->[0] =~ /$match/, 'Password is changed' );
|
||||
|
||||
$postString = "user=$user&password=newp";
|
||||
$postString = "user=$user&password=Newp1@";
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/', IO::String->new($postString),
|
||||
|
@ -163,7 +188,7 @@ SKIP: {
|
|||
);
|
||||
my $id = expectCookie($res);
|
||||
$query =
|
||||
'oldpassword=passwordnottooshort&newpassword=test&confirmpassword=test';
|
||||
'oldpassword=passwordnottooshort&newpassword=Te1@&confirmpassword=Te1@';
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
|
@ -189,7 +214,7 @@ SKIP: {
|
|||
);
|
||||
$id = expectCookie($res);
|
||||
$query =
|
||||
'oldpassword=passwordnottooshort&newpassword=testmore&confirmpassword=testmore';
|
||||
'oldpassword=passwordnottooshort&newpassword=Testmore1@&confirmpassword=Testmore1@';
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
'/',
|
||||
|
|
|
@ -136,7 +136,7 @@ SKIP: {
|
|||
expectOK($res);
|
||||
my $id = expectCookie($res);
|
||||
my @refs = ( $res->[2]->[0] =~
|
||||
/<input type="hidden" name="reference[\dx]+" value="(\w+?)">/gs );
|
||||
m#<input type="hidden" name="reference[\dx]+" value="(\w+?)"/>#gs );
|
||||
ok( @refs == 2, 'Two notification references found' )
|
||||
or print STDERR Dumper( $res->[2]->[0] );
|
||||
ok( $refs[0] eq 'testref2', '1st reference found is "testref2"' )
|
||||
|
|
Loading…
Reference in New Issue