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
Summarize the proposed new feature concisely
Summarize the desired feature concisely
### Design proposition
Detail your proposed implementation (interface design, architecture, impact on
current behavior,…)
Describe here the proposed implementation of this feature (interface design suggestions, general architecture, pseudo-code,…)

View File

@ -31,7 +31,10 @@ Restrictions: superficial, skippable
# Use pkg-perl-autopkgtest test for runtime-deps-and-recommends
# Some portal suggested dependencies are added here
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
#Test-Command: ./debian/tests/runner heavy-deps

View File

@ -34,6 +34,7 @@ and configure the following parameters:
Kerberos code to validate Kerberos ticket
- **Remove domain in username**: set to "enabled" to strip username
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::

View File

@ -98,12 +98,12 @@ Exported attributes
For each attribute, you can set:
- **Key name**: name of the key in LemonLDAP::NG session (for example
"uid" will then be used as $uid in access rules)
- **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
- **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
attribute is not given by IDP.
- **Name**: SAML attribute name.
- **Friendly Name**: optional, SAML attribute friendly name.
- **Format** (optional): SAML attribute format.
|image1|

View File

@ -166,11 +166,16 @@ claim <http://openid.net/specs/openid-connect-core-1_0.html#StandardClaims>`__.
.. 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
- family_name => sn
- email => mail
* **Claim name**: the name of the claim as it will appear in Userinfo responses
* **Variable name**: the name of the LemonLDAP::NG session variable containing the claim value
* **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::
@ -178,6 +183,7 @@ So you can define for example:
The specific ``sub`` attribute is not defined here, but
in User attribute parameter (see below).
Extra Claims
^^^^^^^^^^^^

View File

@ -89,9 +89,9 @@ Exported attributes
For each attribute, you can set:
- **Key name**: name of the key in LemonLDAP::NG session
- **Name**: SAML attribute name.
- **Friendly Name**: optional, SAML attribute friendly name.
- **Variable name**: name of the variable in LemonLDAP::NG session
- **Attribute name**: name of the SAML attribute that will be seen by applications
- **Friendly Name**: optional, friendly name of the SAML attribute seen by applications
- **Mandatory**: if set to "On", then this attribute is required to
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

View File

@ -27,3 +27,4 @@ Plugins
resetcertificate
restservices
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::

View File

@ -25,7 +25,7 @@ authentication process, then use ``afterSub``, for example:
use constant afterSub => {
getUser => 'mysub',
}
};
sub mysub {
my ( $self ,$req ) = @_;
# 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:`REST services<restservices>` |new| REST 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
==================================================================== ============================================================================================================================================

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.
2.0.10
------
- New dependency: IO::Socket::Timeout
2.0.9
-----

View File

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

View File

@ -393,8 +393,31 @@ sub _oidcMetaDataNodes {
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
if ( $query =~
elsif ( $query =~
/^(?:oidc${type}MetaDataExportedVars|oidcRPMetaDataOptionsExtraClaims|oidcRPMetaDataMacros)$/
)
{

View File

@ -44,7 +44,7 @@ our $authParameters = {
facebookParams => [qw(facebookAuthnLevel facebookExportedVars facebookAppId facebookAppSecret facebookUserField)],
githubParams => [qw(githubAuthnLevel githubClientID githubClientSecret githubUserField githubScope)],
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)],
linkedinParams => [qw(linkedInAuthnLevel linkedInClientID linkedInClientSecret linkedInFields linkedInUserField linkedInScope)],
nullParams => [qw(nullAuthnLevel)],

View File

@ -192,6 +192,8 @@ sub sendError {
: $code == 400 ? 'Bad request'
: 'Error'
);
# TODO: this should probably use a template instead
my $s = "<html><head><title>$title</title>
<style>
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>
</body>
</html>";
return [
$code,
[
'Content-Type' => 'text/html; charset=utf-8',
'Content-Length' => length($s),
$req->spliceHdrs,
],
[$s]
];
return $self->sendRawHtml( $req, $s, code => $code );
}
}
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 {
my ( $self, $err ) = @_;
eval { $self->logger->error($err) };
@ -250,7 +259,7 @@ sub sendJs {
return [
200,
[
'Content-Type' => 'application/javascript',
'Content-Type' => 'application/json',
'Content-Length' => length($s),
'Cache-Control' => 'public,max-age=2592000',
],

View File

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

View File

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

View File

@ -128,6 +128,8 @@ site/htdocs/static/forms/longtext.html
site/htdocs/static/forms/menuApp.html
site/htdocs/static/forms/menuCat.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/oidcOPMetaDataNodeContainer.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',
'test' => sub {
my ( $val, $conf ) = @_;
return 1
if defined $conf->{'macros'}{$val} or $val eq '_timezone';
return 1 if defined $conf->{'macros'}{$val} or $val =~ /^_/;
foreach $_ ( keys %$conf ) {
return 1
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;
}
},
'oidcAttribute' => {
'test' => sub {
1;
}
},
'oidcmetadatajson' => {
'test' => sub {
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' => {
'type' => 'password'
},
'krbAllowedDomains' => {
'type' => 'text'
},
'krbAuthnLevel' => {
'default' => 3,
'type' => 'int'
@ -2183,7 +2190,9 @@ m[^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
'family_name' => 'sn',
'name' => 'cn'
},
'type' => 'keyTextContainer'
'keyTest' => qr/\w/,
'test' => qr/\w/,
'type' => 'oidcAttributeContainer'
},
'oidcRPMetaDataMacros' => {
'default' => {},
@ -3923,6 +3932,16 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
'default' => 0,
'type' => 'bool'
},
'stayConnectedCookieName' => {
'default' => 'llngconnection',
'msgFail' => '__badCookieName__',
'test' => qr/^[a-zA-Z][a-zA-Z0-9_-]*$/,
'type' => 'text'
},
'stayConnectedTimeout' => {
'default' => 2592000,
'type' => 'int'
},
'storePassword' => {
'default' => 0,
'type' => 'bool'

View File

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

View File

@ -81,7 +81,7 @@ sub types {
my ( $val, $conf ) = @_;
return 1
if ( defined $conf->{macros}->{$val}
or $val eq '_timezone' );
or $val =~ m/^_/ );
foreach ( keys %$conf ) {
return 1
if ( $_ =~ /exportedvars$/i
@ -184,6 +184,9 @@ sub types {
menuCat => {
test => sub { 1 }
},
oidcAttribute => {
test => sub { 1 }
},
oidcOPMetaDataNode => {
test => sub { 1 }
},
@ -431,12 +434,25 @@ sub attributes {
flags => 'hmp',
},
stayConnected => {
type => 'bool',
#help => 'stayconnected.html',
type => 'bool',
default => 0,
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 => {
type => 'bool',
default => 0,
@ -3684,6 +3700,10 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
default => 1,
documentation => 'Remove domain in Kerberos username',
},
krbAllowedDomains => {
type => 'text',
documentation => 'Allowed domains',
},
# Slave
slaveAuthnLevel => {
@ -4096,11 +4116,13 @@ m{^(?:ldapi://[^/]*/?|\w[\w\-\.]*(?::\d{1,5})?|ldap(?:s|\+tls)?://\w[\w\-\.]*(?:
# OpenID Connect relying parties
oidcRPMetaDataExportedVars => {
type => 'keyTextContainer',
type => 'oidcAttributeContainer',
keyTest => qr/\w/,
test => qr/\w/,
default => {
'name' => 'cn',
'family_name' => 'sn',
'email' => 'mail'
'email' => 'mail',
}
},
oidcRPMetaDataOptionsClientID => { type => 'text', },

View File

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

View File

@ -407,6 +407,37 @@ sub _scanNodes {
hdebug(" $target");
$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 (
$target =~ /^oidc(?:O|R)PMetaData(?:ExportedVars|Macros)$/ )
{

View File

@ -377,6 +377,15 @@ llapp.controller 'TreeCtrl', [
type: 'samlAttribute'
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
$scope.addVhost = ->
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">
<!-- Key Name -->
<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>
</tr>
<!-- Name -->
<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>
</tr>
<!-- Friendly Name -->

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -16,18 +16,30 @@ our $VERSION = '2.1.0';
extends 'Lemonldap::NG::Portal::Main::Auth';
has keytab => ( is => 'rw' );
has Name => ( is => 'ro', default => 'Kerberos' );
has allowedDomains => ( is => 'rw', isa => 'ArrayRef' );
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
sub init {
my $self = shift;
my $file;
my $domains;
unless ( $file = $self->conf->{krbKeytab} ) {
$self->logger->error('Keytab not defined');
return 0;
}
if ( $domains = $self->conf->{krbAllowedDomains} ) {
$self->allowedDomains( [ split /[\s,]+/, $domains ] );
}
$self->keytab("FILE:$file");
return 1;
}
@ -38,7 +50,7 @@ sub extractFormInfo {
if ( $req->data->{_krbUser} ) {
$self->logger->debug(
'Kerberos ticket already validated for ' . $req->data->{_krbUser} );
return PE_OK;
return $self->_checkDomains($req);
}
my $auth = $req->env->{HTTP_AUTHORIZATION};
@ -156,7 +168,24 @@ sub extractFormInfo {
$client_name =~ s/^(.*)@.*$/$1/;
}
$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 {

View File

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

View File

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

View File

@ -1096,7 +1096,9 @@ sub _handlePasswordGrant {
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
my $accessTokenSession = $self->newAccessToken(

View File

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

View File

@ -1349,9 +1349,13 @@ sub buildUserInfoResponse {
my $list = $self->getAttributesListFromClaim( $rp, $claim );
next unless $list;
foreach my $attribute (@$list) {
my $session_key =
$self->conf->{oidcRPMetaDataExportedVars}->{$rp}->{$attribute};
my @attrConf = split /;/,
( $self->conf->{oidcRPMetaDataExportedVars}->{$rp}->{$attribute}
|| "" );
my $session_key = $attrConf[0];
if ($session_key) {
my $type = $attrConf[1] || 'string';
my $array = $attrConf[2] || 'auto';
my $session_value;
@ -1366,21 +1370,25 @@ sub buildUserInfoResponse {
$session_value = $session->data->{$session_key};
}
# Convert mutli-valued attributes to arrays
my $separator = $self->conf->{multiValuesSeparator};
if ( $session_value and $session_value =~ /$separator/ ) {
my @session_array =
split( $separator, $session_value );
$session_value = \@session_array;
}
# Handle empty values, arrays, type, etc.
$session_value =
$self->_formatValue( $session_value, $type, $array,
$attribute, $req->user );
# Address is a JSON object
if ( $claim eq "address" ) {
$userinfo_response->{address}->{$attribute} =
$session_value;
}
else {
$userinfo_response->{$attribute} = $session_value;
# From this point on, do NOT touch $session_value or you will break
# the variable's type.
# Only release claim if it has a value
if ( defined $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;
}
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
# @param payload JWT content
# @param alg Signature algorithm

View File

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

View File

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

View File

@ -199,8 +199,8 @@ sub refresh {
$self->groupsAndMacros,
'setLocalGroups',
sub {
$req->sessionInfo->{$_} = $data{$_} foreach ( keys %data );
$req->refresh(1);
$_[0]->sessionInfo->{$_} = $data{$_} foreach ( keys %data );
$_[0]->refresh(1);
return PE_OK;
},
'store',
@ -277,7 +277,7 @@ sub do {
code => 401,
headers => [
'WWW-Authenticate' => "SSO " . $self->conf->{portal},
"Content-Type" => "application/javascript"
"Content-Type" => "application/json"
],
);
}
@ -1138,6 +1138,18 @@ sub sendJSONresponse {
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
sub loadTemplate {
my ( $self, $req, $name, %prm ) = @_;

View File

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

View File

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

View File

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

View File

@ -2,10 +2,15 @@ package Lemonldap::NG::Portal::Password::DBI;
use strict;
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',
'Lemonldap::NG::Portal::Lib::DBI';
extends qw(
Lemonldap::NG::Portal::Lib::DBI
Lemonldap::NG::Portal::Password::Base
);
our $VERSION = '2.1.0';

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -2,6 +2,7 @@ package Lemonldap::NG::Portal::Plugins::Refresh;
use strict;
use Mouse;
use JSON;
our $VERSION = '2.1.0';
@ -35,9 +36,26 @@ sub run {
);
$req->id($id);
$req->user( $info->{uid} );
eval { $self->p->refresh($req); };
$self->logger->debug("Refresh: $@") if $@;
$c++;
my $res;
eval { $res = $self->p->refresh($req); };
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->$_(undef) foreach (qw(user id));

View File

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

View File

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

View File

@ -30,7 +30,9 @@ sub applyLoginRule {
lc $self->_stripaccents( $req->data->{registerInfo}->{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;

View File

@ -2,7 +2,10 @@ package Lemonldap::NG::Portal::Register::Demo;
use strict;
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';

View File

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

View File

@ -12,7 +12,7 @@
<TMPL_LOOP NAME="check">
<p class="notifCheck">
<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>
</div>
</p>

View File

@ -15,6 +15,8 @@ my $client = LLNG::Manager::Test->new( {
cspFormAction => '*',
cspFrameAncestors => 'test.example.com',
customToTrace => 'mail',
checkStateSecret => 'x',
checkState => 1,
}
}
);
@ -38,6 +40,12 @@ ok(
count(1);
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' );
count(1);

View File

@ -7,7 +7,7 @@ require 't/test-lib.pm';
use lib 't/lib';
my $res;
my $maintests = 26;
my $maintests = 32;
SKIP: {
skip( 'LLNGTESTLDAP is not set', $maintests ) unless ( $ENV{LLNGTESTLDAP} );
@ -22,6 +22,7 @@ SKIP: {
userDB => 'Same',
passwordDB => 'LDAP',
portalRequireOldPassword => 1,
hideOldPassword => 1,
ldapServer => 'ldap://127.0.0.1:19389/',
ldapBase => 'ou=users,dc=example,dc=com',
managerDn => 'cn=lemonldapng,ou=dsa,dc=example,dc=com',
@ -35,12 +36,21 @@ SKIP: {
passwordPolicyMinDigit => 1,
passwordPolicyMinSpeChar => 1,
passwordPolicySpecialChar => '# &',
whatToTrace => 'uid',
macros => {
_whatToTrace => '' # Test 2377
},
}
}
);
use Lemonldap::NG::Portal::Main::Constants 'PE_PP_CHANGE_AFTER_RESET',
'PE_PP_PASSWORD_EXPIRED', 'PE_PASSWORD_OK', 'PE_PP_ACCOUNT_LOCKED',
'PE_PP_PASSWORD_TOO_SHORT', 'PE_PP_GRACE';
use Lemonldap::NG::Portal::Main::Constants qw(
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 );
@ -74,13 +84,31 @@ SKIP: {
my ( $host, $url, $query ) =
expectForm( $res, '#', undef, 'user', 'oldpassword', 'newpassword',
'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">%,
' passwordPolicyMinSize' )
or print STDERR Dumper( $res->[2]->[0], 'passwordPolicyMinSize' );
ok( $query =~ /user=$user/, "User is $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;
ok(
$res = $client->_post(
'/', IO::String->new($query),

View File

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

View File

@ -6,7 +6,7 @@ BEGIN {
eval "use GSSAPI";
}
my $maintests = 12;
my $maintests = 14;
my $debug = 'error';
SKIP: {
@ -103,7 +103,58 @@ SKIP: {
" 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);
@ -123,6 +174,6 @@ package LLNG::GSSR;
sub display {
my $a = \@_;
$a->[1] = 'dwho';
$a->[1] = 'dwho@EXAMPLE.COM';
return 1;
}

View File

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

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
my $op = LLNG::Manager::Test->new( {
ini => {
logLevel => $debug,
domain => 'op.com',
portal => 'http://auth.op.com',
authentication => 'Demo',
userDB => 'Same',
logLevel => $debug,
domain => 'op.com',
portal => 'http://auth.op.com',
authentication => 'Demo',
userDB => 'Same',
macros => {
gender => '"32"',
_whatToTrace => '$uid',
nickname => '"froggie; frenchie"',
},
issuerDBOpenIDConnectActivation => 1,
oidcRPMetaDataExportedVars => {
rp => {
email => "mail",
email => "mail;string;always",
preferred_username => "uid",
name => "cn"
name => "cn",
gender => "gender;int;auto",
nickname => "nickname",
}
},
oidcRPMetaDataOptions => {
@ -131,6 +138,11 @@ $res = $op->_post(
$payload = expectJSON($res);
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();
done_testing();

View File

@ -374,10 +374,10 @@ ok(
) or print STDERR Dumper( $res->[2]->[0] );
ok(
$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'
) 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
ok( @c == 1, ' -> One checkbox found' )
@ -418,17 +418,17 @@ expectForm( $res, undef, '/notifback', 'reference1x1' );
ok(
$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>%,
'Checkbox is displayed'
) or print STDERR Dumper( $res->[2]->[0] );
ok(
$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>%,
'Checkbox is displayed'
) 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
ok( @c == 2, ' -> Two checkboxes found' )

View File

@ -44,7 +44,7 @@ SKIP: {
$res = $client->_post(
'/register',
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,
accept => 'text/html'
),
@ -73,12 +73,12 @@ SKIP: {
);
$user = $1;
$pwd = $2;
ok( $user eq 'fbar', 'Get good login' );
ok( $user eq 'fbabar', 'Get good login' );
ok(
$res = $client->_post(
'/', IO::String->new("user=fbar&password=fbar"),
length => 23,
'/', IO::String->new("user=fbabar&password=fbabar"),
length => 27,
accept => 'text/html'
),
'Try to authenticate'

View File

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

View File

@ -8,13 +8,15 @@ my $res;
my $client = LLNG::Manager::Test->new( {
ini => {
logLevel => 'error',
useSafeJail => 1,
stayConnected => 1,
loginHistoryEnabled => 1,
securedCookie => 1,
portalMainLogo => 'common/logos/logo_llng_old.png',
accept => 'text/html',
logLevel => 'error',
useSafeJail => 1,
stayConnected => 1,
loginHistoryEnabled => 1,
securedCookie => 1,
stayConnectedTimeout => 1000,
stayConnectedCookieName => 'llngpersistent',
portalMainLogo => 'common/logos/logo_llng_old.png',
accept => 'text/html',
}
}
);
@ -34,6 +36,38 @@ my $id = expectCookie($res);
my ( $host, $url, $query ) =
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
$query =~ s/fg=/fg=aaa/;
ok(
@ -47,7 +81,7 @@ ok(
'Post fingerprint'
);
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' )
or print STDERR Dumper( $res->[1]->[5] );
count(2);
@ -57,7 +91,7 @@ $client->logout($id);
ok(
$res = $client->_get(
'/',
cookie => "llngconnexion=$cid",
cookie => "llngpersistent=$cid",
accept => 'text/html',
),
'Try to auth with persistent cookie'
@ -72,7 +106,7 @@ ok(
$res = $client->_post(
'/',
IO::String->new($query),
cookie => "llngconnexion=$cid",
cookie => "llngpersistent=$cid",
length => length($query),
accept => 'text/html',
),
@ -84,11 +118,41 @@ $id = expectCookie($res);
$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(
$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',
),
'Try to auth with persistent cookie'
@ -103,7 +167,7 @@ ok(
$res = $client->_post(
'/',
IO::String->new($query),
cookie => "llngconnexion=$cid",
cookie => "llngpersistent=$cid",
length => length($query),
accept => 'text/html',
),
@ -111,7 +175,12 @@ ok(
);
( $host, $url, $query ) = expectForm($res);
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
# --------------------------------
@ -142,7 +211,7 @@ ok(
'Post fingerprint'
);
count(1);
$cid = expectCookie( $res, 'llngconnexion' );
$cid = expectCookie( $res, 'llngpersistent' );
ok( $res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'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 );
# History with 2 successLogins
ok( @c == 2, " -> Two entries found" )
or explain( $res->[2]->[0], 'Two entries found' );
ok( @c == 3, " -> Three entries found" )
or explain( $res->[2]->[0], 'Three entries found' );
ok( $res = $client->_get( '/', cookie => "lemonldap=$id" ),
'Verify connection' );
expectAuthenticatedAs( $res, 'dwho' );
@ -171,6 +240,36 @@ ok( $res->[2]->[0] =~ m%<span trspan="yourApps">Your applications</span>%,
count(6);
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);
clean_sessions();

View File

@ -392,10 +392,10 @@ sub expectPortalError {
count(1);
}
=head4 expectReject( $res, $code )
=head4 expectReject( $res, $status, $code )
Verify that returned code is 401 and JSON result contains C<error:"$code">.
Note that it works only for Ajax request (see below).
Verify that returned code is 401 (or $status) and JSON result contains
C<error:"$code">. Note that it works only for Ajax request (see below).
=cut
@ -698,6 +698,11 @@ has ini => (
cn => 'Русский',
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;
}