Merge branch 'v2.0' into master

This commit is contained in:
Xavier Guimard 2020-11-13 06:17:45 +01:00
commit 93cb619cd2
92 changed files with 1215 additions and 297 deletions

View File

@ -1,8 +1,7 @@
### Summary ### Summary
Summarize the proposed new feature concisely Summarize the desired feature concisely
### Design proposition ### Design proposition
Detail your proposed implementation (interface design, architecture, impact on Describe here the proposed implementation of this feature (interface design suggestions, general architecture, pseudo-code,…)
current behavior,…)

View File

@ -31,7 +31,10 @@ Restrictions: superficial, skippable
# Use pkg-perl-autopkgtest test for runtime-deps-and-recommends # Use pkg-perl-autopkgtest test for runtime-deps-and-recommends
# Some portal suggested dependencies are added here # Some portal suggested dependencies are added here
Test-Command: /usr/share/pkg-perl-autopkgtest/runner runtime-deps-and-recommends Test-Command: /usr/share/pkg-perl-autopkgtest/runner runtime-deps-and-recommends
Depends: @, @builddeps@, pkg-perl-autopkgtest, libyaml-perl, liblog-log4perl-perl, libauthen-pam-perl, libauthen-radius-perl, libweb-id-perl, libdatetime-format-rfc3339-perl Depends: @, @builddeps@, pkg-perl-autopkgtest
, libyaml-perl, liblog-log4perl-perl
, libauthen-pam-perl, libauthen-radius-perl
, libweb-id-perl, libio-socket-timeout-perl
Restrictions: superficial Restrictions: superficial
#Test-Command: ./debian/tests/runner heavy-deps #Test-Command: ./debian/tests/runner heavy-deps

View File

@ -34,6 +34,7 @@ and configure the following parameters:
Kerberos code to validate Kerberos ticket Kerberos code to validate Kerberos ticket
- **Remove domain in username**: set to "enabled" to strip username - **Remove domain in username**: set to "enabled" to strip username
value and remove the '@domain'. value and remove the '@domain'.
- **Allowed domains**: if set, tickets will only be accepted if they come from one of the domains listed here. This is a space-separated list. This feature can be useful when using :doc:`combination<authcombination>` and cross-realm Kerberos trusts.
.. attention:: .. attention::

View File

@ -98,12 +98,12 @@ Exported attributes
For each attribute, you can set: For each attribute, you can set:
- **Key name**: name of the key in LemonLDAP::NG session (for example - **Variable name**: name of the variable in LemonLDAP::NG session that will contain this attribute. For example
"uid" will then be used as $uid in access rules) "uid" will then be used as $uid in access rules
- **Attribute name**: name of the SAML attribute coming from the remote IDP
- **Friendly Name**: optional, SAML attribute friendly name.
- **Mandatory**: if set to On, then session will not open if this - **Mandatory**: if set to On, then session will not open if this
attribute is not given by IDP. attribute is not given by IDP.
- **Name**: SAML attribute name.
- **Friendly Name**: optional, SAML attribute friendly name.
- **Format** (optional): SAML attribute format. - **Format** (optional): SAML attribute format.
|image1| |image1|

View File

@ -166,11 +166,16 @@ claim <http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims>`__.
.. include:: openidconnectclaims.rst .. include:: openidconnectclaims.rst
So you can define for example: For each OpenID Connect claim you want to release to applications, you can define:
- name => cn * **Claim name**: the name of the claim as it will appear in Userinfo responses
- family_name => sn * **Variable name**: the name of the LemonLDAP::NG session variable containing the claim value
- email => mail * **Type**: the data type of the attribute. By default, a string. Choosing integer or boolean will make the claim appear as the corresponding JSON type.
* **Array**: choose how to process multi-valued attributes
* **Auto**: If the session key contains a single value, it will be released as a JSON number, string or boolean, depending on the previously specified type. If the session key contains multiple values, it will be released as an array of numbers, strings or booleans.
* **Always**: Return an array even if the attribute only contains one value
* **Never**: If the session key contains a single value, it will be released as a JSON number, string or boolean. If the session key contains multiple values, it will be released as a single string with a separator character.
.. attention:: .. attention::
@ -178,6 +183,7 @@ So you can define for example:
The specific ``sub`` attribute is not defined here, but The specific ``sub`` attribute is not defined here, but
in User attribute parameter (see below). in User attribute parameter (see below).
Extra Claims Extra Claims
^^^^^^^^^^^^ ^^^^^^^^^^^^

View File

@ -89,9 +89,9 @@ Exported attributes
For each attribute, you can set: For each attribute, you can set:
- **Key name**: name of the key in LemonLDAP::NG session - **Variable name**: name of the variable in LemonLDAP::NG session
- **Name**: SAML attribute name. - **Attribute name**: name of the SAML attribute that will be seen by applications
- **Friendly Name**: optional, SAML attribute friendly name. - **Friendly Name**: optional, friendly name of the SAML attribute seen by applications
- **Mandatory**: if set to "On", then this attribute is required to - **Mandatory**: if set to "On", then this attribute is required to
build the SAML response, an error will displayed if there is no value build the SAML response, an error will displayed if there is no value
for it. Optional attribute will be sent only if there is a value for it. Optional attribute will be sent only if there is a value

View File

@ -27,3 +27,4 @@ Plugins
resetcertificate resetcertificate
restservices restservices
soapservices soapservices
stayconnected

View File

@ -133,7 +133,7 @@ You have to run this command on Active Directory:
:: ::
ktpass -princ HTTP/auth.example.com@EXAMPLE.COM -mapuser KERB_AUTH@EXAMPLE.COM -crypto DES-CBC-MD5 -ptype KRB5_NT_PRINCIPAL -mapOp set -pass <PASSWORD> -out c:\auth.keytab ktpass -princ HTTP/auth.example.com@EXAMPLE.COM -mapuser KERB_AUTH@EXAMPLE.COM -crypto All -ptype KRB5_NT_PRINCIPAL -mapOp set -pass <PASSWORD> -out c:\auth.keytab
.. attention:: .. attention::

View File

@ -25,7 +25,7 @@ authentication process, then use ``afterSub``, for example:
use constant afterSub => { use constant afterSub => {
getUser => 'mysub', getUser => 'mysub',
} };
sub mysub { sub mysub {
my ( $self ,$req ) = @_; my ( $self ,$req ) = @_;
# Do something # Do something

View File

@ -286,7 +286,7 @@ Name Description
:doc:`Reset certificate by mail<resetcertificate>` [11]_\ |image37| Allow users to reset their certificate :doc:`Reset certificate by mail<resetcertificate>` [11]_\ |image37| Allow users to reset their certificate
:doc:`REST services<restservices>` |new| REST server for :doc:`Proxy<authproxy>` :doc:`REST services<restservices>` |new| REST server for :doc:`Proxy<authproxy>`
:doc:`SOAP services<soapservices>` |deprecated| SOAP server for :doc:`Proxy<authproxy>` :doc:`SOAP services<soapservices>` |deprecated| SOAP server for :doc:`Proxy<authproxy>`
Stay connected |new| Enable persistent connection on same browser :doc:`Stay connected<stayconnected>` |new| Enable persistent connection on same browser
Upgrade session |new| This plugin explains to an already authenticated user that a higher authentication level is required to access the URL instead of reject him Upgrade session |new| This plugin explains to an already authenticated user that a higher authentication level is required to access the URL instead of reject him
==================================================================== ============================================================================================================================================ ==================================================================== ============================================================================================================================================

View File

@ -0,0 +1,16 @@
Stay connected plugin
=====================
This plugin enables persistent connection. It allows us to connect
automatically from the same browser.
Configuration
-------------
Just enable it in the manager (section “plugins”).
- **Parameters**:
- **Activation**: Enable / Disable this plugin
- **Expiration time**: Persistent session connection and cookie timeout
- **Cookie name**: Persistent connection cookie name

View File

@ -17,6 +17,11 @@ backups and a rollback plan ready!
update. update.
2.0.10
------
- New dependency: IO::Socket::Timeout
2.0.9 2.0.9
----- -----

View File

@ -349,6 +349,8 @@ sub defaultValues {
'SSLAuthnLevel' => 5, 'SSLAuthnLevel' => 5,
'SSLVar' => 'SSL_CLIENT_S_DN_Email', 'SSLVar' => 'SSL_CLIENT_S_DN_Email',
'SSLVarIf' => {}, 'SSLVarIf' => {},
'stayConnectedCookieName' => 'llngconnection',
'stayConnectedTimeout' => 2592000,
'successLoginNumber' => 5, 'successLoginNumber' => 5,
'timeout' => 72000, 'timeout' => 72000,
'timeoutActivity' => 0, 'timeoutActivity' => 0,

View File

@ -393,8 +393,31 @@ sub _oidcMetaDataNodes {
my ( $id, $resp ) = ( 1, [] ); my ( $id, $resp ) = ( 1, [] );
# Handle RP Attributes
if ($query eq "oidcRPMetaDataExportedVars") {
my $pk = eval { $self->getConfKey( $req, $query )->{$partner} } // {};
return $self->sendError( $req, undef, 400 ) if ( $req->error );
foreach my $h ( sort keys %$pk ) {
# Set default values for type and array
my $data = [ split /;/, $pk->{$h} ];
unless ( $data->[1]) {
$data->[1] = "string";
}
unless ( $data->[2]) {
$data->[2] = "auto";
}
push @$resp,
{
id => "oidc${type}MetaDataNodes/$partner/$query/" . $id++,
title => $h,
data => $data,
type => 'oidcAttribute',
};
}
return $self->sendJSONresponse( $req, $resp );
}
# Return all exported attributes if asked # Return all exported attributes if asked
if ( $query =~ elsif ( $query =~
/^(?:oidc${type}MetaDataExportedVars|oidcRPMetaDataOptionsExtraClaims|oidcRPMetaDataMacros)$/ /^(?:oidc${type}MetaDataExportedVars|oidcRPMetaDataOptionsExtraClaims|oidcRPMetaDataMacros)$/
) )
{ {

View File

@ -44,7 +44,7 @@ our $authParameters = {
facebookParams => [qw(facebookAuthnLevel facebookExportedVars facebookAppId facebookAppSecret facebookUserField)], facebookParams => [qw(facebookAuthnLevel facebookExportedVars facebookAppId facebookAppSecret facebookUserField)],
githubParams => [qw(githubAuthnLevel githubClientID githubClientSecret githubUserField githubScope)], githubParams => [qw(githubAuthnLevel githubClientID githubClientSecret githubUserField githubScope)],
gpgParams => [qw(gpgAuthnLevel gpgDb)], gpgParams => [qw(gpgAuthnLevel gpgDb)],
kerberosParams => [qw(krbAuthnLevel krbKeytab krbByJs krbRemoveDomain)], kerberosParams => [qw(krbAuthnLevel krbKeytab krbByJs krbRemoveDomain krbAllowedDomains)],
ldapParams => [qw(ldapAuthnLevel ldapExportedVars ldapServer ldapPort ldapVerify ldapBase managerDn managerPassword ldapTimeout ldapIOTimeout ldapVersion ldapRaw ldapCAFile ldapCAPath LDAPFilter AuthLDAPFilter mailLDAPFilter ldapSearchDeref ldapGroupBase ldapGroupObjectClass ldapGroupAttributeName ldapGroupAttributeNameUser ldapGroupAttributeNameSearch ldapGroupDecodeSearchedValue ldapGroupRecursive ldapGroupAttributeNameGroup ldapPpolicyControl ldapSetPassword ldapChangePasswordAsUser ldapPwdEnc ldapUsePasswordResetAttribute ldapPasswordResetAttribute ldapPasswordResetAttributeValue ldapAllowResetExpiredPassword ldapITDS)], ldapParams => [qw(ldapAuthnLevel ldapExportedVars ldapServer ldapPort ldapVerify ldapBase managerDn managerPassword ldapTimeout ldapIOTimeout ldapVersion ldapRaw ldapCAFile ldapCAPath LDAPFilter AuthLDAPFilter mailLDAPFilter ldapSearchDeref ldapGroupBase ldapGroupObjectClass ldapGroupAttributeName ldapGroupAttributeNameUser ldapGroupAttributeNameSearch ldapGroupDecodeSearchedValue ldapGroupRecursive ldapGroupAttributeNameGroup ldapPpolicyControl ldapSetPassword ldapChangePasswordAsUser ldapPwdEnc ldapUsePasswordResetAttribute ldapPasswordResetAttribute ldapPasswordResetAttributeValue ldapAllowResetExpiredPassword ldapITDS)],
linkedinParams => [qw(linkedInAuthnLevel linkedInClientID linkedInClientSecret linkedInFields linkedInUserField linkedInScope)], linkedinParams => [qw(linkedInAuthnLevel linkedInClientID linkedInClientSecret linkedInFields linkedInUserField linkedInScope)],
nullParams => [qw(nullAuthnLevel)], nullParams => [qw(nullAuthnLevel)],

View File

@ -192,6 +192,8 @@ sub sendError {
: $code == 400 ? 'Bad request' : $code == 400 ? 'Bad request'
: 'Error' : 'Error'
); );
# TODO: this should probably use a template instead
my $s = "<html><head><title>$title</title> my $s = "<html><head><title>$title</title>
<style> <style>
body{background:#000;color:#fff;padding:10px 50px;font-family:sans-serif;}a{text-decoration:none;color:#fff;}h1{text-align:center;} body{background:#000;color:#fff;padding:10px 50px;font-family:sans-serif;}a{text-decoration:none;color:#fff;}h1{text-align:center;}
@ -203,18 +205,25 @@ body{background:#000;color:#fff;padding:10px 50px;font-family:sans-serif;}a{text
<center><a href=\"https://lemonldap-ng.org\">LemonLDAP::NG</a></center> <center><a href=\"https://lemonldap-ng.org\">LemonLDAP::NG</a></center>
</body> </body>
</html>"; </html>";
return [ return $self->sendRawHtml( $req, $s, code => $code );
$code,
[
'Content-Type' => 'text/html; charset=utf-8',
'Content-Length' => length($s),
$req->spliceHdrs,
],
[$s]
];
} }
} }
sub sendRawHtml {
my ( $self, $req, $s, %args ) = @_;
my $code = $args{code} || 200;
my $headers = $args{headers} || [ $req->spliceHdrs ];
return [
$code,
[
'Content-Type' => 'text/html; charset=utf-8',
'Content-Length' => length($s),
@{$headers},
],
[$s]
];
}
sub abort { sub abort {
my ( $self, $err ) = @_; my ( $self, $err ) = @_;
eval { $self->logger->error($err) }; eval { $self->logger->error($err) };
@ -250,7 +259,7 @@ sub sendJs {
return [ return [
200, 200,
[ [
'Content-Type' => 'application/javascript', 'Content-Type' => 'application/json',
'Content-Length' => length($s), 'Content-Length' => length($s),
'Cache-Control' => 'public,max-age=2592000', 'Cache-Control' => 'public,max-age=2592000',
], ],

View File

@ -197,9 +197,14 @@ sub custom {
# @return user identifier to log # @return user identifier to log
sub userId { sub userId {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
return $req->userData->{ $Lemonldap::NG::Handler::Main::tsv->{whatToTrace} my $userId =
$req->userData->{ $Lemonldap::NG::Handler::Main::tsv->{whatToTrace}
|| '_whatToTrace' } || '_whatToTrace' }
|| $req->userData->{'_user'} # Fix 2377
|| 'anonymous'; || 'anonymous';
$self->logger->debug("Returned userId: $userId");
return $userId;
} }
## @method boolean group(string group) ## @method boolean group(string group)

View File

@ -624,7 +624,7 @@ sub substitute {
$expr =~ s/\bskip\b/q\{999_SKIP\}/g; $expr =~ s/\bskip\b/q\{999_SKIP\}/g;
# handle inGroup # handle inGroup
$expr =~ s/\binGroup\(([^)]*)\)/listMatch(\$s->{'hGroups'},$1,1),/g; $expr =~ s/\binGroup\(([^)]*)\)/listMatch(\$s->{'hGroups'},$1,1)/g;
return $expr; return $expr;
} }

View File

@ -128,6 +128,8 @@ site/htdocs/static/forms/longtext.html
site/htdocs/static/forms/menuApp.html site/htdocs/static/forms/menuApp.html
site/htdocs/static/forms/menuCat.html site/htdocs/static/forms/menuCat.html
site/htdocs/static/forms/mini.html site/htdocs/static/forms/mini.html
site/htdocs/static/forms/oidcAttribute.html
site/htdocs/static/forms/oidcAttributeContainer.html
site/htdocs/static/forms/oidcOPMetaDataNode.html site/htdocs/static/forms/oidcOPMetaDataNode.html
site/htdocs/static/forms/oidcOPMetaDataNodeContainer.html site/htdocs/static/forms/oidcOPMetaDataNodeContainer.html
site/htdocs/static/forms/oidcRPMetaDataNode.html site/htdocs/static/forms/oidcRPMetaDataNode.html

View File

@ -90,8 +90,7 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
'form' => 'text', 'form' => 'text',
'test' => sub { 'test' => sub {
my ( $val, $conf ) = @_; my ( $val, $conf ) = @_;
return 1 return 1 if defined $conf->{'macros'}{$val} or $val =~ /^_/;
if defined $conf->{'macros'}{$val} or $val eq '_timezone';
foreach $_ ( keys %$conf ) { foreach $_ ( keys %$conf ) {
return 1 return 1
if $_ =~ /exportedvars$/i and defined $conf->{$_}{$val}; if $_ =~ /exportedvars$/i and defined $conf->{$_}{$val};
@ -114,6 +113,11 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
1; 1;
} }
}, },
'oidcAttribute' => {
'test' => sub {
1;
}
},
'oidcmetadatajson' => { 'oidcmetadatajson' => {
'test' => sub { 'test' => sub {
1; 1;
@ -1589,6 +1593,9 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
'key' => { 'key' => {
'type' => 'password' 'type' => 'password'
}, },
'krbAllowedDomains' => {
'type' => 'text'
},
'krbAuthnLevel' => { 'krbAuthnLevel' => {
'default' => 3, 'default' => 3,
'type' => 'int' 'type' => 'int'
@ -2183,7 +2190,9 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
'family_name' => 'sn', 'family_name' => 'sn',
'name' => 'cn' 'name' => 'cn'
}, },
'type' => 'keyTextContainer' 'keyTest' => qr/\w/,
'test' => qr/\w/,
'type' => 'oidcAttributeContainer'
}, },
'oidcRPMetaDataMacros' => { 'oidcRPMetaDataMacros' => {
'default' => {}, 'default' => {},
@ -3923,6 +3932,16 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
'default' => 0, 'default' => 0,
'type' => 'bool' 'type' => 'bool'
}, },
'stayConnectedCookieName' => {
'default' => 'llngconnection',
'msgFail' => '__badCookieName__',
'test' => qr/^[a-zA-Z][a-zA-Z0-9_-]*$/,
'type' => 'text'
},
'stayConnectedTimeout' => {
'default' => 2592000,
'type' => 'int'
},
'storePassword' => { 'storePassword' => {
'default' => 0, 'default' => 0,
'type' => 'bool' 'type' => 'bool'

View File

@ -433,7 +433,8 @@ sub buildZeroConf {
open( F, '>', $self->firstLmConfFile ) or die($!); open( F, '>', $self->firstLmConfFile ) or die($!);
my $tmp = Lemonldap::NG::Manager::Conf::Zero::zeroConf( my $tmp = Lemonldap::NG::Manager::Conf::Zero::zeroConf(
'__DNSDOMAIN__', '__SESSIONDIR__', '__DNSDOMAIN__', '__SESSIONDIR__',
'__PSESSIONDIR__', '__NOTIFICATIONDIR__', '__CACHEDIR__' '__PSESSIONDIR__', '__NOTIFICATIONDIR__',
'__CACHEDIR__'
); );
$tmp->{cfgNum} = 1; $tmp->{cfgNum} = 1;
print F $jsonEnc->encode($tmp); print F $jsonEnc->encode($tmp);
@ -624,10 +625,10 @@ sub scanTree {
# Get data type and build tree # Get data type and build tree
# #
# Types : PerlModule bool boolOrExpr catAndAppList file hostname int # Types : PerlModule bool boolOrExpr catAndAppList file hostname int
# keyTextContainer lmAttrOrMacro longtext openidServerList pcre # keyTextContainer lmAttrOrMacro longtext openidServerList
# rulesContainer samlAssertion samlAttributeContainer samlService # oidcAttributeContainer pcre rulesContainer samlAssertion
# select text trool url virtualHostContainer word # samlAttributeContainer samlService select text trool url
# password # virtualHostContainer word password
if ( $leaf =~ s/^\*// ) { if ( $leaf =~ s/^\*// ) {
push @angularScopeVars, [ $leaf, "$path._nodes[$ord]" ]; push @angularScopeVars, [ $leaf, "$path._nodes[$ord]" ];
@ -659,12 +660,18 @@ sub scanTree {
my $type = $attr->{type}; my $type = $attr->{type};
$type =~ s/Container//; $type =~ s/Container//;
foreach my $k ( sort keys( %{ $attr->{default} } ) ) { foreach my $k ( sort keys( %{ $attr->{default} } ) ) {
# Special handling for oidcAttribute
my $default = $attr->{default}->{$k};
if ( $attr->{type} eq 'oidcAttributeContainer' ) {
$default = [ $default, "string", "auto" ];
}
push @{ $jleaf->{default} }, push @{ $jleaf->{default} },
{ {
id => "$prefix$leaf/$k", id => "$prefix$leaf/$k",
title => $k, title => $k,
type => $type, type => $type,
data => $attr->{default}->{$k}, data => $default,
( (
$type eq 'rule' $type eq 'rule'
? ( re => $k ) ? ( re => $k )

View File

@ -81,7 +81,7 @@ sub types {
my ( $val, $conf ) = @_; my ( $val, $conf ) = @_;
return 1 return 1
if ( defined $conf->{macros}->{$val} if ( defined $conf->{macros}->{$val}
or $val eq '_timezone' ); or $val =~ m/^_/ );
foreach ( keys %$conf ) { foreach ( keys %$conf ) {
return 1 return 1
if ( $_ =~ /exportedvars$/i if ( $_ =~ /exportedvars$/i
@ -184,6 +184,9 @@ sub types {
menuCat => { menuCat => {
test => sub { 1 } test => sub { 1 }
}, },
oidcAttribute => {
test => sub { 1 }
},
oidcOPMetaDataNode => { oidcOPMetaDataNode => {
test => sub { 1 } test => sub { 1 }
}, },
@ -431,12 +434,25 @@ sub attributes {
flags => 'hmp', flags => 'hmp',
}, },
stayConnected => { stayConnected => {
type => 'bool', type => 'bool',
#help => 'stayconnected.html',
default => 0, default => 0,
documentation => 'Enable StayConnected plugin', documentation => 'Enable StayConnected plugin',
}, },
stayConnectedTimeout => {
type => 'int',
default => 2592000,
documentation =>
'StayConnected persistent connexion session timeout',
flags => 'm',
},
stayConnectedCookieName => {
type => 'text',
test => qr/^[a-zA-Z][a-zA-Z0-9_-]*$/,
msgFail => '__badCookieName__',
default => 'llngconnection',
documentation => 'Name of the stayConnected plugin cookie',
flags => 'p',
},
checkState => { checkState => {
type => 'bool', type => 'bool',
default => 0, default => 0,
@ -3684,6 +3700,10 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
default => 1, default => 1,
documentation => 'Remove domain in Kerberos username', documentation => 'Remove domain in Kerberos username',
}, },
krbAllowedDomains => {
type => 'text',
documentation => 'Allowed domains',
},
# Slave # Slave
slaveAuthnLevel => { slaveAuthnLevel => {
@ -4096,11 +4116,13 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
# OpenID Connect relying parties # OpenID Connect relying parties
oidcRPMetaDataExportedVars => { oidcRPMetaDataExportedVars => {
type => 'keyTextContainer', type => 'oidcAttributeContainer',
keyTest => qr/\w/,
test => qr/\w/,
default => { default => {
'name' => 'cn', 'name' => 'cn',
'family_name' => 'sn', 'family_name' => 'sn',
'email' => 'mail' 'email' => 'mail',
} }
}, },
oidcRPMetaDataOptionsClientID => { type => 'text', }, oidcRPMetaDataOptionsClientID => { type => 'text', },

View File

@ -251,7 +251,8 @@ sub tree {
help => 'authkerberos.html', help => 'authkerberos.html',
nodes => [ nodes => [
'krbAuthnLevel', 'krbKeytab', 'krbAuthnLevel', 'krbKeytab',
'krbByJs', 'krbRemoveDomain' 'krbByJs', 'krbRemoveDomain',
'krbAllowedDomains',
] ]
}, },
{ {
@ -616,11 +617,20 @@ sub tree {
title => 'plugins', title => 'plugins',
help => 'start.html#plugins', help => 'start.html#plugins',
nodes => [ nodes => [
'stayConnected',
'portalStatus', 'portalStatus',
'upgradeSession', 'upgradeSession',
'refreshSessions', 'refreshSessions',
'adaptativeAuthenticationLevelRules', 'adaptativeAuthenticationLevelRules',
{
title => 'stayConnect',
help => 'stayconnected.html',
form => 'simpleInputContainer',
nodes => [
'stayConnected',
'stayConnectedTimeout',
'stayConnectedCookieName'
],
},
{ {
title => 'portalServers', title => 'portalServers',
help => 'portalservers.html', help => 'portalservers.html',

View File

@ -407,6 +407,37 @@ sub _scanNodes {
hdebug(" $target"); hdebug(" $target");
$self->set( $target, $key, $leaf->{data} ); $self->set( $target, $key, $leaf->{data} );
} }
elsif ( $target =~ /^oidcRPMetaDataExportedVars$/ ) {
hdebug(" $target");
if ( $leaf->{cnodes} ) {
hdebug(' unopened');
$self->newConf->{$target}->{$key} =
$self->refConf->{$target}->{$oldName} // {};
}
elsif ($h) {
hdebug(' opened');
$self->confChanged(1);
my $tmp = $leaf->{data};
if ( ref( $leaf->{data} ) eq 'ARRAY' ) {
# Forward compatibility. If Type and Array have
# default values, store in old format
if ( $leaf->{data}->[1] eq "string"
and $leaf->{data}->[2] eq "auto" )
{
$tmp = $leaf->{data}->[0];
}
else {
$tmp = join ';', @{ $leaf->{data} };
}
}
$self->set( $target, $key, $leaf->{title}, $tmp );
}
else {
hdebug(" $target: looking for subnodes");
$self->_scanNodes($subNodes);
}
}
elsif ( elsif (
$target =~ /^oidc(?:O|R)PMetaData(?:ExportedVars|Macros)$/ ) $target =~ /^oidc(?:O|R)PMetaData(?:ExportedVars|Macros)$/ )
{ {

View File

@ -377,6 +377,15 @@ llapp.controller 'TreeCtrl', [
type: 'samlAttribute' type: 'samlAttribute'
data: ['0', 'New', '', ''] data: ['0', 'New', '', '']
# OIDC attribute entry
$scope.addOidcAttribute = ->
node = $scope._findContainer()
node.nodes.push
id: "#{node.id}/n#{idinc++}"
title: 'new'
type: 'oidcAttribute'
data: ['', 'string', 'auto']
# Nodes with template # Nodes with template
$scope.addVhost = -> $scope.addVhost = ->
name = if $scope.domain then ".#{$scope.domain.data}" else '.example.com' name = if $scope.domain then ".#{$scope.domain.data}" else '.example.com'

View File

@ -0,0 +1,48 @@
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title" trspan="oidcAttribute"></h3>
</div>
<table class="table">
<!-- Key Name -->
<tr>
<th><span trspan="claimName"></span></th>
<td><input id="oakinput" class="form-control" ng-model="currentNode.title"/></td>
</tr>
<!-- Name -->
<tr>
<th><span trspan="variableName"></span></th>
<td><input id="oaninput" class="form-control" ng-model="currentNode.data[0]"/></td>
</tr>
<!-- Type -->
<tr>
<th><span trspan="type"></span></th>
<td>
<select class="form-control" id="oatselect" aria-describedby="oatlbl" ng-model="currentNode.data[1]">
<option value="string" trspan="string"></option>
<option value="int" trspan="int"></option>
<option value="bool" trspan="bool"></option>
</select>
</td>
</tr>
<!-- Array -->
<tr>
<th><span trspan="array"></span></th>
<td>
<select class="form-control" id="oaaselect" aria-describedby="oaalbl" ng-model="currentNode.data[2]">
<option value="auto" trspan="auto"></option>
<option value="always" trspan="always"></option>
<option value="never" trspan="never"></option>
</select>
</td>
</tr>
</table>
</div>
<script type="text/menu">
[{
"title": "addOidcAttribute",
"icon": "plus-sign"
},{
"title": "deleteEntry",
"icon": "minus-sign"
}]
</script>

View File

@ -0,0 +1,49 @@
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{translateTitle(currentNode)}}</h3>
</div>
<div class="table-container">
<table class="table table-striped">
<thead>
<tr>
<th trspan="claimName"></th>
<th trspan="variableName"></th>
<th trspan="type"></th>
<th trspan="array"></th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="s in currentNode.nodes">
<td><input class="form-control" ng-model="s.title"/></td>
<td><input class="form-control" ng-model="s.data[0]"/></td>
<td>
<select class="form-control" id="oatselect" ng-model="s.data[1]">
<option value="string" trspan="string"></option>
<option value="int" trspan="int"></option>
<option value="bool" trspan="bool"></option>
</select>
</td>
<td>
<select class="form-control" id="oatselect" ng-model="s.data[2]">
<option value="auto" trspan="auto"></option>
<option value="always" trspan="always"></option>
<option value="never" trspan="never"></option>
</select>
</td>
<td>
<span class="link text-danger glyphicon glyphicon-minus-sign" ng-click="del(currentNode.nodes,$index)"></span>
<span ng-if="$last" class="link text-success glyphicon glyphicon-plus-sign" ng-click="menuClick({title:'addOidcAttribute'})"></span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<script type="text/menu">
[{
"title": "addOidcAttribute",
"icon": "plus-sign"
}]
</script>

View File

@ -5,12 +5,12 @@
<table class="table"> <table class="table">
<!-- Key Name --> <!-- Key Name -->
<tr> <tr>
<th><span trspan="keyname"></span></th> <th><span trspan="variableName"></span></th>
<td><input id="sakinput" class="form-control" ng-model="currentNode.title"/></td> <td><input id="sakinput" class="form-control" ng-model="currentNode.title"/></td>
</tr> </tr>
<!-- Name --> <!-- Name -->
<tr> <tr>
<th><span trspan="name"></span></th> <th><span trspan="attributeName"></span></th>
<td><input id="saninput" class="form-control" ng-model="currentNode.data[1]"/></td> <td><input id="saninput" class="form-control" ng-model="currentNode.data[1]"/></td>
</tr> </tr>
<!-- Friendly Name --> <!-- Friendly Name -->

View File

@ -6,8 +6,8 @@
<table class="table table-striped"> <table class="table table-striped">
<thead> <thead>
<tr> <tr>
<th trspan="keyname"></th> <th trspan="variableName"></th>
<th trspan="name"></th> <th trspan="attributeName"></th>
<th trspan="friendlyName"></th> <th trspan="friendlyName"></th>
<th trspan="mandatory"></th> <th trspan="mandatory"></th>
<th trspan="format"></th> <th trspan="format"></th>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -381,27 +381,39 @@ function templates(tpl,key) {
"cnodes" : tpl+"s/"+key+"/"+"oidcRPMetaDataExportedVars", "cnodes" : tpl+"s/"+key+"/"+"oidcRPMetaDataExportedVars",
"default" : [ "default" : [
{ {
"data" : "mail", "data" : [
"mail",
"string",
"auto"
],
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataExportedVars/email", "id" : tpl+"s/"+key+"/"+"oidcRPMetaDataExportedVars/email",
"title" : "email", "title" : "email",
"type" : "keyText" "type" : "oidcAttribute"
}, },
{ {
"data" : "sn", "data" : [
"sn",
"string",
"auto"
],
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataExportedVars/family_name", "id" : tpl+"s/"+key+"/"+"oidcRPMetaDataExportedVars/family_name",
"title" : "family_name", "title" : "family_name",
"type" : "keyText" "type" : "oidcAttribute"
}, },
{ {
"data" : "cn", "data" : [
"cn",
"string",
"auto"
],
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataExportedVars/name", "id" : tpl+"s/"+key+"/"+"oidcRPMetaDataExportedVars/name",
"title" : "name", "title" : "name",
"type" : "keyText" "type" : "oidcAttribute"
} }
], ],
"id" : tpl+"s/"+key+"/"+"oidcRPMetaDataExportedVars", "id" : tpl+"s/"+key+"/"+"oidcRPMetaDataExportedVars",
"title" : "oidcRPMetaDataExportedVars", "title" : "oidcRPMetaDataExportedVars",
"type" : "keyTextContainer" "type" : "oidcAttributeContainer"
}, },
{ {
"cnodes" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsExtraClaims", "cnodes" : tpl+"s/"+key+"/"+"oidcRPMetaDataOptionsExtraClaims",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -451,6 +451,16 @@ This file contains:
data: ['0', 'New', '', ''] data: ['0', 'New', '', '']
}); });
}; };
$scope.addOidcAttribute = function() {
var node;
node = $scope._findContainer();
return node.nodes.push({
id: node.id + "/n" + (idinc++),
title: 'new',
type: 'oidcAttribute',
data: ['', 'string', 'auto']
});
};
$scope.addVhost = function() { $scope.addVhost = function() {
var name; var name;
name = $scope.domain ? "." + $scope.domain.data : '.example.com'; name = $scope.domain ? "." + $scope.domain.data : '.example.com';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -31,6 +31,7 @@
"adaptativeAuthenticationLevelRules":"Adaptative authentication rules", "adaptativeAuthenticationLevelRules":"Adaptative authentication rules",
"addAppCasPartner":"إضافة تطبيق كاس", "addAppCasPartner":"إضافة تطبيق كاس",
"addIDPSamlPartner":"أضف IDP SAML", "addIDPSamlPartner":"أضف IDP SAML",
"addOidcAttribute":"إضافة صفة",
"addOidcOp":"إضافة أوبين أيدي كونيكت بروفيدر", "addOidcOp":"إضافة أوبين أيدي كونيكت بروفيدر",
"addOidcRp":"إضافة الطرف المعول لي أوبين أيدي كونيكت", "addOidcRp":"إضافة الطرف المعول لي أوبين أيدي كونيكت",
"addSamlAttribute":"إضافة صفة", "addSamlAttribute":"إضافة صفة",
@ -44,6 +45,7 @@
"ADPwdMaxAge":"الحد الأقصى لصلحية كلمة المرور", "ADPwdMaxAge":"الحد الأقصى لصلحية كلمة المرور",
"advancedParams":"المعايير المتقدمة", "advancedParams":"المعايير المتقدمة",
"allowedMarkups":"السماح بالترميز:", "allowedMarkups":"السماح بالترميز:",
"always":"Always",
"apacheParams":"معاييرأباتش", "apacheParams":"معاييرأباتش",
"apacheAuthnLevel":"مستوى إثبات الهوية", "apacheAuthnLevel":"مستوى إثبات الهوية",
"application":"تطبيق", "application":"تطبيق",
@ -51,7 +53,9 @@
"applicationList":"الاقسام والتطبيقات", "applicationList":"الاقسام والتطبيقات",
"applyResult":"تطبيق النتيجة", "applyResult":"تطبيق النتيجة",
"appsInThisCat":"التطبيقات في هذه الفئة", "appsInThisCat":"التطبيقات في هذه الفئة",
"array":"Array",
"attributesAndMacros":" السمات و الماكرو", "attributesAndMacros":" السمات و الماكرو",
"attributeName":"Attribute name",
"authAndUserdb":"الترخيص وقاعدة بيانات المستخدم", "authAndUserdb":"الترخيص وقاعدة بيانات المستخدم",
"authChain":"سلسلة إثبات الهوية", "authChain":"سلسلة إثبات الهوية",
"authChoice":"اختيار إثبات الهوية", "authChoice":"اختيار إثبات الهوية",
@ -96,6 +100,7 @@
"badValue":"قيمة خاطئة", "badValue":"قيمة خاطئة",
"badVariableName":"اسم المتغيرة خاطئ", "badVariableName":"اسم المتغيرة خاطئ",
"blackList":"القائمة السوداء", "blackList":"القائمة السوداء",
"bool":"Boolean",
"browse":"تصفح", "browse":"تصفح",
"browsersDontStorePassword":"Avoid browsers to store users password", "browsersDontStorePassword":"Avoid browsers to store users password",
"browserIdAuthnLevel":"مستوى إثبات الهوية", "browserIdAuthnLevel":"مستوى إثبات الهوية",
@ -189,6 +194,7 @@
"cfgVersion":"عملية ضبط الإصدارات", "cfgVersion":"عملية ضبط الإصدارات",
"checkXSS":"تحقق من هجمات XSS", "checkXSS":"تحقق من هجمات XSS",
"clickHereToForce":"انقر هنا لإجبار", "clickHereToForce":"انقر هنا لإجبار",
"claimName":"Claim name",
"checkboxes":"Checkboxes", "checkboxes":"Checkboxes",
"checkState":"تفعيل", "checkState":"تفعيل",
"checkStateSecret":"سر مشترك", "checkStateSecret":"سر مشترك",
@ -372,6 +378,7 @@
"index":"فهرس", "index":"فهرس",
"infoFormMethod":"طريقة للحصول على معلومات الإستمارة", "infoFormMethod":"طريقة للحصول على معلومات الإستمارة",
"invalidSessionData":"بيانات الجلسة غير صحيحة", "invalidSessionData":"بيانات الجلسة غير صحيحة",
"int":"Integer",
"internalReference":"المرجع الداخلي", "internalReference":"المرجع الداخلي",
"ipAddr":"عنوان الأي بي", "ipAddr":"عنوان الأي بي",
"ipAddresses":"عناوين الأي بي", "ipAddresses":"عناوين الأي بي",
@ -413,6 +420,7 @@
"krbByJs":"استخدام طلب أجاكس", "krbByJs":"استخدام طلب أجاكس",
"krbKeytab":"كيتاب", "krbKeytab":"كيتاب",
"krbRemoveDomain":"Remove domain from Kerberos username", "krbRemoveDomain":"Remove domain from Kerberos username",
"krbAllowedDomains":"Allowed domains",
"kerberosParams":"معايير كيربيروس", "kerberosParams":"معايير كيربيروس",
"label":"Label", "label":"Label",
"languages":"اللغات", "languages":"اللغات",
@ -450,7 +458,7 @@
"ldapServer":"مضيف الخادم", "ldapServer":"مضيف الخادم",
"ldapSetPassword":"تعديل كلمة المرور مع عملية موسعة", "ldapSetPassword":"تعديل كلمة المرور مع عملية موسعة",
"ldapTimeout":"Connection timeout", "ldapTimeout":"Connection timeout",
"ldapIOTimeout": "Operation timeout", "ldapIOTimeout":"Operation timeout",
"ldapUsePasswordResetAttribute":"استخدام سمة إعادة الضبط", "ldapUsePasswordResetAttribute":"استخدام سمة إعادة الضبط",
"ldapVerify":"Verify LDAP server certificate", "ldapVerify":"Verify LDAP server certificate",
"ldapVersion":"الإصدار", "ldapVersion":"الإصدار",
@ -519,6 +527,7 @@
"name":"اسم", "name":"اسم",
"needConfirmation":"تتوفر إعدادات جديدة.لإجبار حفظ هذه الإعدادات, انقر على خانة الاختيار بالقرب من زر 'حفظ'", "needConfirmation":"تتوفر إعدادات جديدة.لإجبار حفظ هذه الإعدادات, انقر على خانة الاختيار بالقرب من زر 'حفظ'",
"networkProblem":"مشكلة شبكة الاتصال", "networkProblem":"مشكلة شبكة الاتصال",
"never":"Never",
"newApp":"تطبيق جديد", "newApp":"تطبيق جديد",
"newChain":"سلسلة جديدة", "newChain":"سلسلة جديدة",
"newCat":"فئة جديدة", "newCat":"فئة جديدة",
@ -577,6 +586,7 @@
"offlineSessions":"Offline sessions", "offlineSessions":"Offline sessions",
"oldValue":"قيمة قديمة", "oldValue":"قيمة قديمة",
"on":"تنشيط", "on":"تنشيط",
"oidcAttribute":"OIDC Attribute",
"oidcAuthnLevel":"مستوى إثبات الهوية", "oidcAuthnLevel":"مستوى إثبات الهوية",
"oidcConsents":"OpenID Connect Consents", "oidcConsents":"OpenID Connect Consents",
"oidcOP":" أوبين أيدي كونيكت بروفيدر", "oidcOP":" أوبين أيدي كونيكت بروفيدر",
@ -910,9 +920,13 @@
"SSLVarIf":"حقل الشهادة الرقمية المستخرجة الشرطية", "SSLVarIf":"حقل الشهادة الرقمية المستخرجة الشرطية",
"ssoSessions":"جلسات السسو", "ssoSessions":"جلسات السسو",
"stateCheck":"State Check", "stateCheck":"State Check",
"stayConnected":"الاتصالات المستمرة", "stayConnect":"الاتصالات المستمرة",
"stayConnected":"Activation",
"stayConnectedCookieName":"اسم ملف تعريف الارتباط",
"stayConnectedTimeout":"Expiration time",
"successfullySaved":"تم الحفظ بنجاح", "successfullySaved":"تم الحفظ بنجاح",
"storePassword":"تخزين كلمة مرور المستخدم في بيانات الجلسة", "storePassword":"تخزين كلمة مرور المستخدم في بيانات الجلسة",
"string":"String",
"subtitle":"Subtitle", "subtitle":"Subtitle",
"successLoginNumber":"عدد تسجيلات الدخول المسجلة", "successLoginNumber":"عدد تسجيلات الدخول المسجلة",
"sympaHandler":"لطيف", "sympaHandler":"لطيف",
@ -986,6 +1000,7 @@
"value":"القيمة", "value":"القيمة",
"values":"القيم", "values":"القيم",
"variables":"المتغيرات", "variables":"المتغيرات",
"variableName":"Variable name",
"verifyU2FKey":"Verify U2F key", "verifyU2FKey":"Verify U2F key",
"verifyTOTPKey":"Verify TOTP key", "verifyTOTPKey":"Verify TOTP key",
"version":"الإصدار", "version":"الإصدار",
@ -1166,4 +1181,4 @@
"samlRelayStateTimeout":"تناوب حالة مهلة الجلسة ", "samlRelayStateTimeout":"تناوب حالة مهلة الجلسة ",
"samlUseQueryStringSpecific":"استخدام أسلوب query_string المعين", "samlUseQueryStringSpecific":"استخدام أسلوب query_string المعين",
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP" "samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
} }

View File

@ -31,6 +31,7 @@
"adaptativeAuthenticationLevelRules":"Adaptative authentication rules", "adaptativeAuthenticationLevelRules":"Adaptative authentication rules",
"addAppCasPartner":"Add CAS application", "addAppCasPartner":"Add CAS application",
"addIDPSamlPartner":"Add SAML IDP", "addIDPSamlPartner":"Add SAML IDP",
"addOidcAttribute":"Attribut hinzufügen",
"addOidcOp":"Add OpenID Connect Provider", "addOidcOp":"Add OpenID Connect Provider",
"addOidcRp":"Add OpenID Relying Party", "addOidcRp":"Add OpenID Relying Party",
"addSamlAttribute":"Attribut hinzufügen", "addSamlAttribute":"Attribut hinzufügen",
@ -44,6 +45,7 @@
"ADPwdMaxAge":"maximales Alter", "ADPwdMaxAge":"maximales Alter",
"advancedParams":"Weitere Einstellungen", "advancedParams":"Weitere Einstellungen",
"allowedMarkups":"Allowed markups:", "allowedMarkups":"Allowed markups:",
"always":"Always",
"apacheParams":"Apache parameters", "apacheParams":"Apache parameters",
"apacheAuthnLevel":"Authentication level", "apacheAuthnLevel":"Authentication level",
"application":"Applikation", "application":"Applikation",
@ -51,7 +53,9 @@
"applicationList":"Categories and applications", "applicationList":"Categories and applications",
"applyResult":"Apply result", "applyResult":"Apply result",
"appsInThisCat":"Applications in this category", "appsInThisCat":"Applications in this category",
"array":"Array",
"attributesAndMacros":"Attributes and Macros", "attributesAndMacros":"Attributes and Macros",
"attributeName":"Attribute name",
"authAndUserdb":"Authz and user DB", "authAndUserdb":"Authz and user DB",
"authChain":"Authentication chain", "authChain":"Authentication chain",
"authChoice":"Authentication choice", "authChoice":"Authentication choice",
@ -96,6 +100,7 @@
"badValue":"Bad value", "badValue":"Bad value",
"badVariableName":"Bad variable name", "badVariableName":"Bad variable name",
"blackList":"Black list", "blackList":"Black list",
"bool":"Boolean",
"browse":"Browse", "browse":"Browse",
"browsersDontStorePassword":"Avoid browsers to store users password", "browsersDontStorePassword":"Avoid browsers to store users password",
"browserIdAuthnLevel":"Authentication level", "browserIdAuthnLevel":"Authentication level",
@ -188,6 +193,7 @@
"cfgVersion":"Configuration version", "cfgVersion":"Configuration version",
"checkXSS":"Check XSS attacks", "checkXSS":"Check XSS attacks",
"clickHereToForce":"Click here to force", "clickHereToForce":"Click here to force",
"claimName":"Claim name",
"checkboxes":"Checkboxes", "checkboxes":"Checkboxes",
"checkState":"Activation", "checkState":"Activation",
"checkStateSecret":"Shared secret", "checkStateSecret":"Shared secret",
@ -222,7 +228,7 @@
"connectionTitle":"Verbindung", "connectionTitle":"Verbindung",
"content":"Content", "content":"Content",
"cookieExpiration":"Cookie expiration time", "cookieExpiration":"Cookie expiration time",
"cookieName":"Cookie Name", "cookieName":"Cookie name",
"cookieParams":"Cookies", "cookieParams":"Cookies",
"create":"Create", "create":"Create",
"currentConfiguration":"Current configuration", "currentConfiguration":"Current configuration",
@ -371,6 +377,7 @@
"index":"Index", "index":"Index",
"infoFormMethod":"Method for info form", "infoFormMethod":"Method for info form",
"invalidSessionData":"Invalid session data", "invalidSessionData":"Invalid session data",
"int":"Integer",
"internalReference":"Internal reference", "internalReference":"Internal reference",
"ipAddr":"IP address", "ipAddr":"IP address",
"ipAddresses":"IP addresses", "ipAddresses":"IP addresses",
@ -412,6 +419,7 @@
"krbByJs":"Use Ajax request", "krbByJs":"Use Ajax request",
"krbKeytab":"keytab file", "krbKeytab":"keytab file",
"krbRemoveDomain":"Remove domain from Kerberos username", "krbRemoveDomain":"Remove domain from Kerberos username",
"krbAllowedDomains":"Allowed domains",
"kerberosParams":"Kerberos parameters", "kerberosParams":"Kerberos parameters",
"label":"Label", "label":"Label",
"languages":"Languages", "languages":"Languages",
@ -449,7 +457,7 @@
"ldapServer":"Server host", "ldapServer":"Server host",
"ldapSetPassword":"Password modify extended operation", "ldapSetPassword":"Password modify extended operation",
"ldapTimeout":"Connection timeout", "ldapTimeout":"Connection timeout",
"ldapIOTimeout": "Operation timeout", "ldapIOTimeout":"Operation timeout",
"ldapUsePasswordResetAttribute":"Use reset attribute", "ldapUsePasswordResetAttribute":"Use reset attribute",
"ldapVerify":"Verify LDAP server certificate", "ldapVerify":"Verify LDAP server certificate",
"ldapVersion":"Version", "ldapVersion":"Version",
@ -518,6 +526,7 @@
"name":"Name", "name":"Name",
"needConfirmation":"A new configuration is available. To force saving this one, click on the check box near the 'save' button", "needConfirmation":"A new configuration is available. To force saving this one, click on the check box near the 'save' button",
"networkProblem":"Network problem", "networkProblem":"Network problem",
"never":"Never",
"newApp":"New application", "newApp":"New application",
"newChain":"New chain", "newChain":"New chain",
"newCat":"New category", "newCat":"New category",
@ -576,6 +585,7 @@
"offlineSessions":"Offline sessions", "offlineSessions":"Offline sessions",
"oldValue":"Old value", "oldValue":"Old value",
"on":"On", "on":"On",
"oidcAttribute":"OIDC Attribute",
"oidcAuthnLevel":"Authentication level", "oidcAuthnLevel":"Authentication level",
"oidcConsents":"OpenID Connect Consents", "oidcConsents":"OpenID Connect Consents",
"oidcOP":"OpenID Connect Provider", "oidcOP":"OpenID Connect Provider",
@ -909,9 +919,13 @@
"SSLVarIf":"Conditional extracted certificate field", "SSLVarIf":"Conditional extracted certificate field",
"ssoSessions":"SSO sessions", "ssoSessions":"SSO sessions",
"stateCheck":"State Check", "stateCheck":"State Check",
"stayConnected":"Persistent connections", "stayConnect":"Persistent connections",
"stayConnected":"Activation",
"stayConnectedCookieName":"Cookie name",
"stayConnectedTimeout":"Expiration time",
"successfullySaved":"Successfully saved", "successfullySaved":"Successfully saved",
"storePassword":"Store user password in session", "storePassword":"Store user password in session",
"string":"String",
"subtitle":"Subtitle", "subtitle":"Subtitle",
"successLoginNumber":"Number of registered logins", "successLoginNumber":"Number of registered logins",
"sympaHandler":"Sympa", "sympaHandler":"Sympa",
@ -985,6 +999,7 @@
"value":"Value", "value":"Value",
"values":"Values", "values":"Values",
"variables":"Variables", "variables":"Variables",
"variableName":"Variable name",
"verifyU2FKey":"Verify U2F key", "verifyU2FKey":"Verify U2F key",
"verifyTOTPKey":"Verify TOTP key", "verifyTOTPKey":"Verify TOTP key",
"version":"Version", "version":"Version",
@ -1165,4 +1180,4 @@
"samlRelayStateTimeout":"RelayState session timeout", "samlRelayStateTimeout":"RelayState session timeout",
"samlUseQueryStringSpecific":"Use specific query_string method", "samlUseQueryStringSpecific":"Use specific query_string method",
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP" "samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
} }

View File

@ -31,6 +31,7 @@
"adaptativeAuthenticationLevelRules":"Adaptative authentication rules", "adaptativeAuthenticationLevelRules":"Adaptative authentication rules",
"addAppCasPartner":"Add CAS application", "addAppCasPartner":"Add CAS application",
"addIDPSamlPartner":"Add SAML IDP", "addIDPSamlPartner":"Add SAML IDP",
"addOidcAttribute":"Add attribute",
"addOidcOp":"Add OpenID Connect Provider", "addOidcOp":"Add OpenID Connect Provider",
"addOidcRp":"Add OpenID Relying Party", "addOidcRp":"Add OpenID Relying Party",
"addSamlAttribute":"Add attribute", "addSamlAttribute":"Add attribute",
@ -44,6 +45,7 @@
"ADPwdMaxAge":"Password max age", "ADPwdMaxAge":"Password max age",
"advancedParams":"Advanced parameters", "advancedParams":"Advanced parameters",
"allowedMarkups":"Allowed markups:", "allowedMarkups":"Allowed markups:",
"always":"Always",
"apacheParams":"Apache parameters", "apacheParams":"Apache parameters",
"apacheAuthnLevel":"Authentication level", "apacheAuthnLevel":"Authentication level",
"application":"Application", "application":"Application",
@ -51,7 +53,9 @@
"applicationList":"Categories and applications", "applicationList":"Categories and applications",
"applyResult":"Apply result", "applyResult":"Apply result",
"appsInThisCat":"Applications in this category", "appsInThisCat":"Applications in this category",
"array":"Array",
"attributesAndMacros":"Attributes and Macros", "attributesAndMacros":"Attributes and Macros",
"attributeName":"Attribute name",
"authAndUserdb":"Authz and user DB", "authAndUserdb":"Authz and user DB",
"authChain":"Authentication chain", "authChain":"Authentication chain",
"authChoice":"Authentication choice", "authChoice":"Authentication choice",
@ -96,6 +100,7 @@
"badValue":"Bad value", "badValue":"Bad value",
"badVariableName":"Bad variable name", "badVariableName":"Bad variable name",
"blackList":"Black list", "blackList":"Black list",
"bool":"Boolean",
"browse":"Browse", "browse":"Browse",
"browsersDontStorePassword":"Avoid browsers to store users password", "browsersDontStorePassword":"Avoid browsers to store users password",
"browserIdAuthnLevel":"Authentication level", "browserIdAuthnLevel":"Authentication level",
@ -188,6 +193,7 @@
"cfgVersion":"Configuration version", "cfgVersion":"Configuration version",
"checkXSS":"Check XSS attacks", "checkXSS":"Check XSS attacks",
"clickHereToForce":"Click here to force", "clickHereToForce":"Click here to force",
"claimName":"Claim name",
"checkboxes":"Checkboxes", "checkboxes":"Checkboxes",
"checkState":"Activation", "checkState":"Activation",
"checkStateSecret":"Shared secret", "checkStateSecret":"Shared secret",
@ -222,7 +228,7 @@
"connectionTitle":"Connection", "connectionTitle":"Connection",
"content":"Content", "content":"Content",
"cookieExpiration":"Cookie expiration time", "cookieExpiration":"Cookie expiration time",
"cookieName":"Cookie Name", "cookieName":"Cookie name",
"cookieParams":"Cookies", "cookieParams":"Cookies",
"create":"Create", "create":"Create",
"currentConfiguration":"Current configuration", "currentConfiguration":"Current configuration",
@ -371,6 +377,7 @@
"index":"Index", "index":"Index",
"infoFormMethod":"Method for info form", "infoFormMethod":"Method for info form",
"invalidSessionData":"Invalid session data", "invalidSessionData":"Invalid session data",
"int":"Integer",
"internalReference":"Internal reference", "internalReference":"Internal reference",
"ipAddr":"IP address", "ipAddr":"IP address",
"ipAddresses":"IP addresses", "ipAddresses":"IP addresses",
@ -412,6 +419,7 @@
"krbByJs":"Use Ajax request", "krbByJs":"Use Ajax request",
"krbKeytab":"keytab file", "krbKeytab":"keytab file",
"krbRemoveDomain":"Remove domain from Kerberos username", "krbRemoveDomain":"Remove domain from Kerberos username",
"krbAllowedDomains":"Allowed domains",
"kerberosParams":"Kerberos parameters", "kerberosParams":"Kerberos parameters",
"label":"Label", "label":"Label",
"languages":"Languages", "languages":"Languages",
@ -518,6 +526,7 @@
"name":"Name", "name":"Name",
"needConfirmation":"A new configuration is available. To force saving this one, click on the check box near the 'save' button", "needConfirmation":"A new configuration is available. To force saving this one, click on the check box near the 'save' button",
"networkProblem":"Network problem", "networkProblem":"Network problem",
"never":"Never",
"newApp":"New application", "newApp":"New application",
"newChain":"New chain", "newChain":"New chain",
"newCat":"New category", "newCat":"New category",
@ -576,6 +585,7 @@
"offlineSessions":"Offline sessions", "offlineSessions":"Offline sessions",
"oldValue":"Old value", "oldValue":"Old value",
"on":"On", "on":"On",
"oidcAttribute":"OIDC Attribute",
"oidcAuthnLevel":"Authentication level", "oidcAuthnLevel":"Authentication level",
"oidcConsents":"OpenID Connect Consents", "oidcConsents":"OpenID Connect Consents",
"oidcOP":"OpenID Connect Provider", "oidcOP":"OpenID Connect Provider",
@ -909,9 +919,13 @@
"SSLVarIf":"Conditional extracted certificate field", "SSLVarIf":"Conditional extracted certificate field",
"ssoSessions":"SSO sessions", "ssoSessions":"SSO sessions",
"stateCheck":"State Check", "stateCheck":"State Check",
"stayConnected":"Persistent connections", "stayConnect":"Persistent connections",
"stayConnected":"Activation",
"stayConnectedCookieName":"Cookie name",
"stayConnectedTimeout":"Expiration time",
"successfullySaved":"Successfully saved", "successfullySaved":"Successfully saved",
"storePassword":"Store user password in session", "storePassword":"Store user password in session",
"string":"String",
"subtitle":"Subtitle", "subtitle":"Subtitle",
"successLoginNumber":"Number of registered logins", "successLoginNumber":"Number of registered logins",
"sympaHandler":"Sympa", "sympaHandler":"Sympa",
@ -985,6 +999,7 @@
"value":"Value", "value":"Value",
"values":"Values", "values":"Values",
"variables":"Variables", "variables":"Variables",
"variableName":"Variable name",
"verifyU2FKey":"Verify U2F key", "verifyU2FKey":"Verify U2F key",
"verifyTOTPKey":"Verify TOTP key", "verifyTOTPKey":"Verify TOTP key",
"version":"Version", "version":"Version",

View File

@ -31,6 +31,7 @@
"adaptativeAuthenticationLevelRules":"Règles d'authentification adaptative", "adaptativeAuthenticationLevelRules":"Règles d'authentification adaptative",
"addAppCasPartner":"Ajouter une application CAS", "addAppCasPartner":"Ajouter une application CAS",
"addIDPSamlPartner":"Ajouter un FI SAML", "addIDPSamlPartner":"Ajouter un FI SAML",
"addOidcAttribute":"Ajouter un attribut",
"addOidcOp":"Ajouter un fournisseur OpenID Connect", "addOidcOp":"Ajouter un fournisseur OpenID Connect",
"addOidcRp":"Ajouter un client OpenID Connect", "addOidcRp":"Ajouter un client OpenID Connect",
"addSamlAttribute":"Ajouter un attribut", "addSamlAttribute":"Ajouter un attribut",
@ -44,6 +45,7 @@
"ADPwdMaxAge":"Âge maximal du mot de passe", "ADPwdMaxAge":"Âge maximal du mot de passe",
"advancedParams":"Paramètres avancés", "advancedParams":"Paramètres avancés",
"allowedMarkups":"Balises autorisées :", "allowedMarkups":"Balises autorisées :",
"always":"Toujours",
"apacheParams":"Paramètres Apache", "apacheParams":"Paramètres Apache",
"apacheAuthnLevel":"Niveau d'authentification", "apacheAuthnLevel":"Niveau d'authentification",
"application":"Application", "application":"Application",
@ -51,7 +53,9 @@
"applicationList":"Catégories et applications", "applicationList":"Catégories et applications",
"applyResult":"Résultat de l'application", "applyResult":"Résultat de l'application",
"appsInThisCat":"Applications dans cette catégorie", "appsInThisCat":"Applications dans cette catégorie",
"array":"Tableau",
"attributesAndMacros":"Attributs et Macros", "attributesAndMacros":"Attributs et Macros",
"attributeName":"Nom de l'attribut",
"authAndUserdb":"Authent. et BD utilisateurs", "authAndUserdb":"Authent. et BD utilisateurs",
"authChain":"Chaîne d'authentification", "authChain":"Chaîne d'authentification",
"authChoice":"Choix d'authentification", "authChoice":"Choix d'authentification",
@ -97,6 +101,7 @@
"badVariableName":"Mauvais nom de variable", "badVariableName":"Mauvais nom de variable",
"blackList":"Liste noire", "blackList":"Liste noire",
"browse":"Naviguer", "browse":"Naviguer",
"bool":"Booléen",
"browsersDontStorePassword":"Interdire aux navigateurs de sauvegarder le mot de passe", "browsersDontStorePassword":"Interdire aux navigateurs de sauvegarder le mot de passe",
"browserIdAuthnLevel":"Niveau d'authentification", "browserIdAuthnLevel":"Niveau d'authentification",
"browserIdAutoLogin":"Authentification automatique", "browserIdAutoLogin":"Authentification automatique",
@ -188,6 +193,7 @@
"cfgVersion":"Version de la configuration", "cfgVersion":"Version de la configuration",
"checkXSS":"Contrôler les attaques XSS", "checkXSS":"Contrôler les attaques XSS",
"clickHereToForce":"Cliquer ici pour forcer", "clickHereToForce":"Cliquer ici pour forcer",
"claimName":"Nom de la revendication",
"checkboxes":"Cases à cocher", "checkboxes":"Cases à cocher",
"checkState":"Activation", "checkState":"Activation",
"checkStateSecret":"Secret partagé", "checkStateSecret":"Secret partagé",
@ -371,6 +377,7 @@
"index":"Index", "index":"Index",
"infoFormMethod":"Méthode du formulaire d'information", "infoFormMethod":"Méthode du formulaire d'information",
"invalidSessionData":"Donnée de session invalide", "invalidSessionData":"Donnée de session invalide",
"int":"Entier",
"internalReference":"Référence interne ", "internalReference":"Référence interne ",
"ipAddr":"Adresse IP", "ipAddr":"Adresse IP",
"ipAddresses":"Adresses IP", "ipAddresses":"Adresses IP",
@ -412,6 +419,7 @@
"krbByJs":"Utilise une requête Ajax", "krbByJs":"Utilise une requête Ajax",
"krbKeytab":"Fichier keytab", "krbKeytab":"Fichier keytab",
"krbRemoveDomain":"Supprimer le domaine du nom d'utilisateur", "krbRemoveDomain":"Supprimer le domaine du nom d'utilisateur",
"krbAllowedDomains":"Domaines autorisés",
"kerberosParams":"Paramètres Kerberos", "kerberosParams":"Paramètres Kerberos",
"label":"Label", "label":"Label",
"languages":"Langues", "languages":"Langues",
@ -518,6 +526,7 @@
"name":"Nom", "name":"Nom",
"needConfirmation":"Une nouvelle configuration est disponible. Pour sauvegarder celle-ci, cocher la case à côté du bouton 'sauver'", "needConfirmation":"Une nouvelle configuration est disponible. Pour sauvegarder celle-ci, cocher la case à côté du bouton 'sauver'",
"networkProblem":"Problème de réseau", "networkProblem":"Problème de réseau",
"never":"Jamais",
"newApp":"Nouvelle application", "newApp":"Nouvelle application",
"newChain":"Nouvelle chaîne", "newChain":"Nouvelle chaîne",
"newCat":"Nouvelle catégorie", "newCat":"Nouvelle catégorie",
@ -530,6 +539,7 @@
"newHost":"Nouvel hôte", "newHost":"Nouvel hôte",
"newPost":"Nouveau rejeu de formulaire", "newPost":"Nouveau rejeu de formulaire",
"newPostVar":"Nouvelle variable", "newPostVar":"Nouvelle variable",
"variableName":"Nom de la variable",
"newRSAKey":"Nouvelles clefs", "newRSAKey":"Nouvelles clefs",
"newRule":"Nouvelle règle", "newRule":"Nouvelle règle",
"newSfOver":"Nouveau paramètre", "newSfOver":"Nouveau paramètre",
@ -576,6 +586,7 @@
"offlineSessions":"Sessions hors ligne", "offlineSessions":"Sessions hors ligne",
"oldValue":"Ancienne valeur", "oldValue":"Ancienne valeur",
"on":"Activé", "on":"Activé",
"oidcAttribute":"Attribut OIDC",
"oidcAuthnLevel":"Niveau d'authentification", "oidcAuthnLevel":"Niveau d'authentification",
"oidcConsents":"Consentements OpenID Connect", "oidcConsents":"Consentements OpenID Connect",
"oidcOP":"Fournisseur OpenID Connect", "oidcOP":"Fournisseur OpenID Connect",
@ -909,9 +920,13 @@
"SSLVarIf":"Champ conditionnel extrait du certificat", "SSLVarIf":"Champ conditionnel extrait du certificat",
"ssoSessions":"Sessions SSO", "ssoSessions":"Sessions SSO",
"stateCheck":"Vérification de l'état", "stateCheck":"Vérification de l'état",
"stayConnected":"Connexions persistantes", "stayConnect":"Connexions persistantes",
"stayConnected":"Activation",
"stayConnectedCookieName":"Nom du cookie",
"stayConnectedTimeout":"Durée de validité",
"successfullySaved":"Sauvegarde effectuée", "successfullySaved":"Sauvegarde effectuée",
"storePassword":"Stocke le mot de passe de l'utilisateur en session", "storePassword":"Stocke le mot de passe de l'utilisateur en session",
"string":"Chaîne",
"subtitle":"Sous-titre", "subtitle":"Sous-titre",
"successLoginNumber":"Nombre de connexions mémorisées", "successLoginNumber":"Nombre de connexions mémorisées",
"sympaHandler":"Sympa", "sympaHandler":"Sympa",

View File

@ -31,6 +31,7 @@
"adaptativeAuthenticationLevelRules":"Adaptative authentication rules", "adaptativeAuthenticationLevelRules":"Adaptative authentication rules",
"addAppCasPartner":"Aggiungi applicazione CAS", "addAppCasPartner":"Aggiungi applicazione CAS",
"addIDPSamlPartner":"Aggiungi SAML IDP", "addIDPSamlPartner":"Aggiungi SAML IDP",
"addOidcAttribute":"Aggiungi attributo",
"addOidcOp":"Aggiungere OpenID Connect Provider", "addOidcOp":"Aggiungere OpenID Connect Provider",
"addOidcRp":"Aggiungi parte basata su OpenID ", "addOidcRp":"Aggiungi parte basata su OpenID ",
"addSamlAttribute":"Aggiungi attributo", "addSamlAttribute":"Aggiungi attributo",
@ -44,6 +45,7 @@
"ADPwdMaxAge":"Età massima della password", "ADPwdMaxAge":"Età massima della password",
"advancedParams":"Parametri avanzati", "advancedParams":"Parametri avanzati",
"allowedMarkups":"Marcature consentite:", "allowedMarkups":"Marcature consentite:",
"always":"Always",
"apacheParams":"Parametri Apache", "apacheParams":"Parametri Apache",
"apacheAuthnLevel":"Livello di autenticazione", "apacheAuthnLevel":"Livello di autenticazione",
"application":"Applicazione", "application":"Applicazione",
@ -51,7 +53,9 @@
"applicationList":"Categorie e applicazioni", "applicationList":"Categorie e applicazioni",
"applyResult":"Applica risultato", "applyResult":"Applica risultato",
"appsInThisCat":"Applicazioni in questa categoria", "appsInThisCat":"Applicazioni in questa categoria",
"array":"Array",
"attributesAndMacros":"Attributi e Macro", "attributesAndMacros":"Attributi e Macro",
"attributeName":"Attribute name",
"authAndUserdb":"Authz e utente DB", "authAndUserdb":"Authz e utente DB",
"authChain":"Catena di autenticazione", "authChain":"Catena di autenticazione",
"authChoice":"Scelta di autenticazione", "authChoice":"Scelta di autenticazione",
@ -96,6 +100,7 @@
"badValue":"Velore errato", "badValue":"Velore errato",
"badVariableName":"Nome variabile errato", "badVariableName":"Nome variabile errato",
"blackList":"Black list", "blackList":"Black list",
"bool":"Boolean",
"browse":"Naviga", "browse":"Naviga",
"browsersDontStorePassword":"Avoid browsers to store users password", "browsersDontStorePassword":"Avoid browsers to store users password",
"browserIdAuthnLevel":"Livello di autenticazione", "browserIdAuthnLevel":"Livello di autenticazione",
@ -188,6 +193,7 @@
"cfgVersion":"Versione configurazione", "cfgVersion":"Versione configurazione",
"checkXSS":"Verifica attacchi XSS", "checkXSS":"Verifica attacchi XSS",
"clickHereToForce":"Clicca qui per forzare", "clickHereToForce":"Clicca qui per forzare",
"claimName":"Claim name",
"checkboxes":"Checkboxes", "checkboxes":"Checkboxes",
"checkState":"Attivazione", "checkState":"Attivazione",
"checkStateSecret":"Segreto condiviso", "checkStateSecret":"Segreto condiviso",
@ -371,6 +377,7 @@
"index":"Indice", "index":"Indice",
"infoFormMethod":"Metodo per il modulo informazioni", "infoFormMethod":"Metodo per il modulo informazioni",
"invalidSessionData":"Dati di sessione non validi", "invalidSessionData":"Dati di sessione non validi",
"int":"Integer",
"internalReference":"Riferimento interno", "internalReference":"Riferimento interno",
"ipAddr":"Indirizzo IP", "ipAddr":"Indirizzo IP",
"ipAddresses":"Indirizzi IP", "ipAddresses":"Indirizzi IP",
@ -412,6 +419,7 @@
"krbByJs":"Utilizzare la richiesta Ajax", "krbByJs":"Utilizzare la richiesta Ajax",
"krbKeytab":"File keytab", "krbKeytab":"File keytab",
"krbRemoveDomain":"Rimuovi dominio dal nome utente Kerberos", "krbRemoveDomain":"Rimuovi dominio dal nome utente Kerberos",
"krbAllowedDomains":"Allowed domains",
"kerberosParams":"Parametri di Kerberos", "kerberosParams":"Parametri di Kerberos",
"label":"Label", "label":"Label",
"languages":"Lingue", "languages":"Lingue",
@ -449,7 +457,7 @@
"ldapServer":"Host del server", "ldapServer":"Host del server",
"ldapSetPassword":"Operazione prolungata di modifica password", "ldapSetPassword":"Operazione prolungata di modifica password",
"ldapTimeout":"Connection timeout", "ldapTimeout":"Connection timeout",
"ldapIOTimeout": "Operation timeout", "ldapIOTimeout":"Operation timeout",
"ldapUsePasswordResetAttribute":"Utilizza l'attributo di ripristino", "ldapUsePasswordResetAttribute":"Utilizza l'attributo di ripristino",
"ldapVerify":"Verify LDAP server certificate", "ldapVerify":"Verify LDAP server certificate",
"ldapVersion":"Versione", "ldapVersion":"Versione",
@ -518,6 +526,7 @@
"name":"Nome", "name":"Nome",
"needConfirmation":"È disponibile una nuova configurazione. Per forzarne il salvataggio, fai clic sulla casella di controllo vicino al pulsante 'salva'", "needConfirmation":"È disponibile una nuova configurazione. Per forzarne il salvataggio, fai clic sulla casella di controllo vicino al pulsante 'salva'",
"networkProblem":"Problema di rete", "networkProblem":"Problema di rete",
"never":"Never",
"newApp":"Nuova applicazione", "newApp":"Nuova applicazione",
"newChain":"Nuova catena", "newChain":"Nuova catena",
"newCat":"NUova categoria", "newCat":"NUova categoria",
@ -576,6 +585,7 @@
"offlineSessions":"Offline sessions", "offlineSessions":"Offline sessions",
"oldValue":"Vecchio valore", "oldValue":"Vecchio valore",
"on":"On", "on":"On",
"oidcAttribute":"OIDC Attribute",
"oidcAuthnLevel":"Livello di autenticazione", "oidcAuthnLevel":"Livello di autenticazione",
"oidcConsents":"OpenID Connect Consents", "oidcConsents":"OpenID Connect Consents",
"oidcOP":"Provider di OpenID Connect", "oidcOP":"Provider di OpenID Connect",
@ -909,9 +919,13 @@
"SSLVarIf":"Campo di certificato estratto condizionale", "SSLVarIf":"Campo di certificato estratto condizionale",
"ssoSessions":"Sessioni SSO", "ssoSessions":"Sessioni SSO",
"stateCheck":"Controllo dello stato", "stateCheck":"Controllo dello stato",
"stayConnected":"Connessioni persistenti", "stayConnect":"Connessioni persistenti",
"stayConnected":"Activation",
"stayConnectedCookieName":"Nome del cookie",
"stayConnectedTimeout":"Expiration time",
"successfullySaved":"Salvato con successo", "successfullySaved":"Salvato con successo",
"storePassword":"Memorizzare la password dell'utente nei dati di sessione", "storePassword":"Memorizzare la password dell'utente nei dati di sessione",
"string":"String",
"subtitle":"Subtitle", "subtitle":"Subtitle",
"successLoginNumber":"Numero di login registrati", "successLoginNumber":"Numero di login registrati",
"sympaHandler":"Sympa", "sympaHandler":"Sympa",
@ -985,6 +999,7 @@
"value":"Valore", "value":"Valore",
"values":"Valori", "values":"Valori",
"variables":"Variabili", "variables":"Variabili",
"variableName":"Variable name",
"verifyU2FKey":"Verifica la chiave U2F", "verifyU2FKey":"Verifica la chiave U2F",
"verifyTOTPKey":"Verifica la chiave TOTP", "verifyTOTPKey":"Verifica la chiave TOTP",
"version":"Versioni", "version":"Versioni",
@ -1165,4 +1180,4 @@
"samlRelayStateTimeout":"Timeout di sessione di RelayState", "samlRelayStateTimeout":"Timeout di sessione di RelayState",
"samlUseQueryStringSpecific":"Utilizza il metodo specifico query_string", "samlUseQueryStringSpecific":"Utilizza il metodo specifico query_string",
"samlOverrideIDPEntityID":"Sostituisci l'ID entità quando agisce come IDP" "samlOverrideIDPEntityID":"Sostituisci l'ID entità quando agisce come IDP"
} }

View File

@ -31,6 +31,7 @@
"adaptativeAuthenticationLevelRules":"Adaptative authentication rules", "adaptativeAuthenticationLevelRules":"Adaptative authentication rules",
"addAppCasPartner":"Dodaj aplikację CAS", "addAppCasPartner":"Dodaj aplikację CAS",
"addIDPSamlPartner":"Dodaj SAML IDP", "addIDPSamlPartner":"Dodaj SAML IDP",
"addOidcAttribute":"Dodaj atrybut",
"addOidcOp":"Dodaj dostawcę OpenID Connect", "addOidcOp":"Dodaj dostawcę OpenID Connect",
"addOidcRp":"Dodaj stronę zależną OpenID", "addOidcRp":"Dodaj stronę zależną OpenID",
"addSamlAttribute":"Dodaj atrybut", "addSamlAttribute":"Dodaj atrybut",
@ -44,6 +45,7 @@
"ADPwdMaxAge":"Maksymalny czas ważności hasła", "ADPwdMaxAge":"Maksymalny czas ważności hasła",
"advancedParams":"Zaawansowane parametry", "advancedParams":"Zaawansowane parametry",
"allowedMarkups":"Dozwolone znaczniki:", "allowedMarkups":"Dozwolone znaczniki:",
"always":"Always",
"apacheParams":"Parametry Apache", "apacheParams":"Parametry Apache",
"apacheAuthnLevel":"Poziom uwierzytelnienia", "apacheAuthnLevel":"Poziom uwierzytelnienia",
"application":"Aplikacja", "application":"Aplikacja",
@ -51,7 +53,9 @@
"applicationList":"Kategorie i aplikacje", "applicationList":"Kategorie i aplikacje",
"applyResult":"Zastosuj wynik", "applyResult":"Zastosuj wynik",
"appsInThisCat":"Aplikacje w tej kategorii", "appsInThisCat":"Aplikacje w tej kategorii",
"array":"Array",
"attributesAndMacros":"Atrybuty i Makra", "attributesAndMacros":"Atrybuty i Makra",
"attributeName":"Attribute name",
"authAndUserdb":"Authz i baza danych użytkownika", "authAndUserdb":"Authz i baza danych użytkownika",
"authChain":"Łańcuch uwierzytelnienia", "authChain":"Łańcuch uwierzytelnienia",
"authChoice":"Wybór uwierzytelnienia", "authChoice":"Wybór uwierzytelnienia",
@ -96,6 +100,7 @@
"badValue":"Błędna wartość", "badValue":"Błędna wartość",
"badVariableName":"Błędna nazwa zmiennej", "badVariableName":"Błędna nazwa zmiennej",
"blackList":"Czarna lista", "blackList":"Czarna lista",
"bool":"Boolean",
"browse":"Przeglądaj", "browse":"Przeglądaj",
"browsersDontStorePassword":"Zabroń przeglądarkom przechowywać hasła użytkowników", "browsersDontStorePassword":"Zabroń przeglądarkom przechowywać hasła użytkowników",
"browserIdAuthnLevel":"Poziom uwierzytelnienia", "browserIdAuthnLevel":"Poziom uwierzytelnienia",
@ -188,6 +193,7 @@
"cfgVersion":"Wersja konfiguracji", "cfgVersion":"Wersja konfiguracji",
"checkXSS":"Sprawdź ataki XSS", "checkXSS":"Sprawdź ataki XSS",
"clickHereToForce":"Kliknij tutaj, aby wymusić", "clickHereToForce":"Kliknij tutaj, aby wymusić",
"claimName":"Claim name",
"checkboxes":"Checkboxes", "checkboxes":"Checkboxes",
"checkState":"Aktywacja", "checkState":"Aktywacja",
"checkStateSecret":"Współdzielony sekret", "checkStateSecret":"Współdzielony sekret",
@ -222,7 +228,7 @@
"connectionTitle":"Połączenie", "connectionTitle":"Połączenie",
"content":"Zawartość", "content":"Zawartość",
"cookieExpiration":"Czas ważności pliku cookie", "cookieExpiration":"Czas ważności pliku cookie",
"cookieName":"Nazwa pliku cookie", "cookieName":"Nazwa ciasteczka",
"cookieParams":"Pliki cookie", "cookieParams":"Pliki cookie",
"create":"Stwórz", "create":"Stwórz",
"currentConfiguration":"Aktualna konfiguracja", "currentConfiguration":"Aktualna konfiguracja",
@ -371,6 +377,7 @@
"index":"Indeks", "index":"Indeks",
"infoFormMethod":"Metoda dla formularza informacyjnego", "infoFormMethod":"Metoda dla formularza informacyjnego",
"invalidSessionData":"Nieprawidłowe dane sesji", "invalidSessionData":"Nieprawidłowe dane sesji",
"int":"Integer",
"internalReference":"Referencja wewnętrzna", "internalReference":"Referencja wewnętrzna",
"ipAddr":"Adres IP", "ipAddr":"Adres IP",
"ipAddresses":"Adresy IP", "ipAddresses":"Adresy IP",
@ -412,6 +419,7 @@
"krbByJs":"Użyj żądania Ajax", "krbByJs":"Użyj żądania Ajax",
"krbKeytab":"plik keytab", "krbKeytab":"plik keytab",
"krbRemoveDomain":"Usuń domenę z nazwy użytkownika Kerberos", "krbRemoveDomain":"Usuń domenę z nazwy użytkownika Kerberos",
"krbAllowedDomains":"Allowed domains",
"kerberosParams":"Parametry Kerberos", "kerberosParams":"Parametry Kerberos",
"label":"Etykieta", "label":"Etykieta",
"languages":"Języki", "languages":"Języki",
@ -449,7 +457,7 @@
"ldapServer":"Host serwera", "ldapServer":"Host serwera",
"ldapSetPassword":"Rozszerzona operacja modyfikacji hasła", "ldapSetPassword":"Rozszerzona operacja modyfikacji hasła",
"ldapTimeout":"Connection timeout", "ldapTimeout":"Connection timeout",
"ldapIOTimeout": "Operation timeout", "ldapIOTimeout":"Operation timeout",
"ldapUsePasswordResetAttribute":"Użyj atrybutu reset", "ldapUsePasswordResetAttribute":"Użyj atrybutu reset",
"ldapVerify":"Verify LDAP server certificate", "ldapVerify":"Verify LDAP server certificate",
"ldapVersion":"Wersja", "ldapVersion":"Wersja",
@ -518,6 +526,7 @@
"name":"Nazwa", "name":"Nazwa",
"needConfirmation":"Dostępna jest nowa konfiguracja. Aby wymusić zapisanie aktualnej, kliknij pole wyboru obok przycisku „zapisz”", "needConfirmation":"Dostępna jest nowa konfiguracja. Aby wymusić zapisanie aktualnej, kliknij pole wyboru obok przycisku „zapisz”",
"networkProblem":"Problem z siecią", "networkProblem":"Problem z siecią",
"never":"Never",
"newApp":"Nowa aplikacja", "newApp":"Nowa aplikacja",
"newChain":"Nowy łańcuch", "newChain":"Nowy łańcuch",
"newCat":"Nowa kategoria", "newCat":"Nowa kategoria",
@ -576,6 +585,7 @@
"offlineSessions":"Sesje offline", "offlineSessions":"Sesje offline",
"oldValue":"Stara wartość", "oldValue":"Stara wartość",
"on":"Włączone", "on":"Włączone",
"oidcAttribute":"OIDC Attribute",
"oidcAuthnLevel":"Poziom uwierzytelnienia", "oidcAuthnLevel":"Poziom uwierzytelnienia",
"oidcConsents":"Zgoda na OpenID Connect", "oidcConsents":"Zgoda na OpenID Connect",
"oidcOP":"Dostawca OpenID Connect", "oidcOP":"Dostawca OpenID Connect",
@ -909,9 +919,13 @@
"SSLVarIf":"Warunkowe wyodrębnione pole certyfikatu", "SSLVarIf":"Warunkowe wyodrębnione pole certyfikatu",
"ssoSessions":"Sesje jednokrotnego logowania", "ssoSessions":"Sesje jednokrotnego logowania",
"stateCheck":"Kontrola stanu", "stateCheck":"Kontrola stanu",
"stayConnected":"Trwałe połączenia", "stayConnect":"Trwałe połączenia",
"stayConnected":"Activation",
"stayConnectedCookieName":"Nazwa ciasteczka",
"stayConnectedTimeout":"Expiration time",
"successfullySaved":"Pomyślnie zapisano", "successfullySaved":"Pomyślnie zapisano",
"storePassword":"Przechowuj hasło użytkownika w sesji", "storePassword":"Przechowuj hasło użytkownika w sesji",
"string":"String",
"subtitle":"Podtytuł", "subtitle":"Podtytuł",
"successLoginNumber":"Liczba zarejestrowanych loginów", "successLoginNumber":"Liczba zarejestrowanych loginów",
"sympaHandler":"Sympa", "sympaHandler":"Sympa",
@ -985,6 +999,7 @@
"value":"Wartość", "value":"Wartość",
"values":"Wartości", "values":"Wartości",
"variables":"Zmienne", "variables":"Zmienne",
"variableName":"Variable name",
"verifyU2FKey":"Sprawdź klucz U2F", "verifyU2FKey":"Sprawdź klucz U2F",
"verifyTOTPKey":"Sprawdź klucz TOTP", "verifyTOTPKey":"Sprawdź klucz TOTP",
"version":"Wersja", "version":"Wersja",
@ -1165,4 +1180,4 @@
"samlRelayStateTimeout":"Limit czasu sesji RelayState", "samlRelayStateTimeout":"Limit czasu sesji RelayState",
"samlUseQueryStringSpecific":"Użyj określonej metody query_string", "samlUseQueryStringSpecific":"Użyj określonej metody query_string",
"samlOverrideIDPEntityID":"Zastąp identyfikator jednostki podczas działania jako IDP" "samlOverrideIDPEntityID":"Zastąp identyfikator jednostki podczas działania jako IDP"
} }

View File

@ -31,6 +31,7 @@
"adaptativeAuthenticationLevelRules":"Uyarlanabilir doğrulama kuralları", "adaptativeAuthenticationLevelRules":"Uyarlanabilir doğrulama kuralları",
"addAppCasPartner":"CAS uygulaması ekle", "addAppCasPartner":"CAS uygulaması ekle",
"addIDPSamlPartner":"SAML IDP ekle", "addIDPSamlPartner":"SAML IDP ekle",
"addOidcAttribute":"Nitelik ekle",
"addOidcOp":"OpenID Connect Sağlayıcısı Ekle", "addOidcOp":"OpenID Connect Sağlayıcısı Ekle",
"addOidcRp":"OpenID Relying Party Ekle", "addOidcRp":"OpenID Relying Party Ekle",
"addSamlAttribute":"Nitelik ekle", "addSamlAttribute":"Nitelik ekle",
@ -44,6 +45,7 @@
"ADPwdMaxAge":"Parola maksimum sınırı", "ADPwdMaxAge":"Parola maksimum sınırı",
"advancedParams":"Gelişmiş parametreler", "advancedParams":"Gelişmiş parametreler",
"allowedMarkups":"İzin verilen biçimlendirmeler:", "allowedMarkups":"İzin verilen biçimlendirmeler:",
"always":"Always",
"apacheParams":"Apache parametreleri", "apacheParams":"Apache parametreleri",
"apacheAuthnLevel":"Doğrulama seviyesi", "apacheAuthnLevel":"Doğrulama seviyesi",
"application":"Uygulama", "application":"Uygulama",
@ -51,7 +53,9 @@
"applicationList":"Kategoriler ve uygulamalar", "applicationList":"Kategoriler ve uygulamalar",
"applyResult":"Sonucu uygula", "applyResult":"Sonucu uygula",
"appsInThisCat":"Bu kategorideki uygulamalar", "appsInThisCat":"Bu kategorideki uygulamalar",
"array":"Array",
"attributesAndMacros":"Nitelikler ve Makrolar", "attributesAndMacros":"Nitelikler ve Makrolar",
"attributeName":"Attribute name",
"authAndUserdb":"Yetkilendirme ve kullanıcı veri tabanı", "authAndUserdb":"Yetkilendirme ve kullanıcı veri tabanı",
"authChain":"Doğrulama zinciri", "authChain":"Doğrulama zinciri",
"authChoice":"Kimlik doğrulama tercihi", "authChoice":"Kimlik doğrulama tercihi",
@ -79,7 +83,7 @@
"badDomainName":"Hatalı etki alanı adı", "badDomainName":"Hatalı etki alanı adı",
"badEncoding":"Hatalı kodlama", "badEncoding":"Hatalı kodlama",
"badExpression":"Hatalı ifade", "badExpression":"Hatalı ifade",
"badExpressionAssignment":"Expression containing an assignment", "badExpressionAssignment":"İfade bir atama içeriyor",
"badHeaderName":"Hatalı başlık adı", "badHeaderName":"Hatalı başlık adı",
"badHostname":"Hatalı konak adı", "badHostname":"Hatalı konak adı",
"badLdapUri":"Hatalı LDAP URI", "badLdapUri":"Hatalı LDAP URI",
@ -96,6 +100,7 @@
"badValue":"Hatalı değer", "badValue":"Hatalı değer",
"badVariableName":"Hatalı değişken adı", "badVariableName":"Hatalı değişken adı",
"blackList":"Kara liste", "blackList":"Kara liste",
"bool":"Boolean",
"browse":"Göz at", "browse":"Göz at",
"browsersDontStorePassword":"Kullanıcı parolasını tarayıcılarda saklamaktan kaçının", "browsersDontStorePassword":"Kullanıcı parolasını tarayıcılarda saklamaktan kaçının",
"browserIdAuthnLevel":"Doğrulama seviyesi", "browserIdAuthnLevel":"Doğrulama seviyesi",
@ -188,6 +193,7 @@
"cfgVersion":"Yapılandırma sürümü", "cfgVersion":"Yapılandırma sürümü",
"checkXSS":"XSS saldırılarını kontrol et", "checkXSS":"XSS saldırılarını kontrol et",
"clickHereToForce":"Zorlamak için buraya tıklayın", "clickHereToForce":"Zorlamak için buraya tıklayın",
"claimName":"Claim name",
"checkboxes":"Onay kutuları", "checkboxes":"Onay kutuları",
"checkState":"Aktivasyon", "checkState":"Aktivasyon",
"checkStateSecret":"Paylaşılan sır", "checkStateSecret":"Paylaşılan sır",
@ -222,7 +228,7 @@
"connectionTitle":"Bağlantı", "connectionTitle":"Bağlantı",
"content":"İçerik", "content":"İçerik",
"cookieExpiration":"Çerez son kullanma süresi", "cookieExpiration":"Çerez son kullanma süresi",
"cookieName":"Çerez Adı", "cookieName":"Çerez adı",
"cookieParams":"Çerezler", "cookieParams":"Çerezler",
"create":"Oluştur", "create":"Oluştur",
"currentConfiguration":"Mevcut yapılandırma", "currentConfiguration":"Mevcut yapılandırma",
@ -279,7 +285,7 @@
"diffViewer":"Fark görüntüleyici", "diffViewer":"Fark görüntüleyici",
"diffWithPrevious":"önceki ile farkı", "diffWithPrevious":"önceki ile farkı",
"disabled":"Devre dışı", "disabled":"Devre dışı",
"displaySessionId":"Display session identifier", "displaySessionId":"Oturum kimliğini görüntüle",
"done":"tamam", "done":"tamam",
"dones":"Tamam", "dones":"Tamam",
"down":"Aşağı taşı", "down":"Aşağı taşı",
@ -371,6 +377,7 @@
"index":"Dizin", "index":"Dizin",
"infoFormMethod":"Bilgi formu için metot", "infoFormMethod":"Bilgi formu için metot",
"invalidSessionData":"Geçersiz oturum verisi", "invalidSessionData":"Geçersiz oturum verisi",
"int":"Integer",
"internalReference":"Dahili referans", "internalReference":"Dahili referans",
"ipAddr":"IP adresi", "ipAddr":"IP adresi",
"ipAddresses":"IP adresleri", "ipAddresses":"IP adresleri",
@ -412,6 +419,7 @@
"krbByJs":"Ajax isteği kullan", "krbByJs":"Ajax isteği kullan",
"krbKeytab":"keytab dosyası", "krbKeytab":"keytab dosyası",
"krbRemoveDomain":"Kerberos kullanıcı adından etki alanını kaldır", "krbRemoveDomain":"Kerberos kullanıcı adından etki alanını kaldır",
"krbAllowedDomains":"İzin verilen alan adları",
"kerberosParams":"Kerberos parametreleri", "kerberosParams":"Kerberos parametreleri",
"label":"Etiket", "label":"Etiket",
"languages":"Diller", "languages":"Diller",
@ -448,8 +456,8 @@
"ldapSearchDeref":"Takma ad yönlendirmeleri", "ldapSearchDeref":"Takma ad yönlendirmeleri",
"ldapServer":"Konak sunucu", "ldapServer":"Konak sunucu",
"ldapSetPassword":"Parola değiştirme işlemi genişletilmiş", "ldapSetPassword":"Parola değiştirme işlemi genişletilmiş",
"ldapTimeout":"Connection timeout", "ldapTimeout":"Bağlantı zaman aşımı",
"ldapIOTimeout": "Operation timeout", "ldapIOTimeout":"Operasyon zaman aşımı",
"ldapUsePasswordResetAttribute":"Sıfırlama niteliklerini kullan", "ldapUsePasswordResetAttribute":"Sıfırlama niteliklerini kullan",
"ldapVerify":"LDAP sunucu sertifikasını doğrulayın", "ldapVerify":"LDAP sunucu sertifikasını doğrulayın",
"ldapVersion":"Sürüm", "ldapVersion":"Sürüm",
@ -518,6 +526,7 @@
"name":"Ad", "name":"Ad",
"needConfirmation":"Yeni bir yapılandırma mevcut. Bunu kaydetmeye zorlamak için 'kaydet' butonunun yanındaki onay kutusuna tıklayın.", "needConfirmation":"Yeni bir yapılandırma mevcut. Bunu kaydetmeye zorlamak için 'kaydet' butonunun yanındaki onay kutusuna tıklayın.",
"networkProblem":"Ağ problemi", "networkProblem":"Ağ problemi",
"never":"Never",
"newApp":"Yeni uygulama", "newApp":"Yeni uygulama",
"newChain":"Yeni zincir", "newChain":"Yeni zincir",
"newCat":"Yeni kategori", "newCat":"Yeni kategori",
@ -576,6 +585,7 @@
"offlineSessions":"Çevrimdışı oturumlar", "offlineSessions":"Çevrimdışı oturumlar",
"oldValue":"Eski değer", "oldValue":"Eski değer",
"on":"Açık", "on":"Açık",
"oidcAttribute":"OIDC Attribute",
"oidcAuthnLevel":"Doğrulama seviyesi", "oidcAuthnLevel":"Doğrulama seviyesi",
"oidcConsents":"OpenID Connect İzinleri", "oidcConsents":"OpenID Connect İzinleri",
"oidcOP":"OpenID Connect Sağlayıcısı", "oidcOP":"OpenID Connect Sağlayıcısı",
@ -909,9 +919,13 @@
"SSLVarIf":"Koşullu çıkartılmış sertifika alanı", "SSLVarIf":"Koşullu çıkartılmış sertifika alanı",
"ssoSessions":"TOA oturumları", "ssoSessions":"TOA oturumları",
"stateCheck":"Durum Kontrolü", "stateCheck":"Durum Kontrolü",
"stayConnected":"Kalıcı bağlantılar", "stayConnect":"Kalıcı bağlantılar",
"stayConnected":"Aktivasyon",
"stayConnectedCookieName":"Çerez adı",
"stayConnectedTimeout":"Son kullanma süresi",
"successfullySaved":"Başarıyla kaydedildi", "successfullySaved":"Başarıyla kaydedildi",
"storePassword":"Kullanıcı parolasını oturumda sakla", "storePassword":"Kullanıcı parolasını oturumda sakla",
"string":"String",
"subtitle":"Altyazı", "subtitle":"Altyazı",
"successLoginNumber":"Kayıtlı girişlerin sayısı", "successLoginNumber":"Kayıtlı girişlerin sayısı",
"sympaHandler":"Sympa", "sympaHandler":"Sympa",
@ -985,6 +999,7 @@
"value":"Değer", "value":"Değer",
"values":"Değerler", "values":"Değerler",
"variables":"Değişkenler", "variables":"Değişkenler",
"variableName":"Variable name",
"verifyU2FKey":"U2F anahtarını doğrula", "verifyU2FKey":"U2F anahtarını doğrula",
"verifyTOTPKey":"TOTP anahtarını doğrula", "verifyTOTPKey":"TOTP anahtarını doğrula",
"version":"Sürüm", "version":"Sürüm",
@ -1165,4 +1180,4 @@
"samlRelayStateTimeout":"RelayState oturum zaman aşımı", "samlRelayStateTimeout":"RelayState oturum zaman aşımı",
"samlUseQueryStringSpecific":"Spesifik query_string metodu kullan", "samlUseQueryStringSpecific":"Spesifik query_string metodu kullan",
"samlOverrideIDPEntityID":"IDP olarak davrandığında Varlık ID'yi geçersiz kıl" "samlOverrideIDPEntityID":"IDP olarak davrandığında Varlık ID'yi geçersiz kıl"
} }

View File

@ -31,6 +31,7 @@
"adaptativeAuthenticationLevelRules":"Adaptative authentication rules", "adaptativeAuthenticationLevelRules":"Adaptative authentication rules",
"addAppCasPartner":"Thêm ứng dụng CAS", "addAppCasPartner":"Thêm ứng dụng CAS",
"addIDPSamlPartner":"Thêm SAML IDP", "addIDPSamlPartner":"Thêm SAML IDP",
"addOidcAttribute":"Thêm thuộc tính",
"addOidcOp":"Thêm nhà cung cấp kết nối OpenID", "addOidcOp":"Thêm nhà cung cấp kết nối OpenID",
"addOidcRp":"Thêm OpenID dựa vào Hãng", "addOidcRp":"Thêm OpenID dựa vào Hãng",
"addSamlAttribute":"Thêm thuộc tính", "addSamlAttribute":"Thêm thuộc tính",
@ -44,6 +45,7 @@
"ADPwdMaxAge":"Thời gian tối đa của mật khẩu", "ADPwdMaxAge":"Thời gian tối đa của mật khẩu",
"advancedParams":"Tham số nâng cao", "advancedParams":"Tham số nâng cao",
"allowedMarkups":"Được phép đánh dấu:", "allowedMarkups":"Được phép đánh dấu:",
"always":"Always",
"apacheParams":"Thông số Apache", "apacheParams":"Thông số Apache",
"apacheAuthnLevel":"Mức xác thực", "apacheAuthnLevel":"Mức xác thực",
"application":"Ứng dụng", "application":"Ứng dụng",
@ -51,7 +53,9 @@
"applicationList":"Danh mục và ứng dụng", "applicationList":"Danh mục và ứng dụng",
"applyResult":"Áp dụng kết quả", "applyResult":"Áp dụng kết quả",
"appsInThisCat":"Ứng dụng trong danh mục này", "appsInThisCat":"Ứng dụng trong danh mục này",
"array":"Array",
"attributesAndMacros":"Thuộc tính và Macro", "attributesAndMacros":"Thuộc tính và Macro",
"attributeName":"Attribute name",
"authAndUserdb":"Authz và user DB", "authAndUserdb":"Authz và user DB",
"authChain":"Chuỗi xác thực", "authChain":"Chuỗi xác thực",
"authChoice":"Lựa chọn xác thực", "authChoice":"Lựa chọn xác thực",
@ -96,6 +100,7 @@
"badValue":"Giá trị không hợp lệ", "badValue":"Giá trị không hợp lệ",
"badVariableName":"Tên biến không hợp lệ", "badVariableName":"Tên biến không hợp lệ",
"blackList":"Danh sách đen", "blackList":"Danh sách đen",
"bool":"Boolean",
"browse":"Duyệt", "browse":"Duyệt",
"browsersDontStorePassword":"Avoid browsers to store users password", "browsersDontStorePassword":"Avoid browsers to store users password",
"browserIdAuthnLevel":"Mức xác thực", "browserIdAuthnLevel":"Mức xác thực",
@ -188,6 +193,7 @@
"cfgVersion":"Phiên bản cấu hình", "cfgVersion":"Phiên bản cấu hình",
"checkXSS":"Kiểm tra tấn công XSS", "checkXSS":"Kiểm tra tấn công XSS",
"clickHereToForce":"Nhấp vào đây để bắt buộc", "clickHereToForce":"Nhấp vào đây để bắt buộc",
"claimName":"Claim name",
"checkboxes":"Checkboxes", "checkboxes":"Checkboxes",
"checkState":"Kích hoạt", "checkState":"Kích hoạt",
"checkStateSecret":"Chia sẻ bí mật", "checkStateSecret":"Chia sẻ bí mật",
@ -222,7 +228,7 @@
"connectionTitle":"Kết nối", "connectionTitle":"Kết nối",
"content":"Nội dung", "content":"Nội dung",
"cookieExpiration":"Thời gian hết hạn cookie", "cookieExpiration":"Thời gian hết hạn cookie",
"cookieName":"Cookie Name", "cookieName":"Tên cookie",
"cookieParams":"Cookie", "cookieParams":"Cookie",
"create":"Tạo", "create":"Tạo",
"currentConfiguration":"Cấu hình hiện tại", "currentConfiguration":"Cấu hình hiện tại",
@ -371,6 +377,7 @@
"index":"Chỉ mục", "index":"Chỉ mục",
"infoFormMethod":"Phương pháp cho mẫu thông tin", "infoFormMethod":"Phương pháp cho mẫu thông tin",
"invalidSessionData":"Dữ liệu phiên không hợp lệ", "invalidSessionData":"Dữ liệu phiên không hợp lệ",
"int":"Integer",
"internalReference":"Tham chiếu nội bộ", "internalReference":"Tham chiếu nội bộ",
"ipAddr":"Địa chỉ IP", "ipAddr":"Địa chỉ IP",
"ipAddresses":"Địa chỉ IP", "ipAddresses":"Địa chỉ IP",
@ -412,6 +419,7 @@
"krbByJs":"Sử dụng yêu cầu Ajax", "krbByJs":"Sử dụng yêu cầu Ajax",
"krbKeytab":"tệp keytab", "krbKeytab":"tệp keytab",
"krbRemoveDomain":"Remove domain from Kerberos username", "krbRemoveDomain":"Remove domain from Kerberos username",
"krbAllowedDomains":"Allowed domains",
"kerberosParams":"Tham số Kerberos", "kerberosParams":"Tham số Kerberos",
"label":"Label", "label":"Label",
"languages":"Ngôn ngữ", "languages":"Ngôn ngữ",
@ -449,7 +457,7 @@
"ldapServer":"Máy chủ lưu trữ", "ldapServer":"Máy chủ lưu trữ",
"ldapSetPassword":"Mật khẩu sửa đổi hoạt động mở rộng", "ldapSetPassword":"Mật khẩu sửa đổi hoạt động mở rộng",
"ldapTimeout":"Connection timeout", "ldapTimeout":"Connection timeout",
"ldapIOTimeout": "Operation timeout", "ldapIOTimeout":"Operation timeout",
"ldapUsePasswordResetAttribute":"Sử dụng thuộc tính đặt lại", "ldapUsePasswordResetAttribute":"Sử dụng thuộc tính đặt lại",
"ldapVerify":"Verify LDAP server certificate", "ldapVerify":"Verify LDAP server certificate",
"ldapVersion":"Phiên bản", "ldapVersion":"Phiên bản",
@ -518,6 +526,7 @@
"name":"Tên", "name":"Tên",
"needConfirmation":"Một cấu hình mới có sẵn. Để bắt buộc lưu cấu hình này, hãy nhấp vào hộp kiểm gần nút 'Lưu' ", "needConfirmation":"Một cấu hình mới có sẵn. Để bắt buộc lưu cấu hình này, hãy nhấp vào hộp kiểm gần nút 'Lưu' ",
"networkProblem":"Vấn đề về mạng", "networkProblem":"Vấn đề về mạng",
"never":"Never",
"newApp":"Ứng dụng mới", "newApp":"Ứng dụng mới",
"newChain":"Chuỗi mới", "newChain":"Chuỗi mới",
"newCat":"Danh mục mới", "newCat":"Danh mục mới",
@ -576,6 +585,7 @@
"offlineSessions":"Offline sessions", "offlineSessions":"Offline sessions",
"oldValue":"Giá trị cũ", "oldValue":"Giá trị cũ",
"on":"Vào", "on":"Vào",
"oidcAttribute":"OIDC Attribute",
"oidcAuthnLevel":"Mức xác thực", "oidcAuthnLevel":"Mức xác thực",
"oidcConsents":"OpenID Connect Consents", "oidcConsents":"OpenID Connect Consents",
"oidcOP":"Bộ cung cấp Kết nối OpenID", "oidcOP":"Bộ cung cấp Kết nối OpenID",
@ -909,9 +919,13 @@
"SSLVarIf":"Trích xuất trường chứng chỉ có điều kiện", "SSLVarIf":"Trích xuất trường chứng chỉ có điều kiện",
"ssoSessions":"Phiên SSO", "ssoSessions":"Phiên SSO",
"stateCheck":"State Check", "stateCheck":"State Check",
"stayConnected":"Duy trì kết nối", "stayConnect":"Duy trì kết nối",
"stayConnected":"Activation",
"stayConnectedCookieName":"Tên cookie",
"stayConnectedTimeout":"Expiration time",
"successfullySaved":"Lưu thành công", "successfullySaved":"Lưu thành công",
"storePassword":"Lưu trữ mật khẩu người dùng trong các dữ liệu phiên", "storePassword":"Lưu trữ mật khẩu người dùng trong các dữ liệu phiên",
"string":"String",
"subtitle":"Subtitle", "subtitle":"Subtitle",
"successLoginNumber":"Số lượng đăng nhập đã đăng ký", "successLoginNumber":"Số lượng đăng nhập đã đăng ký",
"sympaHandler":"Sympa", "sympaHandler":"Sympa",
@ -985,6 +999,7 @@
"value":"Giá trị", "value":"Giá trị",
"values":"Giá trị", "values":"Giá trị",
"variables":"biến", "variables":"biến",
"variableName":"Variable name",
"verifyU2FKey":"Verify U2F key", "verifyU2FKey":"Verify U2F key",
"verifyTOTPKey":"Verify TOTP key", "verifyTOTPKey":"Verify TOTP key",
"version":"Phiên bản", "version":"Phiên bản",
@ -1165,4 +1180,4 @@
"samlRelayStateTimeout":"Thời gian hết hạn phiên RelayState ", "samlRelayStateTimeout":"Thời gian hết hạn phiên RelayState ",
"samlUseQueryStringSpecific":"Sử dụng phương pháp query_string cụ thể", "samlUseQueryStringSpecific":"Sử dụng phương pháp query_string cụ thể",
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP" "samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
} }

View File

@ -31,6 +31,7 @@
"adaptativeAuthenticationLevelRules":"Adaptative authentication rules", "adaptativeAuthenticationLevelRules":"Adaptative authentication rules",
"addAppCasPartner":"增加CAS应用", "addAppCasPartner":"增加CAS应用",
"addIDPSamlPartner":"增加SAML IDP", "addIDPSamlPartner":"增加SAML IDP",
"addOidcAttribute":"增加属性",
"addOidcOp":"增加OpenID Connect Provider", "addOidcOp":"增加OpenID Connect Provider",
"addOidcRp":"增加OpenID Relying Party", "addOidcRp":"增加OpenID Relying Party",
"addSamlAttribute":"增加属性", "addSamlAttribute":"增加属性",
@ -44,6 +45,7 @@
"ADPwdMaxAge":"密码最长有效期", "ADPwdMaxAge":"密码最长有效期",
"advancedParams":"高级参数", "advancedParams":"高级参数",
"allowedMarkups":"允许的标记", "allowedMarkups":"允许的标记",
"always":"Always",
"apacheParams":"Apache 参数", "apacheParams":"Apache 参数",
"apacheAuthnLevel":"认证等级", "apacheAuthnLevel":"认证等级",
"application":"应用", "application":"应用",
@ -51,7 +53,9 @@
"applicationList":"分类和应用", "applicationList":"分类和应用",
"applyResult":"申请结果", "applyResult":"申请结果",
"appsInThisCat":"此类中的应用", "appsInThisCat":"此类中的应用",
"array":"Array",
"attributesAndMacros":"属性和宏", "attributesAndMacros":"属性和宏",
"attributeName":"Attribute name",
"authAndUserdb":"授权和用户数据库", "authAndUserdb":"授权和用户数据库",
"authChain":"认证chain", "authChain":"认证chain",
"authChoice":"认证方式选择", "authChoice":"认证方式选择",
@ -96,6 +100,7 @@
"badValue":"无效的 value", "badValue":"无效的 value",
"badVariableName":"无效的 variable 名称", "badVariableName":"无效的 variable 名称",
"blackList":"黑名单", "blackList":"黑名单",
"bool":"Boolean",
"browse":"浏览", "browse":"浏览",
"browsersDontStorePassword":"Avoid browsers to store users password", "browsersDontStorePassword":"Avoid browsers to store users password",
"browserIdAuthnLevel":"认证等级", "browserIdAuthnLevel":"认证等级",
@ -188,6 +193,7 @@
"cfgVersion":"配置信息", "cfgVersion":"配置信息",
"checkXSS":"Check XSS attacks", "checkXSS":"Check XSS attacks",
"clickHereToForce":"Click here to force", "clickHereToForce":"Click here to force",
"claimName":"Claim name",
"checkboxes":"Checkboxes", "checkboxes":"Checkboxes",
"checkState":"激活", "checkState":"激活",
"checkStateSecret":"Shared secret", "checkStateSecret":"Shared secret",
@ -371,6 +377,7 @@
"index":"Index", "index":"Index",
"infoFormMethod":"Method for info form", "infoFormMethod":"Method for info form",
"invalidSessionData":"Invalid session data", "invalidSessionData":"Invalid session data",
"int":"Integer",
"internalReference":"Internal reference", "internalReference":"Internal reference",
"ipAddr":"IP 地址", "ipAddr":"IP 地址",
"ipAddresses":"IP 地址", "ipAddresses":"IP 地址",
@ -412,6 +419,7 @@
"krbByJs":"使用 Ajax 请求", "krbByJs":"使用 Ajax 请求",
"krbKeytab":"keytab file", "krbKeytab":"keytab file",
"krbRemoveDomain":"Remove domain from Kerberos username", "krbRemoveDomain":"Remove domain from Kerberos username",
"krbAllowedDomains":"Allowed domains",
"kerberosParams":"Kerberos 参数", "kerberosParams":"Kerberos 参数",
"label":"Label", "label":"Label",
"languages":"语言", "languages":"语言",
@ -449,7 +457,7 @@
"ldapServer":"Server host", "ldapServer":"Server host",
"ldapSetPassword":"Password modify extended operation", "ldapSetPassword":"Password modify extended operation",
"ldapTimeout":"Connection timeout", "ldapTimeout":"Connection timeout",
"ldapIOTimeout": "Operation timeout", "ldapIOTimeout":"Operation timeout",
"ldapUsePasswordResetAttribute":"Use reset attribute", "ldapUsePasswordResetAttribute":"Use reset attribute",
"ldapVerify":"Verify LDAP server certificate", "ldapVerify":"Verify LDAP server certificate",
"ldapVersion":"版本", "ldapVersion":"版本",
@ -518,6 +526,7 @@
"name":"Name", "name":"Name",
"needConfirmation":"A new configuration is available. To force saving this one, click on the check box near the 'save' button", "needConfirmation":"A new configuration is available. To force saving this one, click on the check box near the 'save' button",
"networkProblem":"Network problem", "networkProblem":"Network problem",
"never":"Never",
"newApp":"New application", "newApp":"New application",
"newChain":"New chain", "newChain":"New chain",
"newCat":"New category", "newCat":"New category",
@ -576,6 +585,7 @@
"offlineSessions":"Offline sessions", "offlineSessions":"Offline sessions",
"oldValue":"Old value", "oldValue":"Old value",
"on":"On", "on":"On",
"oidcAttribute":"OIDC Attribute",
"oidcAuthnLevel":"认证等级", "oidcAuthnLevel":"认证等级",
"oidcConsents":"OpenID Connect Consents", "oidcConsents":"OpenID Connect Consents",
"oidcOP":"OpenID Connect Provider", "oidcOP":"OpenID Connect Provider",
@ -804,7 +814,7 @@
"reloadParams":"Configuration reload", "reloadParams":"Configuration reload",
"reloadTimeout":"Reload timeout", "reloadTimeout":"Reload timeout",
"reloadUrls":"Reload URLs", "reloadUrls":"Reload URLs",
"remoteCookieName":"Cookie name", "remoteCookieName":"Cookie 名称",
"remoteGlobalStorage":"Sessions module", "remoteGlobalStorage":"Sessions module",
"remoteGlobalStorageOptions":"Sessions module options", "remoteGlobalStorageOptions":"Sessions module options",
"remoteParams":"Remote parameters", "remoteParams":"Remote parameters",
@ -909,9 +919,13 @@
"SSLVarIf":"Conditional extracted certificate field", "SSLVarIf":"Conditional extracted certificate field",
"ssoSessions":"SSO sessions", "ssoSessions":"SSO sessions",
"stateCheck":"State Check", "stateCheck":"State Check",
"stayConnected":"Persistent connections", "stayConnect":"Persistent connections",
"stayConnected":"Activation",
"stayConnectedCookieName":"Cookie 名称",
"stayConnectedTimeout":"Expiration time",
"successfullySaved":"Successfully saved", "successfullySaved":"Successfully saved",
"storePassword":"Store user password in session", "storePassword":"Store user password in session",
"string":"String",
"subtitle":"Subtitle", "subtitle":"Subtitle",
"successLoginNumber":"Number of registered logins", "successLoginNumber":"Number of registered logins",
"sympaHandler":"Sympa", "sympaHandler":"Sympa",
@ -985,6 +999,7 @@
"value":"Value", "value":"Value",
"values":"Values", "values":"Values",
"variables":"Variables", "variables":"Variables",
"variableName":"Variable name",
"verifyU2FKey":"Verify U2F key", "verifyU2FKey":"Verify U2F key",
"verifyTOTPKey":"Verify TOTP key", "verifyTOTPKey":"Verify TOTP key",
"version":"Version", "version":"Version",
@ -1165,4 +1180,4 @@
"samlRelayStateTimeout":"RelayState session timeout", "samlRelayStateTimeout":"RelayState session timeout",
"samlUseQueryStringSpecific":"Use specific query_string method", "samlUseQueryStringSpecific":"Use specific query_string method",
"samlOverrideIDPEntityID":"Override Entity ID when acting as IDP" "samlOverrideIDPEntityID":"Override Entity ID when acting as IDP"
} }

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -114,7 +114,7 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="input-group maxw"> <div class="input-group maxw">
<label class="input-group-addon" id="promptlabel" for="promptinput" trspan="{{elem('message').field}}"/> <label class="input-group-addon" id="promptlabel" for="promptinput" trspan="{{elem('message').field}}"></label>
<input id="promptinput" class="form-control" ng-model="result" aria-describedby="promptlabel"/> <input id="promptinput" class="form-control" ng-model="result" aria-describedby="promptlabel"/>
</div> </div>
</div> </div>
@ -161,7 +161,7 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="input-group maxw"> <div class="input-group maxw">
<label class="input-group-addon" id="mlabel" for="mdPwd" trspan="password"/> <label class="input-group-addon" id="mlabel" for="mdPwd" trspan="password"></label>
<input id="mdPwd" class="form-control" ng-model="result" aria-describedby="mlabel"/> <input id="mdPwd" class="form-control" ng-model="result" aria-describedby="mlabel"/>
</div> </div>
</div> </div>

View File

@ -557,6 +557,7 @@ t/32-Auth-and-issuer-OIDC-implicit.t
t/32-Auth-and-issuer-OIDC-sorted.t t/32-Auth-and-issuer-OIDC-sorted.t
t/32-CAS-10.t t/32-CAS-10.t
t/32-CAS-Macros.t t/32-CAS-Macros.t
t/32-OIDC-ClaimTypes.t
t/32-OIDC-Code-Flow-with-2F-UpgradeOnly.t t/32-OIDC-Code-Flow-with-2F-UpgradeOnly.t
t/32-OIDC-Code-Flow-with-2F.t t/32-OIDC-Code-Flow-with-2F.t
t/32-OIDC-Macro.t t/32-OIDC-Macro.t

View File

@ -150,7 +150,7 @@ sub authenticate {
and $self->conf->{ldapAllowResetExpiredPassword} ) and $self->conf->{ldapAllowResetExpiredPassword} )
) )
{ {
$req->data->{oldpassword} = $self->{password}; $req->data->{oldpassword} = $req->data->{password}; # Fix 2377
$req->data->{noerror} = 1; $req->data->{noerror} = 1;
$self->setSecurity($req); $self->setSecurity($req);
} }

View File

@ -16,18 +16,30 @@ our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Auth'; extends 'Lemonldap::NG::Portal::Main::Auth';
has keytab => ( is => 'rw' ); has allowedDomains => ( is => 'rw', isa => 'ArrayRef' );
has Name => ( is => 'ro', default => 'Kerberos' ); has keytab => ( is => 'rw' );
has AjaxInitScript => ( is => 'rw', default => '' );
has Name => ( is => 'ro', default => 'Kerberos' );
has InitCmd => (
is => 'ro',
default => q@$self->p->setHiddenFormValue( $req, kerberos => 0, '', 0 )@
);
# INITIALIZATION # INITIALIZATION
sub init { sub init {
my $self = shift; my $self = shift;
my $file; my $file;
my $domains;
unless ( $file = $self->conf->{krbKeytab} ) { unless ( $file = $self->conf->{krbKeytab} ) {
$self->logger->error('Keytab not defined'); $self->logger->error('Keytab not defined');
return 0; return 0;
} }
if ( $domains = $self->conf->{krbAllowedDomains} ) {
$self->allowedDomains( [ split /[\s,]+/, $domains ] );
}
$self->keytab("FILE:$file"); $self->keytab("FILE:$file");
return 1; return 1;
} }
@ -38,7 +50,7 @@ sub extractFormInfo {
if ( $req->data->{_krbUser} ) { if ( $req->data->{_krbUser} ) {
$self->logger->debug( $self->logger->debug(
'Kerberos ticket already validated for ' . $req->data->{_krbUser} ); 'Kerberos ticket already validated for ' . $req->data->{_krbUser} );
return PE_OK; return $self->_checkDomains($req);
} }
my $auth = $req->env->{HTTP_AUTHORIZATION}; my $auth = $req->env->{HTTP_AUTHORIZATION};
@ -156,7 +168,24 @@ sub extractFormInfo {
$client_name =~ s/^(.*)@.*$/$1/; $client_name =~ s/^(.*)@.*$/$1/;
} }
$req->user($client_name); $req->user($client_name);
return PE_OK; return $self->_checkDomains($req);
}
sub _checkDomains {
my ( $self, $req ) = @_;
# If krbAllowedDomains is not defined, allow every domain
return PE_OK unless ( $self->allowedDomains );
my ($domain) = $req->data->{_krbUser} =~ m/^.*@(.*)$/;
if ( grep { lc($_) eq lc($domain) } @{ $self->allowedDomains } ) {
return PE_OK;
}
else {
$self->userLogger->warn(
"Received kerberos domain $domain is not allowed");
return PE_BADCREDENTIALS;
}
} }
sub authenticate { sub authenticate {

View File

@ -8,22 +8,17 @@ use Lemonldap::NG::Portal::Main::Constants qw(
PE_ERROR PE_ERROR
PE_BADOLDPASSWORD PE_BADOLDPASSWORD
PE_LDAPCONNECTFAILED PE_LDAPCONNECTFAILED
PE_PASSWORDFORMEMPTY
PE_PASSWORD_MISMATCH
PE_PP_CHANGE_AFTER_RESET
PE_PP_PASSWORD_EXPIRED PE_PP_PASSWORD_EXPIRED
PE_PP_INSUFFICIENT_PASSWORD_QUALITY PE_PP_CHANGE_AFTER_RESET
PE_PP_PASSWORD_TOO_SHORT
PE_PP_PASSWORD_TOO_YOUNG
PE_PP_PASSWORD_IN_HISTORY
PE_PP_MUST_SUPPLY_OLD_PASSWORD
); );
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';
# Inheritance: UserDB::LDAP provides all needed ldap functions # Inheritance: UserDB::LDAP provides all needed ldap functions
extends extends qw(
qw(Lemonldap::NG::Portal::Auth::_WebForm Lemonldap::NG::Portal::Lib::LDAP); Lemonldap::NG::Portal::Lib::LDAP
Lemonldap::NG::Portal::Auth::_WebForm
);
sub init { sub init {
my ($self) = @_; my ($self) = @_;
@ -92,7 +87,7 @@ sub authenticate {
and $self->conf->{ldapAllowResetExpiredPassword} ) and $self->conf->{ldapAllowResetExpiredPassword} )
) )
{ {
$req->data->{oldpassword} = $self->{password}; $req->data->{oldpassword} = $req->data->{password}; # Fix 2377
$req->data->{noerror} = 1; $req->data->{noerror} = 1;
$self->setSecurity($req); $self->setSecurity($req);
} }
@ -102,7 +97,7 @@ sub authenticate {
} }
sub authLogout { sub authLogout {
PE_OK; return PE_OK;
} }
sub getForm { sub getForm {

View File

@ -8,21 +8,23 @@ package Lemonldap::NG::Portal::Auth::_WebForm;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw( use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_NOTOKEN
PE_FORMEMPTY
PE_FIRSTACCESS
PE_CAPTCHAEMPTY PE_CAPTCHAEMPTY
PE_CAPTCHAERROR PE_CAPTCHAERROR
PE_FIRSTACCESS
PE_FORMEMPTY
PE_NOTOKEN
PE_OK
PE_PASSWORDFORMEMPTY
PE_TOKENEXPIRED PE_TOKENEXPIRED
PE_MALFORMEDUSER PE_MALFORMEDUSER
PE_PASSWORDFORMEMPTY
); );
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Auth', extends qw(
'Lemonldap::NG::Portal::Lib::_tokenRule'; Lemonldap::NG::Portal::Main::Auth
Lemonldap::NG::Portal::Lib::_tokenRule
);
has authnLevel => ( has authnLevel => (
is => 'rw', is => 'rw',
@ -138,7 +140,7 @@ sub extractFormInfo {
# Other parameters # Other parameters
$req->data->{timezone} = $req->param('timezone'); $req->data->{timezone} = $req->param('timezone');
PE_OK; return PE_OK;
} }
# Set password in session data if wanted. # Set password in session data if wanted.
@ -158,7 +160,7 @@ sub setAuthSessionInfo {
# Store user timezone # Store user timezone
$req->{sessionInfo}->{'_timezone'} = $self->{'timezone'}; $req->{sessionInfo}->{'_timezone'} = $self->{'timezone'};
PE_OK; return PE_OK;
} }
# @return display type # @return display type

View File

@ -1096,7 +1096,9 @@ sub _handlePasswordGrant {
my $user_id = $self->getUserIDForRP( $req, $rp, $req->sessionInfo ); my $user_id = $self->getUserIDForRP( $req, $rp, $req->sessionInfo );
$self->logger->debug("Found corresponding user: $user_id"); $self->logger->debug( $user_id
? "Found corresponding user: $user_id"
: 'Corresponding user not found' );
# Generate access_token # Generate access_token
my $accessTokenSession = $self->newAccessToken( my $accessTokenSession = $self->newAccessToken(

View File

@ -3,8 +3,10 @@ package Lemonldap::NG::Portal::Lib::LDAP;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Lib::Net::LDAP; use Lemonldap::NG::Portal::Lib::Net::LDAP;
use Lemonldap::NG::Portal::Main::Constants use Lemonldap::NG::Portal::Main::Constants qw(
qw(PE_OK PE_LDAPCONNECTFAILED PE_LDAPERROR PE_BADCREDENTIALS); PE_OK PE_LDAPCONNECTFAILED
PE_LDAPERROR PE_BADCREDENTIALS
);
extends 'Lemonldap::NG::Common::Module'; extends 'Lemonldap::NG::Common::Module';
@ -149,7 +151,8 @@ sub getUser {
return PE_BADCREDENTIALS; return PE_BADCREDENTIALS;
} }
$req->data->{dn} = $req->data->{ldapentry}->dn(); $req->data->{dn} = $req->data->{ldapentry}->dn();
PE_OK;
return PE_OK;
} }
# Validate LDAP connection before use # Validate LDAP connection before use
@ -169,12 +172,13 @@ sub bind {
$self->validateLdap; $self->validateLdap;
return undef unless $self->ldap; return undef unless $self->ldap;
my $msg = $self->ldap->bind(@_); my $msg = $self->ldap->bind(@_);
if ( $msg->code ) { if ( $msg->code ) {
$self->logger->error( $msg->error ); $self->logger->error( $msg->error );
return undef; return undef;
} }
return 1; return 1;
} }

View File

@ -1349,9 +1349,13 @@ sub buildUserInfoResponse {
my $list = $self->getAttributesListFromClaim( $rp, $claim ); my $list = $self->getAttributesListFromClaim( $rp, $claim );
next unless $list; next unless $list;
foreach my $attribute (@$list) { foreach my $attribute (@$list) {
my $session_key = my @attrConf = split /;/,
$self->conf->{oidcRPMetaDataExportedVars}->{$rp}->{$attribute}; ( $self->conf->{oidcRPMetaDataExportedVars}->{$rp}->{$attribute}
|| "" );
my $session_key = $attrConf[0];
if ($session_key) { if ($session_key) {
my $type = $attrConf[1] || 'string';
my $array = $attrConf[2] || 'auto';
my $session_value; my $session_value;
@ -1366,21 +1370,25 @@ sub buildUserInfoResponse {
$session_value = $session->data->{$session_key}; $session_value = $session->data->{$session_key};
} }
# Convert mutli-valued attributes to arrays # Handle empty values, arrays, type, etc.
my $separator = $self->conf->{multiValuesSeparator}; $session_value =
if ( $session_value and $session_value =~ /$separator/ ) { $self->_formatValue( $session_value, $type, $array,
my @session_array = $attribute, $req->user );
split( $separator, $session_value );
$session_value = \@session_array;
}
# Address is a JSON object # From this point on, do NOT touch $session_value or you will break
if ( $claim eq "address" ) { # the variable's type.
$userinfo_response->{address}->{$attribute} =
$session_value; # Only release claim if it has a value
} if ( defined $session_value ) {
else {
$userinfo_response->{$attribute} = $session_value; # Address is a JSON object
if ( $claim eq "address" ) {
$userinfo_response->{address}->{$attribute} =
$session_value;
}
else {
$userinfo_response->{$attribute} = $session_value;
}
} }
} }
} }
@ -1389,6 +1397,85 @@ sub buildUserInfoResponse {
return $userinfo_response; return $userinfo_response;
} }
sub _formatValue {
my ( $self, $session_value, $type, $array, $attribute, $user ) = @_;
# If $session_value is not a scalar, return it as is
unless ( ref($session_value) ) {
if ( defined $session_value ) {
# Empty strings or lists are invalid values
if ( length($session_value) > 0 ) {
# Format value for JSON output: multi valuation, JSON type...
my $separator = $self->conf->{multiValuesSeparator};
return $self->_applyType( $session_value, $separator, $type,
$array, $attribute, $user );
}
else {
return undef;
}
}
}
return $session_value;
}
sub _applyType {
my ( $self, $session_value, $separator, $type, $array, $attribute, $user )
= @_;
# Array style handling
# In auto array mode, split as array only if there are multiple values
if ( $array eq "auto" ) {
if ( $session_value and $session_value =~ /$separator/ ) {
$session_value = [ map { $self->_forceType( $_, $type ) }
split( $separator, $session_value ) ];
}
else {
$session_value = $self->_forceType( $session_value, $type );
}
# In always array mode, always split (even on empty values)
}
elsif ( $array eq "always" ) {
$session_value = [ map { $self->_forceType( $_, $type ) }
split( $separator, $session_value ) ];
}
# In never array mode, return the string as-is
else {
# No type coaxing is possible on a flattened string
if ( $session_value =~ /$separator/ and $type ne "string" ) {
$self->logger->warn( "Cannot force type of value $session_value"
. " for attribute $attribute of user "
. $user
. " because it is multi-valued. "
. "Use auto or always as array type for this attribute" );
}
else {
$session_value = $self->_forceType( $session_value, $type );
}
}
return $session_value;
}
sub _forceType {
my ( $self, $val, $type ) = @_;
if ( $type eq "bool" ) {
return ( $val ? JSON::true : JSON::false );
}
if ( $type eq "int" ) {
# Coax into int
return ( $val + 0 );
}
# Coax into string
return ( $val . "" );
}
# Return JWT # Return JWT
# @param payload JWT content # @param payload JWT content
# @param alg Signature algorithm # @param alg Signature algorithm

View File

@ -125,8 +125,8 @@ sub _redirect {
? sub { ? sub {
# Restore urldc if auth doesn't need to dial with browser # Restore urldc if auth doesn't need to dial with browser
$self->restoreRequest( $req, $ir ); $self->restoreRequest( $_[0], $ir );
$self->cleanPdata($req); $self->cleanPdata( $_[0] );
return $self->run( @_, @path ); return $self->run( @_, @path );
} }
: () : ()

View File

@ -136,12 +136,12 @@ sub controlUrl {
} }
# Unprotected hosts # Unprotected hosts
my ( $vhost, $appuri ) = $tmp =~ m#^https?://([^/]*)(.*)#; my ( $proto, $vhost, $appuri ) = $tmp =~ m#^(https?://)([^/]*)(.*)#;
$vhost =~ s/:\d+$//; $vhost =~ s/:\d+$//;
# try to resolve alias # Try to resolve alias
my $originalVhost = $self->HANDLER->resolveAlias($vhost); my $originalVhost = $self->HANDLER->resolveAlias($vhost);
$vhost = 'http://' . $originalVhost; $vhost = $proto . $originalVhost;
$self->logger->debug( "Required URL (param: " $self->logger->debug( "Required URL (param: "
. ( $req->param('logout') ? 'HTTP Referer' : 'urldc' ) . ( $req->param('logout') ? 'HTTP Referer' : 'urldc' )
. " | value: $tmp | alias: $vhost)" ); . " | value: $tmp | alias: $vhost)" );

View File

@ -199,8 +199,8 @@ sub refresh {
$self->groupsAndMacros, $self->groupsAndMacros,
'setLocalGroups', 'setLocalGroups',
sub { sub {
$req->sessionInfo->{$_} = $data{$_} foreach ( keys %data ); $_[0]->sessionInfo->{$_} = $data{$_} foreach ( keys %data );
$req->refresh(1); $_[0]->refresh(1);
return PE_OK; return PE_OK;
}, },
'store', 'store',
@ -277,7 +277,7 @@ sub do {
code => 401, code => 401,
headers => [ headers => [
'WWW-Authenticate' => "SSO " . $self->conf->{portal}, 'WWW-Authenticate' => "SSO " . $self->conf->{portal},
"Content-Type" => "application/javascript" "Content-Type" => "application/json"
], ],
); );
} }
@ -1138,6 +1138,18 @@ sub sendJSONresponse {
return $res; return $res;
} }
sub sendRawHtml {
my ($self) = $_[0];
my $res = Lemonldap::NG::Common::PSGI::sendRawHtml(@_);
if ( $self->conf->{corsEnabled} ) {
my @cors = split /;/, $self->cors;
push @{ $res->[1] }, @cors;
$self->logger->debug('Apply following CORS policy :');
$self->logger->debug(" $_") for @cors;
}
return $res;
}
# Temlate loader # Temlate loader
sub loadTemplate { sub loadTemplate {
my ( $self, $req, $name, %prm ) = @_; my ( $self, $req, $name, %prm ) = @_;

View File

@ -3,14 +3,16 @@ package Lemonldap::NG::Portal::Password::AD;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw( use Lemonldap::NG::Portal::Main::Constants qw(
PE_PASSWORD_OK
PE_LDAPERROR
PE_LDAPCONNECTFAILED
PE_ERROR PE_ERROR
PE_LDAPERROR
PE_PASSWORD_OK
PE_LDAPCONNECTFAILED
); );
extends 'Lemonldap::NG::Portal::Lib::LDAP', extends qw(
'Lemonldap::NG::Portal::Password::Base'; Lemonldap::NG::Portal::Lib::LDAP
Lemonldap::NG::Portal::Password::Base
);
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';
@ -55,10 +57,7 @@ sub modifyPassword {
my $code = my $code =
$self->ldap->userModifyPassword( $dn, $pwd, $req->data->{oldpassword}, $self->ldap->userModifyPassword( $dn, $pwd, $req->data->{oldpassword},
1, $requireOldPassword ); 1, $requireOldPassword );
return $code unless ( $code == PE_PASSWORD_OK );
unless ( $code == PE_PASSWORD_OK ) {
return $code;
}
# If force reset, set reset flag # If force reset, set reset flag
if ( $req->data->{forceReset} ) { if ( $req->data->{forceReset} ) {

View File

@ -5,8 +5,8 @@ use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw( use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK PE_OK
PE_BADOLDPASSWORD
PE_PASSWORD_OK PE_PASSWORD_OK
PE_BADOLDPASSWORD
PE_PASSWORD_MISMATCH PE_PASSWORD_MISMATCH
PE_PP_PASSWORD_TOO_SHORT PE_PP_PASSWORD_TOO_SHORT
PE_PP_NOT_ALLOWED_CHARACTER PE_PP_NOT_ALLOWED_CHARACTER

View File

@ -4,8 +4,10 @@ use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(PE_ERROR); use Lemonldap::NG::Portal::Main::Constants qw(PE_ERROR);
extends 'Lemonldap::NG::Portal::Password::Base', extends qw(
'Lemonldap::NG::Portal::Lib::Choice'; Lemonldap::NG::Portal::Lib::Choice
Lemonldap::NG::Portal::Password::Base
);
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';

View File

@ -2,10 +2,15 @@ package Lemonldap::NG::Portal::Password::DBI;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(PE_PASSWORD_OK PE_ERROR); use Lemonldap::NG::Portal::Main::Constants qw(
PE_ERROR
PE_PASSWORD_OK
);
extends 'Lemonldap::NG::Portal::Password::Base', extends qw(
'Lemonldap::NG::Portal::Lib::DBI'; Lemonldap::NG::Portal::Lib::DBI
Lemonldap::NG::Portal::Password::Base
);
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';

View File

@ -3,14 +3,16 @@ package Lemonldap::NG::Portal::Password::LDAP;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw( use Lemonldap::NG::Portal::Main::Constants qw(
PE_PASSWORD_OK
PE_LDAPERROR
PE_LDAPCONNECTFAILED
PE_ERROR PE_ERROR
PE_LDAPERROR
PE_PASSWORD_OK
PE_LDAPCONNECTFAILED
); );
extends 'Lemonldap::NG::Portal::Lib::LDAP', extends qw(
'Lemonldap::NG::Portal::Password::Base'; Lemonldap::NG::Portal::Lib::LDAP
Lemonldap::NG::Portal::Password::Base
);
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';

View File

@ -8,8 +8,10 @@ use Lemonldap::NG::Portal::Main::Constants qw(
PE_PASSWORD_OK PE_PASSWORD_OK
); );
extends 'Lemonldap::NG::Portal::Password::Base', extends qw(
'Lemonldap::NG::Portal::Lib::REST'; Lemonldap::NG::Portal::Lib::REST
Lemonldap::NG::Portal::Password::Base
);
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';

View File

@ -10,7 +10,7 @@ our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Plugin'; extends 'Lemonldap::NG::Portal::Main::Plugin';
use constant afterData => 'adaptAuthenticationLevel'; use constant aroundSub => { 'store' => 'adaptAuthenticationLevel' };
has rules => ( is => 'rw', default => sub { {} } ); has rules => ( is => 'rw', default => sub { {} } );
@ -30,12 +30,12 @@ sub init {
next unless $rule; next unless $rule;
$self->rules->{$_} = $rule; $self->rules->{$_} = $rule;
} }
return 1; return 1;
} }
sub adaptAuthenticationLevel { sub adaptAuthenticationLevel {
my ( $self, $req ) = @_; my ( $self, $sub, $req ) = @_;
my $userid = $req->sessionInfo->{ $self->conf->{whatToTrace} }; my $userid = $req->sessionInfo->{ $self->conf->{whatToTrace} };
$self->logger->debug("Check adaptative authentication rules for $userid"); $self->logger->debug("Check adaptative authentication rules for $userid");
@ -68,16 +68,11 @@ sub adaptAuthenticationLevel {
} }
if ( $authenticationLevel ne $updatedAuthenticationLevel ) { if ( $authenticationLevel ne $updatedAuthenticationLevel ) {
$self->logger->debug( $self->logger->debug("Authentication level has changed for $userid");
"Authentication level has changed for $userid, update session"); $req->sessionInfo->{authenticationLevel} = $updatedAuthenticationLevel;
$self->p->updateSession(
$req,
{
'authenticationLevel' => $updatedAuthenticationLevel
}
);
} }
return PE_OK;
return $sub->($req);
} }
1; 1;

View File

@ -10,34 +10,34 @@ use MIME::Base64;
use POSIX qw(strftime); use POSIX qw(strftime);
use Lemonldap::NG::Common::FormEncode; use Lemonldap::NG::Common::FormEncode;
use Lemonldap::NG::Portal::Main::Constants qw( use Lemonldap::NG::Portal::Main::Constants qw(
PE_BADCREDENTIALS PE_OK
PE_MAILOK
PE_NOTOKEN
PE_MAILERROR
PE_BADMAILTOKEN PE_BADMAILTOKEN
PE_CAPTCHAEMPTY PE_CAPTCHAEMPTY
PE_CAPTCHAERROR PE_CAPTCHAERROR
PE_MAILCONFIRMATION_ALREADY_SENT
PE_MAILCONFIRMOK
PE_MAILERROR
PE_MAILFIRSTACCESS
PE_MAILFORMEMPTY
PE_MAILNOTFOUND PE_MAILNOTFOUND
PE_MAILOK
PE_MALFORMEDUSER
PE_NOTOKEN
PE_OK
PE_PASSWORDFIRSTACCESS
PE_PASSWORDFORMEMPTY
PE_PASSWORD_OK
PE_TOKENEXPIRED PE_TOKENEXPIRED
PE_USERNOTFOUND PE_USERNOTFOUND
PE_MAILCONFIRMOK
PE_MAILFORMEMPTY
PE_MALFORMEDUSER
PE_BADCREDENTIALS
PE_MAILFIRSTACCESS
PE_RESETCERTIFICATE_INVALID PE_RESETCERTIFICATE_INVALID
PE_RESETCERTIFICATE_FORMEMPTY PE_RESETCERTIFICATE_FORMEMPTY
PE_RESETCERTIFICATE_FIRSTACCESS PE_RESETCERTIFICATE_FIRSTACCESS
PE_MAILCONFIRMATION_ALREADY_SENT
); );
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Plugin', extends qw(
'Lemonldap::NG::Portal::Lib::SMTP', 'Lemonldap::NG::Portal::Lib::_tokenRule'; Lemonldap::NG::Portal::Lib::SMTP
Lemonldap::NG::Portal::Main::Plugin
Lemonldap::NG::Portal::Lib::_tokenRule
);
# PROPERTIES # PROPERTIES
@ -107,7 +107,7 @@ sub init {
'::CertificateResetByMail::' . $self->conf->{registerDB} '::CertificateResetByMail::' . $self->conf->{registerDB}
) )
) or return 0; ) or return 0;
return 1; return 1;
} }

View File

@ -3,8 +3,8 @@ package Lemonldap::NG::Portal::Plugins::DecryptValue;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw( use Lemonldap::NG::Portal::Main::Constants qw(
PE_TOKENEXPIRED
PE_NOTOKEN PE_NOTOKEN
PE_TOKENEXPIRED
PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED
); );

View File

@ -11,9 +11,9 @@ use Lemonldap::NG::Portal::Main::Constants qw(
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';
extends qw( extends qw(
Lemonldap::NG::Portal::Main::Plugin Lemonldap::NG::Portal::Main::Plugin
Lemonldap::NG::Portal::Lib::_tokenRule Lemonldap::NG::Portal::Lib::_tokenRule
); );
# INITIALIZATION # INITIALIZATION

View File

@ -2,6 +2,7 @@ package Lemonldap::NG::Portal::Plugins::Refresh;
use strict; use strict;
use Mouse; use Mouse;
use JSON;
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';
@ -35,9 +36,26 @@ sub run {
); );
$req->id($id); $req->id($id);
$req->user( $info->{uid} ); $req->user( $info->{uid} );
eval { $self->p->refresh($req); }; my $res;
$self->logger->debug("Refresh: $@") if $@; eval { $res = $self->p->refresh($req); };
$c++; if ($@) {
$self->logger->error("Refresh: $@");
next;
}
if ( ref($res) ne "ARRAY" ) {
$self->logger->error("Refresh failed for session $id");
next;
}
my $refreshJSON = $res->[2]->[0];
$self->logger->debug("Refresh result: $refreshJSON");
my $refreshHASH = from_json($refreshJSON);
if ( $refreshHASH->{error} == 0 ) {
$self->logger->notice("Refresh succeed for session $id");
$c++;
}
else {
$self->logger->error("Refresh failed for session $id");
}
} }
$req->userData( {} ); $req->userData( {} );
$req->$_(undef) foreach (qw(user id)); $req->$_(undef) foreach (qw(user id));

View File

@ -2,7 +2,6 @@
package Lemonldap::NG::Portal::Plugins::StayConnected; package Lemonldap::NG::Portal::Plugins::StayConnected;
use 5.16.0;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw( use Lemonldap::NG::Portal::Main::Constants qw(
@ -32,13 +31,20 @@ has ott => (
return $ott; return $ott;
} }
); );
has cookieName => (
is => 'rw',
lazy => 1,
default => sub {
$_[0]->{conf}->{stayConnectedCookieName} || 'llngconnection';
}
);
# Default timeout: 1 month # Default timeout: 1 month
has timeout => ( has timeout => (
is => 'rw', is => 'rw',
lazy => 1, lazy => 1,
default => sub { default => sub {
$_[0]->{conf}->{stayConnectedTimeout} || 2678400; $_[0]->{conf}->{stayConnectedTimeout} || 2592000;
} }
); );
@ -51,8 +57,8 @@ sub init {
# RUNNING METHODS # RUNNING METHODS
# Registration: detect if user wants to stay connected. Then ask for # Registration: detect if user wants to stay connected.
# fingerprint # Then ask for browser fingerprint
sub newDevice { sub newDevice {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
@ -102,7 +108,7 @@ sub storeBrowser {
$self->conf->{globalStorageOptions}, $self->conf->{globalStorageOptions},
kind => "SSO", kind => "SSO",
info => { info => {
_utime => time + $self->timeout, _utime => time + $self->timeout(),
_session_uid => $uid, _session_uid => $uid,
_connectedSince => time, _connectedSince => time,
dataKeep => $req->data->{dataToKeep}, dataKeep => $req->data->{dataToKeep},
@ -113,13 +119,14 @@ sub storeBrowser {
# Cookie available 30 days # Cookie available 30 days
$req->addCookie( $req->addCookie(
$self->p->cookie( $self->p->cookie(
name => 'llngconnexion', name => $self->cookieName(),
value => $ps->id, value => $ps->id,
max_age => 2592000, max_age => $self->timeout(),
secure => $self->conf->{securedCookie}, secure => $self->conf->{securedCookie},
) )
); );
$req->sessionInfo->{_loginHistory} = $tmp->{history} if exists $tmp->{history}; $req->sessionInfo->{_loginHistory} = $tmp->{history}
if exists $tmp->{history};
} }
else { else {
$self->logger->warn("Browser hasn't return fingerprint"); $self->logger->warn("Browser hasn't return fingerprint");
@ -139,7 +146,7 @@ sub storeBrowser {
$self->userLogger->error('StayConnected called without token'); $self->userLogger->error('StayConnected called without token');
} }
# Return cookie llngconnexion # Return persistent connection cookie
return $self->p->do( $req, [ @{ $self->p->endAuth }, sub { PE_OK } ] ); return $self->p->do( $req, [ @{ $self->p->endAuth }, sub { PE_OK } ] );
} }
@ -150,14 +157,17 @@ sub storeBrowser {
# Then delete authentication methods from "steps" array. # Then delete authentication methods from "steps" array.
sub check { sub check {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
if ( my $cid = $req->cookies->{llngconnexion} ) { if ( my $cid = $req->cookies->{ $self->cookieName() } ) {
my $ps = Lemonldap::NG::Common::Session->new( my $ps = Lemonldap::NG::Common::Session->new(
storageModule => $self->conf->{globalStorage}, storageModule => $self->conf->{globalStorage},
storageModuleOptions => $self->conf->{globalStorageOptions}, storageModuleOptions => $self->conf->{globalStorageOptions},
kind => "SSO", kind => "SSO",
id => $cid, id => $cid,
); );
if ( $ps and my $uid = $ps->data->{_session_uid} ) { if ( $ps
and my $uid = $ps->data->{_session_uid}
and time() < $ps->data->{_utime} )
{
$self->logger->debug('Persistent connection found'); $self->logger->debug('Persistent connection found');
if ( my $fg = $req->param('fg') if ( my $fg = $req->param('fg')
and my $token = $req->param('token') ) and my $token = $req->param('token') )
@ -179,6 +189,8 @@ sub check {
} }
else { else {
$self->userLogger->warn("Fingerprint changed for $uid"); $self->userLogger->warn("Fingerprint changed for $uid");
$ps->remove;
$self->logout($req);
} }
} }
else { else {
@ -203,6 +215,13 @@ sub check {
} }
else { else {
$self->userLogger->notice('Persistent connection expired'); $self->userLogger->notice('Persistent connection expired');
unless ( $ps->{error} ) {
$self->logger->debug(
'Persistent connection session id = ' . $ps->{id} );
$self->logger->debug( 'Persistent connection session _utime = '
. $ps->data->{_utime} );
$ps->remove;
}
} }
} }
return PE_OK; return PE_OK;
@ -212,7 +231,7 @@ sub logout {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
$req->addCookie( $req->addCookie(
$self->p->cookie( $self->p->cookie(
name => 'llngconnexion', name => $self->cookieName(),
value => 0, value => 0,
expires => 'Wed, 21 Oct 2015 00:00:00 GMT', expires => 'Wed, 21 Oct 2015 00:00:00 GMT',
secure => $self->conf->{securedCookie}, secure => $self->conf->{securedCookie},

View File

@ -3,8 +3,8 @@ package Lemonldap::NG::Portal::Register::AD;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw( use Lemonldap::NG::Portal::Main::Constants qw(
PE_LDAPERROR
PE_OK PE_OK
PE_LDAPERROR
); );
extends 'Lemonldap::NG::Portal::Register::LDAP'; extends 'Lemonldap::NG::Portal::Register::LDAP';

View File

@ -30,7 +30,9 @@ sub applyLoginRule {
lc $self->_stripaccents( $req->data->{registerInfo}->{lastname} ); lc $self->_stripaccents( $req->data->{registerInfo}->{lastname} );
# For now, get first letter of firstname and lastname # For now, get first letter of firstname and lastname
return substr( $firstname, 0, 1 ) . $lastname; my $login = substr( $firstname, 0, 1 ) . $lastname;
$login =~ s/\s*//g;
return $login;
} }
1; 1;

View File

@ -2,7 +2,10 @@ package Lemonldap::NG::Portal::Register::Demo;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw(PE_OK PE_MALFORMEDUSER); use Lemonldap::NG::Portal::Main::Constants qw(
PE_OK
PE_MALFORMEDUSER
);
extends 'Lemonldap::NG::Portal::Register::Base'; extends 'Lemonldap::NG::Portal::Register::Base';

View File

@ -3,14 +3,16 @@ package Lemonldap::NG::Portal::Register::LDAP;
use strict; use strict;
use Mouse; use Mouse;
use Lemonldap::NG::Portal::Main::Constants qw( use Lemonldap::NG::Portal::Main::Constants qw(
PE_LDAPCONNECTFAILED
PE_LDAPERROR
PE_OK PE_OK
PE_LDAPERROR
PE_MALFORMEDUSER PE_MALFORMEDUSER
PE_LDAPCONNECTFAILED
); );
extends 'Lemonldap::NG::Portal::Lib::LDAP', extends qw(
'Lemonldap::NG::Portal::Register::Base'; Lemonldap::NG::Portal::Lib::LDAP
Lemonldap::NG::Portal::Register::Base
);
our $VERSION = '2.1.0'; our $VERSION = '2.1.0';
@ -24,10 +26,7 @@ sub computeLogin {
# Get first letter of firstname and lastname # Get first letter of firstname and lastname
my $login = $self->applyLoginRule($req); my $login = $self->applyLoginRule($req);
return PE_MALFORMEDUSER unless $login;
unless ($login) {
return PE_MALFORMEDUSER;
}
my $finalLogin = $login; my $finalLogin = $login;

View File

@ -1 +1 @@
(function(){var r,e,n,t,o;n=function(e,r){return $("#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),n(o,"warning")},t="",e=function(e){return n("yourTotpKey","warning"),$.ajax({type:"POST",url:portal+"/2fregisters/totp/getkey",dataType:"json",data:{newkey:e},error:r,success:function(e){var r;return e.error?(e.error.match(/totpExistingKey/)&&$("#divToHide").hide(),n(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}),$("#serialized").text(r),e.newkey?n("yourNewTotpKey","warning"):n("yourTotpKey","success"),t=e.token):n("PE24","danger")}})},o=function(){var e;return(e=$("#code").val())?$.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)/)?n(e.error,"warning"):n(e.error,"danger"):n("yourKeyIsRegistered","success")}}):n("fillTheForm","warning")},$(document).ready(function(){return e(0),$("#changekey").on("click",function(){return e(1)}),$("#verify").on("click",function(){return o()})})}).call(this); (function(){var o=function(e,r){return $("#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(e){return o("yourTotpKey","warning"),$.ajax({type:"POST",url:portal+"/2fregisters/totp/getkey",dataType:"json",data:{newkey:e},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}),$("#serialized").text(r),e.newkey?o("yourNewTotpKey","warning"):o("yourTotpKey","success"),t=e.token):o("PE24","danger")}})},n=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("fillTheForm","warning")};$(document).ready(function(){return e(0),$("#changekey").on("click",function(){return e(1)}),$("#verify").on("click",n)})}).call(this);

View File

@ -1 +1 @@
{"version":3,"sources":["totpregistration.js"],"names":["displayError","getKey","setMsg","token","verify","msg","level","$","html","window","translate","removeClass","addClass","j","status","err","res","console","log","JSON","parse","responseText","error","replace","reset","ajax","type","url","portal","dataType","data","newkey","success","s","match","hide","user","secret","show","escape","digits","interval","QRious","element","document","getElementById","value","size","text","val","code","TOTPName","ready","on","call","this"],"mappings":"CAMA,WACE,IAAIA,EAAcC,EAAQC,EAAQC,EAAOC,EAEzCF,EAAS,SAASG,EAAKC,GAOrB,OANAC,EAAE,QAAQC,KAAKC,OAAOC,UAAUL,IAChCE,EAAE,UAAUI,YAAY,4FACxBJ,EAAE,UAAUK,SAAS,WAAaN,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUK,SAAS,SAAWN,IAGzCN,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,YAIvBb,EAAQ,GAERF,EAAS,SAASuB,GAEhB,OADAtB,EAAO,cAAe,WACfK,EAAEkB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVC,KAAM,CACJC,OAAQP,GAEVF,MAAOtB,EACPgC,QAAS,SAASF,GAChB,IAAQG,EACR,OAAIH,EAAKR,OACHQ,EAAKR,MAAMY,MAAM,oBACnB3B,EAAE,cAAc4B,OAEXjC,EAAO4B,EAAKR,MAAO,YAEtBQ,EAAKF,QAAUE,EAAKM,MAAQN,EAAKO,QAGvC9B,EAAE,cAAc+B,OAChBL,EAAI,kBAAqBM,OAAOT,EAAKF,QAAW,IAAOW,OAAOT,EAAKM,MAAS,WAAaN,EAAKO,OAAS,WAAcE,OAAOT,EAAKF,QAC7G,IAAhBE,EAAKU,SACPP,GAAK,WAAaH,EAAKU,QAEH,KAAlBV,EAAKW,WACPR,GAAK,WAAaH,EAAKW,UAEpB,IAAIC,OAAO,CACdC,QAASC,SAASC,eAAe,MACjCC,MAAOb,EACPc,KAAM,MAERxC,EAAE,eAAeyC,KAAKf,GAClBH,EAAKC,OACP7B,EAAO,iBAAkB,WAEzBA,EAAO,cAAe,WAEjBC,EAAQ2B,EAAK3B,OArBXD,EAAO,OAAQ,cA0B9BE,EAAS,WACP,IAAI6C,EAEJ,OADAA,EAAM1C,EAAE,SAAS0C,OAIR1C,EAAEkB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVC,KAAM,CACJ3B,MAAOA,EACP+C,KAAMD,EACNE,SAAU5C,EAAE,aAAa0C,OAE3B3B,MAAOtB,EACPgC,QAAS,SAASF,GAChB,OAAIA,EAAKR,MACHQ,EAAKR,MAAMY,MAAM,kBACZhC,EAAO4B,EAAKR,MAAO,WAEnBpB,EAAO4B,EAAKR,MAAO,UAGrBpB,EAAO,sBAAuB,cApBpCA,EAAO,cAAe,YA2BjCK,EAAEqC,UAAUQ,MAAM,WAKhB,OAJAnD,EAAO,GACPM,EAAE,cAAc8C,GAAG,QAAS,WAC1B,OAAOpD,EAAO,KAETM,EAAE,WAAW8C,GAAG,QAAS,WAC9B,OAAOjD,UAIVkD,KAAKC"} {"version":3,"sources":["totpregistration.js"],"names":["setMsg","msg","level","$","html","window","translate","removeClass","addClass","displayError","j","status","err","console","log","res","JSON","parse","responseText","error","replace","token","getKey","reset","ajax","type","url","portal","dataType","data","newkey","success","s","match","hide","user","secret","show","escape","digits","interval","QRious","element","document","getElementById","value","size","text","verify","val","code","TOTPName","ready","on","call","this"],"mappings":"CAMA,WACE,IAEAA,EAAS,SAASC,EAAKC,GAOrB,OANAC,EAAE,QAAQC,KAAKC,OAAOC,UAAUL,IAChCE,EAAE,UAAUI,YAAY,4FACxBJ,EAAE,UAAUK,SAAS,WAAaN,GACpB,aAAVA,IACFA,EAAQ,WAEHC,EAAE,UAAUK,SAAS,SAAWN,IAGzCO,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,GACvBf,EAAOe,EAAK,YAIvBM,EAAQ,GAERC,EAAS,SAASC,GAEhB,OADAvB,EAAO,cAAe,WACfG,EAAEqB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVC,KAAM,CACJC,OAAQP,GAEVJ,MAAOV,EACPsB,QAAS,SAASF,GAChB,IAAQG,EACR,OAAIH,EAAKV,OACHU,EAAKV,MAAMc,MAAM,oBACnB9B,EAAE,cAAc+B,OAEXlC,EAAO6B,EAAKV,MAAO,YAEtBU,EAAKF,QAAUE,EAAKM,MAAQN,EAAKO,QAGvCjC,EAAE,cAAckC,OAChBL,EAAI,kBAAqBM,OAAOT,EAAKF,QAAW,IAAOW,OAAOT,EAAKM,MAAS,WAAaN,EAAKO,OAAS,WAAcE,OAAOT,EAAKF,QAC7G,IAAhBE,EAAKU,SACPP,GAAK,WAAaH,EAAKU,QAEH,KAAlBV,EAAKW,WACPR,GAAK,WAAaH,EAAKW,UAEpB,IAAIC,OAAO,CACdC,QAASC,SAASC,eAAe,MACjCC,MAAOb,EACPc,KAAM,MAER3C,EAAE,eAAe4C,KAAKf,GAClBH,EAAKC,OACP9B,EAAO,iBAAkB,WAEzBA,EAAO,cAAe,WAEjBqB,EAAQQ,EAAKR,OArBXrB,EAAO,OAAQ,cA0B9BgD,EAAS,WACP,IACAC,EAAM9C,EAAE,SAAS8C,MACjB,OAAKA,EAGI9C,EAAEqB,KAAK,CACZC,KAAM,OACNC,IAAKC,OAAS,2BACdC,SAAU,OACVC,KAAM,CACJR,MAAOA,EACP6B,KAAMD,EACNE,SAAUhD,EAAE,aAAa8C,OAE3B9B,MAAOV,EACPsB,QAAS,SAASF,GAChB,OAAIA,EAAKV,MACHU,EAAKV,MAAMc,MAAM,kBACZjC,EAAO6B,EAAKV,MAAO,WAEnBnB,EAAO6B,EAAKV,MAAO,UAGrBnB,EAAO,sBAAuB,cApBpCA,EAAO,cAAe,YA2BjCG,EAAEwC,UAAUS,MAAM,WAKhB,OAJA9B,EAAO,GACPnB,EAAE,cAAckD,GAAG,QAAS,WAC1B,OAAO/B,EAAO,KAETnB,EAAE,WAAWkD,GAAG,QACdL,OAIVM,KAAKC"}

View File

@ -89,7 +89,7 @@
<div class="input-group mb-3"> <div class="input-group mb-3">
<div class="input-group-prepend"> <div class="input-group-prepend">
<div class="input-group-text"> <div class="input-group-text">
<input id="resendconfirmation" type="checkbox" name="resendconfirmation" ariadescribedby="resendconfirmationlabel"> <input class="form-check-input" id="resendconfirmation" type="checkbox" name="resendconfirmation" ariadescribedby="resendconfirmationlabel">
</div> </div>
</div> </div>
<p class="form-control"> <p class="form-control">

View File

@ -12,7 +12,7 @@
<TMPL_LOOP NAME="check"> <TMPL_LOOP NAME="check">
<p class="notifCheck"> <p class="notifCheck">
<div class="form-group form-check"> <div class="form-group form-check">
<input type="checkbox" name="check<TMPL_VAR NAME="id">" id="<TMPL_VAR NAME="id">" value="accepted"/> <input class="form-check-input" type="checkbox" name="check<TMPL_VAR NAME="id">" id="<TMPL_VAR NAME="id">" value="accepted"/>
<label class="form-check-label" for="<TMPL_VAR NAME="id">"><TMPL_VAR NAME="value"></label> <label class="form-check-label" for="<TMPL_VAR NAME="id">"><TMPL_VAR NAME="value"></label>
</div> </div>
</p> </p>

View File

@ -15,6 +15,8 @@ my $client = LLNG::Manager::Test->new( {
cspFormAction => '*', cspFormAction => '*',
cspFrameAncestors => 'test.example.com', cspFrameAncestors => 'test.example.com',
customToTrace => 'mail', customToTrace => 'mail',
checkStateSecret => 'x',
checkState => 1,
} }
} }
); );
@ -38,6 +40,12 @@ ok(
count(1); count(1);
expectReject($res); expectReject($res);
# sendError (#2380)
ok( $res = $client->_get( '/checkstate', accept => 'text/html' ),
'Get error page' );
count(1);
checkCorsPolicy($res);
ok( $res = $client->_options( '/', accept => 'text/html' ), 'Get Menu' ); ok( $res = $client->_options( '/', accept => 'text/html' ), 'Get Menu' );
count(1); count(1);

View File

@ -7,7 +7,7 @@ require 't/test-lib.pm';
use lib 't/lib'; use lib 't/lib';
my $res; my $res;
my $maintests = 26; my $maintests = 32;
SKIP: { SKIP: {
skip( 'LLNGTESTLDAP is not set', $maintests ) unless ( $ENV{LLNGTESTLDAP} ); skip( 'LLNGTESTLDAP is not set', $maintests ) unless ( $ENV{LLNGTESTLDAP} );
@ -22,6 +22,7 @@ SKIP: {
userDB => 'Same', userDB => 'Same',
passwordDB => 'LDAP', passwordDB => 'LDAP',
portalRequireOldPassword => 1, portalRequireOldPassword => 1,
hideOldPassword => 1,
ldapServer => 'ldap://127.0.0.1:19389/', ldapServer => 'ldap://127.0.0.1:19389/',
ldapBase => 'ou=users,dc=example,dc=com', ldapBase => 'ou=users,dc=example,dc=com',
managerDn => 'cn=lemonldapng,ou=dsa,dc=example,dc=com', managerDn => 'cn=lemonldapng,ou=dsa,dc=example,dc=com',
@ -35,12 +36,21 @@ SKIP: {
passwordPolicyMinDigit => 1, passwordPolicyMinDigit => 1,
passwordPolicyMinSpeChar => 1, passwordPolicyMinSpeChar => 1,
passwordPolicySpecialChar => '# &', passwordPolicySpecialChar => '# &',
whatToTrace => 'uid',
macros => {
_whatToTrace => '' # Test 2377
},
} }
} }
); );
use Lemonldap::NG::Portal::Main::Constants 'PE_PP_CHANGE_AFTER_RESET', use Lemonldap::NG::Portal::Main::Constants qw(
'PE_PP_PASSWORD_EXPIRED', 'PE_PASSWORD_OK', 'PE_PP_ACCOUNT_LOCKED', PE_PP_GRACE
'PE_PP_PASSWORD_TOO_SHORT', 'PE_PP_GRACE'; PE_PASSWORD_OK
PE_PP_ACCOUNT_LOCKED
PE_PP_PASSWORD_EXPIRED
PE_PP_PASSWORD_TOO_SHORT
PE_PP_CHANGE_AFTER_RESET
);
my ( $user, $code, $postString, $match ); my ( $user, $code, $postString, $match );
@ -74,13 +84,31 @@ SKIP: {
my ( $host, $url, $query ) = my ( $host, $url, $query ) =
expectForm( $res, '#', undef, 'user', 'oldpassword', 'newpassword', expectForm( $res, '#', undef, 'user', 'oldpassword', 'newpassword',
'confirmpassword' ); 'confirmpassword' );
ok(
$res->[2]->[0] =~
m%<input name="user" type="hidden" value="$user" />%,
' Hidden user input found'
) or print STDERR Dumper( $res->[2]->[0], 'Hidden user input' );
ok(
$res->[2]->[0] =~
m%<input id="oldpassword" name="oldpassword" type="hidden" value="$user" aria-required="true">%,
' Hidden oldpassword input found'
)
or print STDERR Dumper( $res->[2]->[0], 'Hidden oldpassword input' );
ok(
$res->[2]->[0] =~
m%<input id="staticUser" type="text" readonly class="form-control" value="$user" />%,
' staticUser found'
) or print STDERR Dumper( $res->[2]->[0], 'staticUser' );
ok( $res->[2]->[0] !~ m%<span trspan="passwordPolicyMinSize">%, ok( $res->[2]->[0] !~ m%<span trspan="passwordPolicyMinSize">%,
' passwordPolicyMinSize' ) ' passwordPolicyMinSize' )
or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinSize' ); or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinSize' );
ok( $query =~ /user=$user/, "User is $user" ) ok( $query =~ /user=$user/, "User is $user" )
or explain( $query, "user=$user" ); or explain( $query, "user=$user" );
$query =~ s/(oldpassword)=/$1=$user/g;
#$query =~ s/(oldpassword)=$user/$1=$user/g; -> Now old password is defined #2377
$query =~ s/((?:confirm|new)password)=/$1=newp/g; $query =~ s/((?:confirm|new)password)=/$1=newp/g;
ok( ok(
$res = $client->_post( $res = $client->_post(
'/', IO::String->new($query), '/', IO::String->new($query),

View File

@ -7,7 +7,7 @@ require 't/test-lib.pm';
use lib 't/lib'; use lib 't/lib';
my $res; my $res;
my $maintests = 36; my $maintests = 42;
SKIP: { SKIP: {
skip( 'LLNGTESTLDAP is not set', $maintests ) unless ( $ENV{LLNGTESTLDAP} ); skip( 'LLNGTESTLDAP is not set', $maintests ) unless ( $ENV{LLNGTESTLDAP} );
@ -34,13 +34,21 @@ SKIP: {
passwordPolicyMinDigit => 1, passwordPolicyMinDigit => 1,
passwordPolicyMinSpeChar => 1, passwordPolicyMinSpeChar => 1,
passwordPolicySpecialChar => '__ALL__', passwordPolicySpecialChar => '__ALL__',
portalDisplayPasswordPolicy => 1 portalDisplayPasswordPolicy => 1,
whatToTrace => 'uid',
macros => {
_whatToTrace => '' # Test 2377
},
} }
} }
); );
use Lemonldap::NG::Portal::Main::Constants 'PE_PP_CHANGE_AFTER_RESET', use Lemonldap::NG::Portal::Main::Constants qw(
'PE_PP_PASSWORD_EXPIRED', 'PE_PASSWORD_OK', 'PE_PP_ACCOUNT_LOCKED', PE_PASSWORD_OK
'PE_PP_PASSWORD_TOO_SHORT', 'PE_PP_GRACE'; PE_PP_ACCOUNT_LOCKED
PE_PP_PASSWORD_EXPIRED
PE_PP_CHANGE_AFTER_RESET
PE_PP_PASSWORD_TOO_SHORT PE_PP_GRACE
);
my ( $user, $code, $postString, $match ); my ( $user, $code, $postString, $match );
@ -74,6 +82,21 @@ SKIP: {
my ( $host, $url, $query ) = my ( $host, $url, $query ) =
expectForm( $res, '#', undef, 'user', 'oldpassword', 'newpassword', expectForm( $res, '#', undef, 'user', 'oldpassword', 'newpassword',
'confirmpassword' ); 'confirmpassword' );
ok(
$res->[2]->[0] =~
m%<input name="user" type="hidden" value="$user" />%,
' Hidden user input found'
) or print STDERR Dumper( $res->[2]->[0], 'Hidden user input' );
ok(
$res->[2]->[0] =~
m%<input id="oldpassword" name="oldpassword" type="password" value="$user"%,
' oldpassword input found'
) or print STDERR Dumper( $res->[2]->[0], 'oldpassword input' );
ok(
$res->[2]->[0] =~
m%<input id="staticUser" type="text" readonly class="form-control" value="$user" />%,
' staticUser found'
) or print STDERR Dumper( $res->[2]->[0], 'staticUser' );
ok( $res->[2]->[0] =~ m%<span trspan="passwordPolicyMinSize">%, ok( $res->[2]->[0] =~ m%<span trspan="passwordPolicyMinSize">%,
' passwordPolicyMinSize' ) ' passwordPolicyMinSize' )
or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinSize' ); or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinSize' );
@ -94,8 +117,10 @@ SKIP: {
or print STDERR Dumper( $res->[2]->[0], 'passwordPolicySpecialChar' ); or print STDERR Dumper( $res->[2]->[0], 'passwordPolicySpecialChar' );
ok( $query =~ /user=$user/, "User is $user" ) ok( $query =~ /user=$user/, "User is $user" )
or explain( $query, "user=$user" ); or explain( $query, "user=$user" );
$query =~ s/(oldpassword)=/$1=$user/g;
#$query =~ s/(oldpassword)=/$1=$user/g; -> Now old password is defined #2377
$query =~ s/((?:confirm|new)password)=/$1=Newp1@/g; $query =~ s/((?:confirm|new)password)=/$1=Newp1@/g;
ok( ok(
$res = $client->_post( $res = $client->_post(
'/', IO::String->new($query), '/', IO::String->new($query),

View File

@ -6,7 +6,7 @@ BEGIN {
eval "use GSSAPI"; eval "use GSSAPI";
} }
my $maintests = 12; my $maintests = 14;
my $debug = 'error'; my $debug = 'error';
SKIP: { SKIP: {
@ -103,7 +103,58 @@ SKIP: {
" Make sure no pdata is returned" " Make sure no pdata is returned"
); );
#print STDERR Dumper($res); # Test krbAllowedDomains
&Lemonldap::NG::Handler::Main::cfgNum( 0, 0 );
$client = LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
useSafeJail => 1,
authentication => 'Kerberos',
userDB => 'Null',
krbKeytab => '/etc/keytab',
krbByJs => 1,
krbAuthnLevel => 4,
krbAllowedDomains => 'toto.com titi.com',
}
}
);
ok(
$res = $client->_get(
'/',
query => 'kerberos=1',
accept => 'application/json',
custom => { HTTP_AUTHORIZATION => 'Negotiate c29tZXRoaW5n' },
cookie => "lemonldappdata=$pdata"
),
'Push fake kerberos in blacklisted domain'
);
expectReject( $res, 401, 5, "Rejected because the domain is wrong" );
&Lemonldap::NG::Handler::Main::cfgNum( 0, 0 );
$client = LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
useSafeJail => 1,
authentication => 'Kerberos',
userDB => 'Null',
krbKeytab => '/etc/keytab',
krbByJs => 1,
krbAuthnLevel => 4,
krbAllowedDomains => 'toto.com example.com',
}
}
);
ok(
$res = $client->_get(
'/',
query => 'kerberos=1',
accept => 'application/json',
custom => { HTTP_AUTHORIZATION => 'Negotiate c29tZXRoaW5n' },
cookie => "lemonldappdata=$pdata"
),
'Push fake kerberos in an allowed domain'
);
my $id = expectCookie($res);
} }
count($maintests); count($maintests);
@ -123,6 +174,6 @@ package LLNG::GSSR;
sub display { sub display {
my $a = \@_; my $a = \@_;
$a->[1] = 'dwho'; $a->[1] = 'dwho@EXAMPLE.COM';
return 1; return 1;
} }

View File

@ -14,7 +14,7 @@ BEGIN {
my $debug = 'error'; my $debug = 'error';
my ( $issuer, $res ); my ( $issuer, $res );
my $maintests = 7; my $maintests = 8;
SKIP: { SKIP: {
eval "use Lasso"; eval "use Lasso";
@ -67,6 +67,12 @@ SKIP: {
{ {
is( $value->textContent, 'Accents', 'Check Attribute' ); is( $value->textContent, 'Accents', 'Check Attribute' );
} }
foreach my $value (
$xpc->findnodes('//saml:Attribute[@Name="planet"]/saml:AttributeValue')
)
{
is( $value->textContent, 'Earth', 'Check Attribute' );
}
foreach my $value ( $xpc->findnodes('//saml:NameID') ) { foreach my $value ( $xpc->findnodes('//saml:NameID') ) {
is( $value->textContent, 'customfrench', 'Check NameID from macro' ); is( $value->textContent, 'customfrench', 'Check NameID from macro' );
} }
@ -89,6 +95,7 @@ sub issuer {
'sp.com' => { 'sp.com' => {
extracted_sn => '(split(/\s/, $cn))[1]', extracted_sn => '(split(/\s/, $cn))[1]',
customnameid => '"custom".$uid', customnameid => '"custom".$uid',
planet => 'inGroup("earthlings") ? "Earth" : "UNKNOWN"',
} }
}, },
samlSPMetaDataOptions => { samlSPMetaDataOptions => {
@ -110,6 +117,8 @@ sub issuer {
'1;sn;urn:oasis:names:tc:SAML:2.0:attrname-format:basic', '1;sn;urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
uid => uid =>
'1;uid;urn:oasis:names:tc:SAML:2.0:attrname-format:basic', '1;uid;urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
planet =>
'1;planet;urn:oasis:names:tc:SAML:2.0:attrname-format:basic',
} }
}, },
samlOrganizationDisplayName => "IDP", samlOrganizationDisplayName => "IDP",

View File

@ -0,0 +1,79 @@
use Test::More;
use strict;
use IO::String;
use MIME::Base64;
use JSON qw/to_json/;
require 't/test-lib.pm';
my $res;
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
useSafeJail => 1,
issuerDBOpenIDConnectActivation => 1,
multiValuesSeparator => ";"
}
}
);
my $oidc =
$client->p->loadedModules->{'Lemonldap::NG::Portal::Issuer::OpenIDConnect'};
my $tests = [
# Auto array
[ [ undef, "string", "auto" ], '{"key":null}' ],
[ [ "", "string", "auto" ], '{"key":null}' ],
[ [ "foo", "string", "auto" ], '{"key":"foo"}' ],
[ [ "foo;bar", "string", "auto" ], '{"key":["foo","bar"]}' ],
[ [ undef, "int", "auto" ], '{"key":null}' ],
[ [ "", "int", "auto" ], '{"key":null}' ],
[ [ "0", "int", "auto" ], '{"key":0}' ],
[ [ "0;1;2;3", "int", "auto" ], '{"key":[0,1,2,3]}' ],
[ [ undef, "bool", "auto" ], '{"key":null}' ],
[ [ "", "bool", "auto" ], '{"key":null}' ],
[ [ "0", "bool", "auto" ], '{"key":false}' ],
[ [ "1", "bool", "auto" ], '{"key":true}' ],
[ [ "0;1;;3", "bool", "auto" ], '{"key":[false,true,false,true]}' ],
# Always array
[ [ undef, "string", "always" ], '{"key":null}' ],
[ [ "", "string", "always" ], '{"key":null}' ],
[ [ "foo", "string", "always" ], '{"key":["foo"]}' ],
[ [ "foo;bar", "string", "always" ], '{"key":["foo","bar"]}' ],
[ [ undef, "int", "always" ], '{"key":null}' ],
[ [ "", "int", "always" ], '{"key":null}' ],
[ [ "0", "int", "always" ], '{"key":[0]}' ],
[ [ "0;1;2;3", "int", "always" ], '{"key":[0,1,2,3]}' ],
[ [ undef, "bool", "always" ], '{"key":null}' ],
[ [ "", "bool", "always" ], '{"key":null}' ],
[ [ "0", "bool", "always" ], '{"key":[false]}' ],
[ [ "1", "bool", "always" ], '{"key":[true]}' ],
[ [ "0;1;;3", "bool", "always" ], '{"key":[false,true,false,true]}' ],
# Never array
[ [ undef, "string", "never" ], '{"key":null}' ],
[ [ "", "string", "never" ], '{"key":null}' ],
[ [ "foo", "string", "never" ], '{"key":"foo"}' ],
[ [ "foo;bar", "string", "never" ], '{"key":"foo;bar"}' ],
[ [ undef, "int", "never" ], '{"key":null}' ],
[ [ "", "int", "never" ], '{"key":null}' ],
[ [ "0", "int", "never" ], '{"key":0}' ],
[ [ "0;1;2;3", "int", "never" ], '{"key":"0;1;2;3"}' ],
[ [ undef, "bool", "never" ], '{"key":null}' ],
[ [ "", "bool", "never" ], '{"key":null}' ],
[ [ "0", "bool", "never" ], '{"key":false}' ],
[ [ "1", "bool", "never" ], '{"key":true}' ],
[ [ "0;1;;3", "bool", "never" ], '{"key":"0;1;;3"}' ],
];
for my $test ( @{$tests} ) {
my @args = @{ $test->[0] };
my $expect = $test->[1];
is( to_json( { key => $oidc->_formatValue( @args, "key", "foo" ) } ),
$expect, "_formatvalue(" . join( ', ', map { "'$_'" } @args ) . ")" );
}
done_testing();

View File

@ -17,17 +17,24 @@ my $debug = 'error';
# Initialization # Initialization
my $op = LLNG::Manager::Test->new( { my $op = LLNG::Manager::Test->new( {
ini => { ini => {
logLevel => $debug, logLevel => $debug,
domain => 'op.com', domain => 'op.com',
portal => 'http://auth.op.com', portal => 'http://auth.op.com',
authentication => 'Demo', authentication => 'Demo',
userDB => 'Same', userDB => 'Same',
macros => {
gender => '"32"',
_whatToTrace => '$uid',
nickname => '"froggie; frenchie"',
},
issuerDBOpenIDConnectActivation => 1, issuerDBOpenIDConnectActivation => 1,
oidcRPMetaDataExportedVars => { oidcRPMetaDataExportedVars => {
rp => { rp => {
email => "mail", email => "mail;string;always",
preferred_username => "uid", preferred_username => "uid",
name => "cn" name => "cn",
gender => "gender;int;auto",
nickname => "nickname",
} }
}, },
oidcRPMetaDataOptions => { oidcRPMetaDataOptions => {
@ -131,6 +138,11 @@ $res = $op->_post(
$payload = expectJSON($res); $payload = expectJSON($res);
ok( $payload->{'name'} eq "Frédéric Accents", 'Got User Info' ); ok( $payload->{'name'} eq "Frédéric Accents", 'Got User Info' );
like( $res->[2]->[0], qr/"gender":32/, "Attribute released as int in JSON" );
is( ref( $payload->{email} ),
"ARRAY", "Single valued attribute forced as array" );
is( ref( $payload->{nickname} ),
"ARRAY", "Multi valued attribute exposed as array" );
clean_sessions(); clean_sessions();
done_testing(); done_testing();

View File

@ -374,10 +374,10 @@ ok(
) or print STDERR Dumper( $res->[2]->[0] ); ) or print STDERR Dumper( $res->[2]->[0] );
ok( ok(
$res->[2]->[0] =~ $res->[2]->[0] =~
m%<input type="checkbox" name="check1x2x1" id="1x2x1" value="accepted"/>%, m%<input class="form-check-input" type="checkbox" name="check1x2x1" id="1x2x1" value="accepted"/>%,
'Checkbox is displayed' 'Checkbox is displayed'
) or print STDERR Dumper( $res->[2]->[0] ); ) or print STDERR Dumper( $res->[2]->[0] );
my @c = ( $res->[2]->[0] =~ m%<input type="checkbox"%gs ); my @c = ( $res->[2]->[0] =~ m%<input class="form-check-input" type="checkbox"%gs );
## One entry found ## One entry found
ok( @c == 1, ' -> One checkbox found' ) ok( @c == 1, ' -> One checkbox found' )
@ -418,17 +418,17 @@ expectForm( $res, undef, '/notifback', 'reference1x1' );
ok( ok(
$res->[2]->[0] =~ $res->[2]->[0] =~
m%<input type="checkbox" name="check1x1x1" id="1x1x1" value="accepted"/>% m%<input class="form-check-input" type="checkbox" name="check1x1x1" id="1x1x1" value="accepted"/>%
and m%<label class="form-check-label" for="1x1x1">I agree</label>%, and m%<label class="form-check-label" for="1x1x1">I agree</label>%,
'Checkbox is displayed' 'Checkbox is displayed'
) or print STDERR Dumper( $res->[2]->[0] ); ) or print STDERR Dumper( $res->[2]->[0] );
ok( ok(
$res->[2]->[0] =~ $res->[2]->[0] =~
m%<input type="checkbox" name="check1x1x2" id="1x1x2" value="accepted"/>% m%<input class="form-check-input" type="checkbox" name="check1x1x2" id="1x1x2" value="accepted"/>%
and m%<label class="form-check-label" for="1x1x2">I am sure</label>%, and m%<label class="form-check-label" for="1x1x2">I am sure</label>%,
'Checkbox is displayed' 'Checkbox is displayed'
) or print STDERR Dumper( $res->[2]->[0] ); ) or print STDERR Dumper( $res->[2]->[0] );
@c = ( $res->[2]->[0] =~ m%<input type="checkbox"%gs ); @c = ( $res->[2]->[0] =~ m%<input class="form-check-input" type="checkbox"%gs );
## Two entries found ## Two entries found
ok( @c == 2, ' -> Two checkboxes found' ) ok( @c == 2, ' -> Two checkboxes found' )

View File

@ -44,7 +44,7 @@ SKIP: {
$res = $client->_post( $res = $client->_post(
'/register', '/register',
IO::String->new( IO::String->new(
'firstname=Fôo&lastname=Bàr&mail=foobar%40badwolf.org'), 'firstname=Fôo&lastname=Bà Bar&mail=foobar%40badwolf.org'),
length => 53, length => 53,
accept => 'text/html' accept => 'text/html'
), ),
@ -73,12 +73,12 @@ SKIP: {
); );
$user = $1; $user = $1;
$pwd = $2; $pwd = $2;
ok( $user eq 'fbar', 'Get good login' ); ok( $user eq 'fbabar', 'Get good login' );
ok( ok(
$res = $client->_post( $res = $client->_post(
'/', IO::String->new("user=fbar&password=fbar"), '/', IO::String->new("user=fbabar&password=fbabar"),
length => 23, length => 27,
accept => 'text/html' accept => 'text/html'
), ),
'Try to authenticate' 'Try to authenticate'

View File

@ -242,7 +242,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
), ),
'Post fingerprint' 'Post fingerprint'
); );
my $cid = expectCookie( $res, 'llngconnexion' ); my $cid = expectCookie( $res, 'llngconnection' );
# History is displayed # History is displayed
ok( ok(
@ -358,7 +358,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
), ),
'Post fingerprint' 'Post fingerprint'
); );
$cid = expectCookie( $res, 'llngconnexion' ); $cid = expectCookie( $res, 'llngconnection' );
# History is displayed # History is displayed
ok( ok(
@ -393,7 +393,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
ok( ok(
$res = $client->_get( $res = $client->_get(
'/', '/',
cookie => "llngconnexion=$cid", cookie => "llngconnection=$cid",
accept => 'text/html', accept => 'text/html',
), ),
'Try to auth with persistent cookie' 'Try to auth with persistent cookie'
@ -407,7 +407,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
$res = $client->_post( $res = $client->_post(
'/', '/',
IO::String->new($query), IO::String->new($query),
cookie => "llngconnexion=$cid", cookie => "llngconnection=$cid",
length => length($query), length => length($query),
accept => 'text/html', accept => 'text/html',
), ),
@ -458,7 +458,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
ok( ok(
$res = $client->_get( $res = $client->_get(
'/', '/',
cookie => "llngconnexion=$cid", cookie => "llngconnection=$cid",
accept => 'text/html', accept => 'text/html',
), ),
'Try to auth with persistent cookie' 'Try to auth with persistent cookie'
@ -472,7 +472,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
$res = $client->_post( $res = $client->_post(
'/', '/',
IO::String->new($query), IO::String->new($query),
cookie => "llngconnexion=$cid", cookie => "llngconnection=$cid",
length => length($query), length => length($query),
accept => 'text/html', accept => 'text/html',
), ),

View File

@ -8,13 +8,15 @@ my $res;
my $client = LLNG::Manager::Test->new( { my $client = LLNG::Manager::Test->new( {
ini => { ini => {
logLevel => 'error', logLevel => 'error',
useSafeJail => 1, useSafeJail => 1,
stayConnected => 1, stayConnected => 1,
loginHistoryEnabled => 1, loginHistoryEnabled => 1,
securedCookie => 1, securedCookie => 1,
portalMainLogo => 'common/logos/logo_llng_old.png', stayConnectedTimeout => 1000,
accept => 'text/html', stayConnectedCookieName => 'llngpersistent',
portalMainLogo => 'common/logos/logo_llng_old.png',
accept => 'text/html',
} }
} }
); );
@ -34,6 +36,38 @@ my $id = expectCookie($res);
my ( $host, $url, $query ) = my ( $host, $url, $query ) =
expectForm( $res, undef, '/registerbrowser', 'fg', 'token' ); expectForm( $res, undef, '/registerbrowser', 'fg', 'token' );
# Push fingerprint with an expired token
$query =~ s/fg=/fg=aaa/;
Time::Fake->offset("+130s");
ok(
$res = $client->_post(
'/registerbrowser',
IO::String->new($query),
length => length($query),
cookie => "lemonldap=$id",
accept => 'text/html',
),
'Post fingerprint'
);
expectRedirection( $res, 'http://auth.example.com/' );
count(1);
$client->logout($id);
# Try to authenticate
# -------------------
ok(
$res = $client->_post(
'/',
IO::String->new('user=dwho&password=dwho&stayconnected=1'),
length => 39
),
'Auth query'
);
count(1);
$id = expectCookie($res);
( $host, $url, $query ) =
expectForm( $res, undef, '/registerbrowser', 'fg', 'token' );
# Push fingerprint # Push fingerprint
$query =~ s/fg=/fg=aaa/; $query =~ s/fg=/fg=aaa/;
ok( ok(
@ -47,7 +81,7 @@ ok(
'Post fingerprint' 'Post fingerprint'
); );
expectRedirection( $res, 'http://auth.example.com/' ); expectRedirection( $res, 'http://auth.example.com/' );
my $cid = expectCookie( $res, 'llngconnexion' ); my $cid = expectCookie( $res, 'llngpersistent' );
ok( $res->[1]->[5] =~ /\bsecure\b/, ' Secured cookie found' ) ok( $res->[1]->[5] =~ /\bsecure\b/, ' Secured cookie found' )
or print STDERR Dumper( $res->[1]->[5] ); or print STDERR Dumper( $res->[1]->[5] );
count(2); count(2);
@ -57,7 +91,7 @@ $client->logout($id);
ok( ok(
$res = $client->_get( $res = $client->_get(
'/', '/',
cookie => "llngconnexion=$cid", cookie => "llngpersistent=$cid",
accept => 'text/html', accept => 'text/html',
), ),
'Try to auth with persistent cookie' 'Try to auth with persistent cookie'
@ -72,7 +106,7 @@ ok(
$res = $client->_post( $res = $client->_post(
'/', '/',
IO::String->new($query), IO::String->new($query),
cookie => "llngconnexion=$cid", cookie => "llngpersistent=$cid",
length => length($query), length => length($query),
accept => 'text/html', accept => 'text/html',
), ),
@ -84,11 +118,41 @@ $id = expectCookie($res);
$client->logout($id); $client->logout($id);
# Try to connect with persistent connection cookie but bad fingerprint # Try to connect with persistent connection cookie and an expired token
ok( ok(
$res = $client->_get( $res = $client->_get(
'/', '/',
cookie => "llngconnexion=$cid", cookie => "llngpersistent=$cid",
accept => 'text/html',
),
'Try to auth with persistent cookie and an expired token'
);
count(1);
expectOK($res);
( $host, $url, $query ) = expectForm( $res, '#', undef, 'fg', 'token' );
Time::Fake->offset("+250s");
# Push fingerprint
$query =~ s/fg=/fg=aaa/;
ok(
$res = $client->_post(
'/',
IO::String->new($query),
cookie => "llngpersistent=$cid",
length => length($query),
accept => 'text/html',
),
'Post fingerprint with an expired token'
);
( $host, $url, $query ) = expectForm($res);
ok( $query =~ /user/, ' Get login form' );
count(2);
# Try to connect with persistent connection cookie but with bad fingerprint
ok(
$res = $client->_get(
'/',
cookie => "llngpersistent=$cid",
accept => 'text/html', accept => 'text/html',
), ),
'Try to auth with persistent cookie' 'Try to auth with persistent cookie'
@ -103,7 +167,7 @@ ok(
$res = $client->_post( $res = $client->_post(
'/', '/',
IO::String->new($query), IO::String->new($query),
cookie => "llngconnexion=$cid", cookie => "llngpersistent=$cid",
length => length($query), length => length($query),
accept => 'text/html', accept => 'text/html',
), ),
@ -111,7 +175,12 @@ ok(
); );
( $host, $url, $query ) = expectForm($res); ( $host, $url, $query ) = expectForm($res);
ok( $query =~ /user/, ' Get login form' ); ok( $query =~ /user/, ' Get login form' );
count(2); expectCookie( $res, 'llngpersistent' );
my @connexionCookie = grep /llngpersistent/, @{ $res->[1] };
ok( $connexionCookie[0] =~ /secure/ && $connexionCookie[0] =~ /21 Oct 2015/,
'Found secured and expired connexion Cookie' )
or print STDERR Dumper( $connexionCookie[0] );
count(3);
# Try to authenticate with history # Try to authenticate with history
# -------------------------------- # --------------------------------
@ -142,7 +211,7 @@ ok(
'Post fingerprint' 'Post fingerprint'
); );
count(1); count(1);
$cid = expectCookie( $res, 'llngconnexion' ); $cid = expectCookie( $res, 'llngpersistent' );
ok( $res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%, ok( $res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'Found custom Main Logo' ) 'Found custom Main Logo' )
@ -152,8 +221,8 @@ ok( $res->[2]->[0] =~ /trspan="lastLogins"/, 'History found' )
my @c = ( $res->[2]->[0] =~ /<td>127.0.0.1/gs ); my @c = ( $res->[2]->[0] =~ /<td>127.0.0.1/gs );
# History with 2 successLogins # History with 2 successLogins
ok( @c == 2, " -> Two entries found" ) ok( @c == 3, " -> Three entries found" )
or explain( $res->[2]->[0], 'Two entries found' ); or explain( $res->[2]->[0], 'Three entries found' );
ok( $res = $client->_get( '/', cookie => "lemonldap=$id" ), ok( $res = $client->_get( '/', cookie => "lemonldap=$id" ),
'Verify connection' ); 'Verify connection' );
expectAuthenticatedAs( $res, 'dwho' ); expectAuthenticatedAs( $res, 'dwho' );
@ -171,6 +240,36 @@ ok( $res->[2]->[0] =~ m%<span trspan="yourApps">Your applications</span>%,
count(6); count(6);
expectOK($res); expectOK($res);
# Try to connect with an expired persistent connection cookie
Time::Fake->offset("+1300s");
ok(
$res = $client->_get(
'/',
cookie => "llngpersistent=$cid",
accept => 'text/html',
),
'Try to auth with an expired persistent session cookie'
);
( $host, $url, $query ) = expectForm($res);
ok( $query =~ /user/, ' Get login form' );
count(2);
# Push fingerprint
$query =~ s/fg=/fg=aaa/;
ok(
$res = $client->_post(
'/',
IO::String->new($query),
cookie => "llngpersistent=$cid",
length => length($query),
accept => 'text/html',
),
'Post fingerprint with an expired persistent connexion cookie'
);
( $host, $url, $query ) = expectForm($res);
ok( $query =~ /user/, ' Get login form' );
count(2);
$client->logout($id); $client->logout($id);
clean_sessions(); clean_sessions();

View File

@ -392,10 +392,10 @@ sub expectPortalError {
count(1); count(1);
} }
=head4 expectReject( $res, $code ) =head4 expectReject( $res, $status, $code )
Verify that returned code is 401 and JSON result contains C<error:"$code">. Verify that returned code is 401 (or $status) and JSON result contains
Note that it works only for Ajax request (see below). C<error:"$code">. Note that it works only for Ajax request (see below).
=cut =cut
@ -698,6 +698,11 @@ has ini => (
cn => 'Русский', cn => 'Русский',
mail => 'ru@badwolf.org', mail => 'ru@badwolf.org',
}; };
push
@{ $Lemonldap::NG::Portal::UserDB::Demo::demoGroups{earthlings} },
"french", "russian";
push @{ $Lemonldap::NG::Portal::UserDB::Demo::demoGroups{users} },
"french", "russian", "davros";
} }
$self; $self;
} }