Merge branch 'v2.0'

This commit is contained in:
Yadd 2021-06-26 23:03:26 +02:00
commit 467bbf0f5e
38 changed files with 635 additions and 186 deletions

View File

@ -36,6 +36,7 @@ Applications
applications/office365 applications/office365
applications/publik applications/publik
applications/phpldapadmin applications/phpldapadmin
applications/redmine
applications/roundcube applications/roundcube
applications/salesforce applications/salesforce
applications/sap applications/sap
@ -116,6 +117,7 @@ Application Configuration
.. image:: applications/logo_office_365.png :doc:`Office 365<applications/office365>` .. image:: applications/logo_office_365.png :doc:`Office 365<applications/office365>`
.. image:: applications/logo-publik.png :doc:`Publik<applications/publik>` .. image:: applications/logo-publik.png :doc:`Publik<applications/publik>`
.. image:: applications/phpldapadmin_logo.png :doc:`phpLDAPAdmin<applications/phpldapadmin>` .. image:: applications/phpldapadmin_logo.png :doc:`phpLDAPAdmin<applications/phpldapadmin>`
.. image:: applications/redmine_logo.png :doc:`Redmine<applications/redmine>`
.. image:: applications/roundcube_logo.png :doc:`Roundcube<applications/roundcube>` .. image:: applications/roundcube_logo.png :doc:`Roundcube<applications/roundcube>`
.. image:: applications/salesforce-logo.jpg :doc:`SalesForce<applications/salesforce>` .. image:: applications/salesforce-logo.jpg :doc:`SalesForce<applications/salesforce>`
.. image:: applications/SAPLogo.gif :doc:`SAP<applications/sap>` ✔ ✔ .. image:: applications/SAPLogo.gif :doc:`SAP<applications/sap>` ✔ ✔

View File

@ -0,0 +1,85 @@
Redmine
=======
|logo|
Presentation
------------
`Redmine <https://redmine.org/>`__ is is a flexible project management web application.
Written using the Ruby on Rails framework, it is cross-platform and cross-database.
It can be configured to authenticate users with :doc:`OpenID Connect <../idpopenidconnect>` with a plugin.
Configuration
--------------
LL:NG
~~~~~
Make sure you have already
:doc:`enabled OpenID Connect<../idpopenidconnect>` on your LemonLDAP::NG
server.
Make sure you have generated a set of signing keys in
``OpenID Connect Service`` » ``Security`` » ``Keys``
You also need to set a Signing key ID to a non-empty value of your choice.
Then, add a Relaying Party with the following configuration:
- Options » Basic » Client ID : choose a client ID, such as ``my_client_id``
- Options » Basic » Client Secret : choose a client secret, such as ``my_client_secret``
- Options » Basic » Allowed redirection address : ``https://my_redmine_server/oic/local_login``
- Options » Advanced » Force claims to be returned in ID Token : ``On``
- Options » Security » ID Token Signature Algorithm : ``RS512``
- Options » Logou( » Allowed redirection address for logout : ``https://my_redmine_server/oic/local_logout``
Define exported attributes:
- ``email``
- ``family_name``
- ``given_name``
- ``name``
- ``nickname``: the user login
To transfer groups:
- Declare ``member_of`` exported attribute as an array
- Declare a new scope named ``groups`` whith value ``member_of``
- Create a local macro ``member_of`` which will return ``["admin"]`` is user is administrator and ``["user"]`` else.
Redmine
~~~~~~~
Install `OpenID Connect plugin <https://github.com/devopskube/redmine_openid_connect>`__.
Go in Redmine admin console and configure the OpenID Connect plugin:
- Enabled: check the box
- Client ID: ``my_client_id``
- OpenID Connect server url: ``https://auth.example.com/``
- Client Secret: ``my_client_secret``
- OpenID Connect scopes: ``openid profile email groups``
- Authorized group: leave blank
- Admins group: ``admin``
- How often to retrieve openid configuration: leave blank
- Disable Ssl Validation: uncheck the box
- Login Selector: uncheck the box
- Create user if not exists: check the box
- Users from the following auth sources will be required to login with SSO: do not select anythin
.. attention::
A `bug <https://github.com/devopskube/redmine_openid_connect/issues/54>`__ has been reported, you must apply a patch
if you transfer groups.
.. note::
To bypass SSO, you can connect to `<https://my_redmine_server/login?local_login=true>`__
.. |logo| image:: /applications/redmine_logo.png
:class: align-center

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View File

@ -60,7 +60,7 @@ Debian dist LLNG version Se
**8** Jessie `1.3.3 </documentation/1.3/>`__ |clean| CVE-2019-19791 tagged as minor **None** [1]_ June 2020 Probably 2023 **8** Jessie `1.3.3 </documentation/1.3/>`__ |clean| CVE-2019-19791 tagged as minor **None** [1]_ June 2020 Probably 2023
**9** Stretch `1.9.7 </documentation/1.9/>`__ |clean| CVE-2019-19791 tagged as minor `Debian LTS Team <https://www.debian.org/lts/>`__ June 2022 **9** Stretch `1.9.7 </documentation/1.9/>`__ |clean| CVE-2019-19791 tagged as minor `Debian LTS Team <https://www.debian.org/lts/>`__ June 2022
\ *Stretch-backports* `2.0.2 </documentation/2.0/>`__ |bad| CVE-2019-12046, CVE-2019-13031, CVE-2019-15941 *None* *June 2019* \ *Stretch-backports* `2.0.2 </documentation/2.0/>`__ |bad| CVE-2019-12046, CVE-2019-13031, CVE-2019-15941 *None* *June 2019*
\ Stretch-backports-sloppy `2.0.11 </documentation/2.0/>`__ |clean| `LLNG Team </team>`__, "best effort" [3]_ Until Debian 11 release [4]_ \ Stretch-backports-sloppy `2.0.9 </documentation/2.0/>`__ |bad| *Maybe none*, "best effort" [3]_ Until Debian 11 release [4]_
**10** Buster `2.0.2 </documentation/2.0/>`__ |clean| CVE-2019-19791 tagged as minor `Debian Security Team <https://security-team.debian.org/>`__ Probably July 2024 **10** Buster `2.0.2 </documentation/2.0/>`__ |clean| CVE-2019-19791 tagged as minor `Debian Security Team <https://security-team.debian.org/>`__ Probably July 2024
\ Buster-backports `2.0.11 </documentation/2.0/>`__ |clean| `LLNG Team </team>`__ Until Debian 11 release [4]_ \ Buster-backports `2.0.11 </documentation/2.0/>`__ |clean| `LLNG Team </team>`__ Until Debian 11 release [4]_
\ Bullseye `2.0.11 </documentation/2.0/>`__ |clean| `Debian Security Team <https://security-team.debian.org/>`__ Probably July 2026 \ Bullseye `2.0.11 </documentation/2.0/>`__ |clean| `Debian Security Team <https://security-team.debian.org/>`__ Probably July 2026
@ -139,10 +139,11 @@ Other
Possible `Extended LTS <https://wiki.debian.org/LTS/Extended>`__ Possible `Extended LTS <https://wiki.debian.org/LTS/Extended>`__
.. [3] .. [3]
updated by `LLNG Team </team>`__ until dependencies are compatible updated by `LLNG Team </team>`__ until dependencies are compatible,
however this distribution seems unmaintained now
.. [4] .. [4]
around June 2021 around September 2021
.. [5] .. [5]
few days after release few days after release

View File

@ -54,8 +54,9 @@ sub load {
$fields = $fields ? join( ",", @$fields ) : '*'; $fields = $fields ? join( ",", @$fields ) : '*';
my $sth = my $sth =
$self->_dbh->prepare( $self->_dbh->prepare(
"SELECT field,value from " . $self->{dbiTable} . " WHERE cfgNum=?" ); "SELECT field,value from " . $self->{dbiTable} . " WHERE cfgNum=?" )
$sth->execute($cfgNum); or $self->logError;
$sth->execute($cfgNum) or $self->logError;
my ( $res, @row ); my ( $res, @row );
while ( @row = $sth->fetchrow_array ) { while ( @row = $sth->fetchrow_array ) {
$res->{ $row[0] } = $row[1]; $res->{ $row[0] } = $row[1];

View File

@ -36,8 +36,8 @@ sub available {
my $sth = my $sth =
$self->_dbh->prepare( "SELECT DISTINCT cfgNum from " $self->_dbh->prepare( "SELECT DISTINCT cfgNum from "
. $self->{dbiTable} . $self->{dbiTable}
. " order by cfgNum" ); . " order by cfgNum" ) or $self->logError;
$sth->execute(); $sth->execute() or $self->logError;
my @conf; my @conf;
while ( my @row = $sth->fetchrow_array ) { while ( my @row = $sth->fetchrow_array ) {
push @conf, $row[0]; push @conf, $row[0];
@ -105,8 +105,9 @@ sub unlock {
sub delete { sub delete {
my ( $self, $cfgNum ) = @_; my ( $self, $cfgNum ) = @_;
my $req = my $req =
$self->_dbh->prepare("DELETE FROM $self->{dbiTable} WHERE cfgNum=?"); $self->_dbh->prepare("DELETE FROM $self->{dbiTable} WHERE cfgNum=?")
my $res = $req->execute($cfgNum); or $self->logError;
my $res = $req->execute($cfgNum) or $self->logError;
$Lemonldap::NG::Common::Conf::msg .= $Lemonldap::NG::Common::Conf::msg .=
"Unable to find conf $cfgNum (" . $self->_dbh->errstr . ")" "Unable to find conf $cfgNum (" . $self->_dbh->errstr . ")"
unless ($res); unless ($res);

View File

@ -338,7 +338,7 @@ sub defaultValues {
'sfManagerRule' => 1, 'sfManagerRule' => 1,
'sfRemovedMsgRule' => 0, 'sfRemovedMsgRule' => 0,
'sfRemovedNotifMsg' => 'sfRemovedNotifMsg' =>
'_removedSF_ expired second factor(s) has/have been removed!', '_removedSF_ expired second factor(s) has/have been removed (_nameSF_)!',
'sfRemovedNotifRef' => 'RemoveSF', 'sfRemovedNotifRef' => 'RemoveSF',
'sfRemovedNotifTitle' => 'Second factor notification', 'sfRemovedNotifTitle' => 'Second factor notification',
'sfRequired' => 0, 'sfRequired' => 0,

View File

@ -248,6 +248,7 @@ t/15-combination.t
t/16-cli.t t/16-cli.t
t/17-extra2f.t t/17-extra2f.t
t/20-test-coverage.t t/20-test-coverage.t
t/30-DBI-Cli.t
t/40-sessions.t t/40-sessions.t
t/50-notifications-DBI.t t/50-notifications-DBI.t
t/50-notifications.t t/50-notifications.t
@ -267,6 +268,7 @@ t/jsonfiles/14-bad.json
t/jsonfiles/15-combination.json t/jsonfiles/15-combination.json
t/jsonfiles/17-extra2f.json t/jsonfiles/17-extra2f.json
t/jsonfiles/70-diff.json t/jsonfiles/70-diff.json
t/lemonldap-ng-DBI-conf.ini
t/lemonldap-ng-dbi.ini t/lemonldap-ng-dbi.ini
t/lemonldap-ng-noDiff.ini t/lemonldap-ng-noDiff.ini
t/lemonldap-ng.ini t/lemonldap-ng.ini

View File

@ -3954,7 +3954,7 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
}, },
'sfRemovedNotifMsg' => { 'sfRemovedNotifMsg' => {
'default' => 'default' =>
'_removedSF_ expired second factor(s) has/have been removed!', '_removedSF_ expired second factor(s) has/have been removed (_nameSF_)!',
'type' => 'text' 'type' => 'text'
}, },
'sfRemovedNotifRef' => { 'sfRemovedNotifRef' => {

View File

@ -3238,7 +3238,7 @@ sub attributes {
sfRemovedNotifMsg => { sfRemovedNotifMsg => {
type => 'text', type => 'text',
default => default =>
'_removedSF_ expired second factor(s) has/have been removed!', '_removedSF_ expired second factor(s) has/have been removed (_nameSF_)!',
help => 'secondfactor.html', help => 'secondfactor.html',
documentation => 'Notification message', documentation => 'Notification message',
}, },

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,67 @@
# Test notifications explorer API
use strict;
use Data::Dumper;
use IO::String;
use JSON qw(from_json);
use Test::More;
my $count = 0;
my $file = 't/conf.db';
my $maintests = 1;
my ( $res, $client );
eval { unlink $file };
sub count {
my $c = shift;
$count += $c if ($c);
return $count;
}
SKIP: {
eval { require DBI; require DBD::SQLite; };
if ($@) {
skip 'DBD::SQLite not found', $maintests;
}
my $dbh = DBI->connect("dbi:SQLite:dbname=$file");
$dbh->do('CREATE TABLE lmConfig (cfgNum int, data text)')
or die $DBI::errstr;
{
local $/ = undef;
open my $f, '<', 't/conf/lmConf-1.json';
my $content = <$f>;
close $f;
my $sth = $dbh->prepare('INSERT INTO lmConfig VALUES(1,?)')
or die $DBI::errstr;
$sth->execute($content) or die $DBI::errstr;
}
use_ok('Lemonldap::NG::Manager::Cli::Lib');
ok(
$client = Lemonldap::NG::Manager::Cli::Lib->new(
iniFile => 't/lemonldap-ng-DBI-conf.ini'
),
'Client object'
);
count(1);
use_ok('Lemonldap::NG::Manager::Cli');
count(1);
my @args = (qw(-yes 1 -force 1 set ldapSetPassword 0));
$ENV{LLNG_DEFAULTCONFFILE} = 't/lemonldap-ng-DBI-conf.ini';
Lemonldap::NG::Manager::Cli->run(@args);
my $res = $dbh->selectall_arrayref('SELECT * FROM lmConfig');
my $conf = from_json( $res->[0]->[1] );
ok( (
defined( $conf->{ldapSetPassword} )
and $conf->{ldapSetPassword} == 0
),
'Key inserted'
);
count(1);
}
eval { unlink $file };
done_testing( count($maintests) );

View File

@ -0,0 +1,27 @@
[all]
logLevel = debug
localSessionStorage =
localSessionStorageOptions =
[configuration]
type=CDBI
dbiChain=dbi:SQLite:dbname=t/conf.db
[portal]
checkXSS = 0
[handler]
https = 0
status = 0
useRedirectOnError = 0
[manager]
protection = manager
staticPrefix = app/
languages = fr, en, vi, ar
templateDir = site/templates/

View File

@ -521,6 +521,7 @@ t/29-AuthSSL.t
t/30-Auth-and-issuer-SAML-Artifact-with-SOAP-SLO-IdP-initiated.t t/30-Auth-and-issuer-SAML-Artifact-with-SOAP-SLO-IdP-initiated.t
t/30-Auth-and-issuer-SAML-Artifact-with-SOAP-SLO.t t/30-Auth-and-issuer-SAML-Artifact-with-SOAP-SLO.t
t/30-Auth-and-issuer-SAML-Metadata.t t/30-Auth-and-issuer-SAML-Metadata.t
t/30-Auth-and-issuer-SAML-NameID.t
t/30-Auth-and-issuer-SAML-POST-Hook.t t/30-Auth-and-issuer-SAML-POST-Hook.t
t/30-Auth-and-issuer-SAML-POST-IdP-initiated.t t/30-Auth-and-issuer-SAML-POST-IdP-initiated.t
t/30-Auth-and-issuer-SAML-POST-Missing-SLO.t t/30-Auth-and-issuer-SAML-POST-Missing-SLO.t
@ -576,6 +577,7 @@ t/32-OIDC-Hooks.t
t/32-OIDC-Macro.t t/32-OIDC-Macro.t
t/32-OIDC-Offline-Session.t t/32-OIDC-Offline-Session.t
t/32-OIDC-Password-Grant-with-Bruteforce-and-Choice.t t/32-OIDC-Password-Grant-with-Bruteforce-and-Choice.t
t/32-OIDC-Password-Grant.t
t/32-OIDC-Refresh-Token.t t/32-OIDC-Refresh-Token.t
t/32-OIDC-Register.t t/32-OIDC-Register.t
t/32-OIDC-RP-rule.t t/32-OIDC-RP-rule.t
@ -679,6 +681,7 @@ t/65-AutoSignin.t
t/65-CheckState.t t/65-CheckState.t
t/66-CDA-already-auth.t t/66-CDA-already-auth.t
t/66-CDA-PSGI-Try.t t/66-CDA-PSGI-Try.t
t/66-CDA-wildcard.t
t/66-CDA-with-doubleCookies.t t/66-CDA-with-doubleCookies.t
t/66-CDA-with-REST.t t/66-CDA-with-REST.t
t/66-CDA-with-SOAP.t t/66-CDA-with-SOAP.t

View File

@ -240,6 +240,7 @@ sub run {
$self->logger->debug("Looking for expired 2F device(s)..."); $self->logger->debug("Looking for expired 2F device(s)...");
my $removed = 0; my $removed = 0;
my $name = '';
my $now = time(); my $now = time();
foreach my $device (@$_2fDevices) { foreach my $device (@$_2fDevices) {
my $type = lc( $device->{type} ); my $type = lc( $device->{type} );
@ -252,16 +253,18 @@ sub run {
); );
$self->userLogger->info("Remove expired $device->{type}"); $self->userLogger->info("Remove expired $device->{type}");
$device->{type} = 'EXPIRED'; $device->{type} = 'EXPIRED';
$name .= "$device->{name}; ";
$removed++; $removed++;
} }
} }
if ($removed) { if ($removed) {
$name =~ s/;\s$//;
$self->logger->debug( $self->logger->debug(
"Found $removed EXPIRED 2F device(s) => Update persistent session" "Found $removed EXPIRED 2F device(s) => Update persistent session"
); );
$self->userLogger->notice( $self->userLogger->notice(
" -> $removed expired 2F device(s) removed"); " -> $removed expired 2F device(s) removed ($name)");
@$_2fDevices = @$_2fDevices =
map { $_->{type} =~ /\bEXPIRED\b/ ? () : $_ } @$_2fDevices; map { $_->{type} =~ /\bEXPIRED\b/ ? () : $_ } @$_2fDevices;
$self->p->updatePersistentSession( $req, $self->p->updatePersistentSession( $req,
@ -276,13 +279,13 @@ sub run {
my $title = $self->conf->{sfRemovedNotifTitle} my $title = $self->conf->{sfRemovedNotifTitle}
|| 'Second factor notification'; || 'Second factor notification';
my $msg = $self->conf->{sfRemovedNotifMsg} my $msg = $self->conf->{sfRemovedNotifMsg}
|| "$removed expired second factor(s) has/have been removed!"; || "$removed expired second factor(s) has/have been removed ($name)!";
$msg =~ s/_removedSF_/$removed/; $msg =~ s/_removedSF_/$removed/;
$msg =~ s/_nameSF_/$name/;
my $params = my $params =
$removed > 1 $removed > 1
? { trspan => "expired2Fremoved, $removed" } ? { trspan => "expired2Fremoved, $removed, $name" }
: { trspan => "oneExpired2Fremoved" }; : { trspan => "oneExpired2Fremoved, $name" };
my $notifEngine = $self->p->loadedModules->{ my $notifEngine = $self->p->loadedModules->{
'Lemonldap::NG::Portal::Plugins::Notifications'}; 'Lemonldap::NG::Portal::Plugins::Notifications'};
@ -384,8 +387,8 @@ sub run {
# bool public display2fRegisters($req, $session) # bool public display2fRegisters($req, $session)
# #
# Return true if at least 1 register module is available for this user. Used # Return true if at least 1 register module is available for this user.
# by Menu to display or not /2fregisters page # Used by Menu for displaying or not /2fregisters page
sub display2fRegisters { sub display2fRegisters {
my ( $self, $req, $session ) = @_; my ( $self, $req, $session ) = @_;
foreach my $m ( @{ $self->sfRModules } ) { foreach my $m ( @{ $self->sfRModules } ) {

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Enter TOTP code", "enterTotpCode":"Enter TOTP code",
"enterYubikey":"يرجى استخدام يوبي كي الخاص بك", "enterYubikey":"يرجى استخدام يوبي كي الخاص بك",
"errorMsg":"رسالة خاطئة", "errorMsg":"رسالة خاطئة",
"expired2Fremoved":"%s expired 2F devices have been removed!", "expired2Fremoved":"%s expired 2F devices have been removed (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Verification code", "ext2f":"Verification code",
"firstName":"الاسم الاول", "firstName":"الاسم الاول",
@ -225,7 +225,7 @@
"oidcConsent":"التطبيق ٪s هل ترغب في معرفة:", "oidcConsent":"التطبيق ٪s هل ترغب في معرفة:",
"oidcConsents":"OIDC consents", "oidcConsents":"OIDC consents",
"oidcConsentsFull":"OpenID Connect consents", "oidcConsentsFull":"OpenID Connect consents",
"oneExpired2Fremoved":"An expired 2F device has been removed!", "oneExpired2Fremoved":"An expired 2F device has been removed (%s)!",
"openIdExample":"فمثلا:http://myopenid.org/toto", "openIdExample":"فمثلا:http://myopenid.org/toto",
"openSSOSession":"افتح جلسة الدخول الموحد (سسو)", "openSSOSession":"افتح جلسة الدخول الموحد (سسو)",
"openSessionSpace":"هذه المساحة تتيح لك فتح جلسة تسجيل الدخول الموحد (سسو).سوف تساعدك على الوصول بشكل آمن إلى جميع التطبيقات التي أذن بها بروفيل الخاص بك.", "openSessionSpace":"هذه المساحة تتيح لك فتح جلسة تسجيل الدخول الموحد (سسو).سوف تساعدك على الوصول بشكل آمن إلى جميع التطبيقات التي أذن بها بروفيل الخاص بك.",
@ -338,4 +338,4 @@
"yourProfile":"Know your profile", "yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key", "yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Gebe den TOTP Code ein", "enterTotpCode":"Gebe den TOTP Code ein",
"enterYubikey":"Benutze bitte deinen Yubikey", "enterYubikey":"Benutze bitte deinen Yubikey",
"errorMsg":"Fehlermeldung", "errorMsg":"Fehlermeldung",
"expired2Fremoved":"%s expired 2F devices have been removed!", "expired2Fremoved":"%s expired 2F devices have been removed (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Verification code", "ext2f":"Verification code",
"firstName":"Vorname", "firstName":"Vorname",
@ -225,7 +225,7 @@
"oidcConsent":"The application %s would like to:", "oidcConsent":"The application %s would like to:",
"oidcConsents":"OIDC consents", "oidcConsents":"OIDC consents",
"oidcConsentsFull":"OpenID Connect consents", "oidcConsentsFull":"OpenID Connect consents",
"oneExpired2Fremoved":"An expired 2F device has been removed!", "oneExpired2Fremoved":"An expired 2F device has been removed (%s)!",
"openIdExample":"zum Beispiel: http://myopenid.org/toto", "openIdExample":"zum Beispiel: http://myopenid.org/toto",
"openSSOSession":"Eine SSO Sitzung öffnen", "openSSOSession":"Eine SSO Sitzung öffnen",
"openSessionSpace":"Mit diesem Bereich kannst du eine SSO-Sitzung öffnen. Dadurch kannst du sicher auf alle von deinem Profil autorisierten Anwendungen zugreifen.", "openSessionSpace":"Mit diesem Bereich kannst du eine SSO-Sitzung öffnen. Dadurch kannst du sicher auf alle von deinem Profil autorisierten Anwendungen zugreifen.",
@ -292,7 +292,7 @@
"submit":"Absenden", "submit":"Absenden",
"switchContext":"Switch context", "switchContext":"Switch context",
"totp2f":"OTP App", "totp2f":"OTP App",
"totpExistingKey":"Es existiert bereits ein TOTP-Secret", "totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application", "totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application", "totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application", "totpRegisterCode":"Input the code provided by your application",
@ -338,4 +338,4 @@
"yourProfile":"Know your profile", "yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key", "yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Enter TOTP code", "enterTotpCode":"Enter TOTP code",
"enterYubikey":"Please use your Yubikey", "enterYubikey":"Please use your Yubikey",
"errorMsg":"Error Message", "errorMsg":"Error Message",
"expired2Fremoved":"%s expired 2F devices have been removed!", "expired2Fremoved":"%s expired 2F devices have been removed (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Verification code", "ext2f":"Verification code",
"firstName":"First name", "firstName":"First name",
@ -225,7 +225,7 @@
"oidcConsent":"The application %s would like to:", "oidcConsent":"The application %s would like to:",
"oidcConsents":"OIDC consents", "oidcConsents":"OIDC consents",
"oidcConsentsFull":"OpenID Connect consents", "oidcConsentsFull":"OpenID Connect consents",
"oneExpired2Fremoved":"An expired 2F device has been removed!", "oneExpired2Fremoved":"An expired 2F device has been removed (%s)!",
"openIdExample":"for example:http://myopenid.org/toto", "openIdExample":"for example:http://myopenid.org/toto",
"openSSOSession":"Open your SSO session", "openSSOSession":"Open your SSO session",
"openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.", "openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.",

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Ingrese el código TOTP", "enterTotpCode":"Ingrese el código TOTP",
"enterYubikey":"Por favor utilice su Yubikey", "enterYubikey":"Por favor utilice su Yubikey",
"errorMsg":"Mensaje de Error", "errorMsg":"Mensaje de Error",
"expired2Fremoved":"¡%s dispositivos 2F caducados han sido suprimidos!", "expired2Fremoved":"¡%s dispositivos 2F caducados han sido suprimidos (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Código de verificación", "ext2f":"Código de verificación",
"firstName":"Nombre", "firstName":"Nombre",
@ -225,7 +225,7 @@
"oidcConsent":"La aplicación %s quisiera:", "oidcConsent":"La aplicación %s quisiera:",
"oidcConsents":"Permisos OIDC", "oidcConsents":"Permisos OIDC",
"oidcConsentsFull":"Permisos OpenID Connect", "oidcConsentsFull":"Permisos OpenID Connect",
"oneExpired2Fremoved":"¡Un dispositivo 2F caducado ha sido suprimido!", "oneExpired2Fremoved":"¡Un dispositivo 2F caducado ha sido suprimido (%s)!",
"openIdExample":"por ejemplo:http://myopenid.org/juan", "openIdExample":"por ejemplo:http://myopenid.org/juan",
"openSSOSession":"Abra su sesión SSO", "openSSOSession":"Abra su sesión SSO",
"openSessionSpace":"Este espacio le permite abrir una sesión SSO. Esto le ayudará a acceder de manera segura a todas las aplicaciones autorizadas por su perfil.", "openSessionSpace":"Este espacio le permite abrir una sesión SSO. Esto le ayudará a acceder de manera segura a todas las aplicaciones autorizadas por su perfil.",
@ -292,7 +292,7 @@
"submit":"Enviar", "submit":"Enviar",
"switchContext":"Cambiar contexto", "switchContext":"Cambiar contexto",
"totp2f":"Aplicación OTP", "totp2f":"Aplicación OTP",
"totpExistingKey":"Un secreto TOTP ya existe", "totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application", "totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application", "totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application", "totpRegisterCode":"Input the code provided by your application",
@ -338,4 +338,4 @@
"yourProfile":"Conozca su perfil", "yourProfile":"Conozca su perfil",
"yourTotpKey":"Su llave TOTP", "yourTotpKey":"Su llave TOTP",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Enter TOTP code", "enterTotpCode":"Enter TOTP code",
"enterYubikey":"Please use your Yubikey", "enterYubikey":"Please use your Yubikey",
"errorMsg":"Virhe viesti", "errorMsg":"Virhe viesti",
"expired2Fremoved":"%s expired 2F devices have been removed!", "expired2Fremoved":"%s expired 2F devices have been removed (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Verification code", "ext2f":"Verification code",
"firstName":"Etunimi", "firstName":"Etunimi",
@ -225,7 +225,7 @@
"oidcConsent":"The application %s would like to:", "oidcConsent":"The application %s would like to:",
"oidcConsents":"OIDC consents", "oidcConsents":"OIDC consents",
"oidcConsentsFull":"OpenID Connect consents", "oidcConsentsFull":"OpenID Connect consents",
"oneExpired2Fremoved":"An expired 2F device has been removed!", "oneExpired2Fremoved":"An expired 2F device has been removed (%s)!",
"openIdExample":"for example:http://myopenid.org/toto", "openIdExample":"for example:http://myopenid.org/toto",
"openSSOSession":"Open your SSO session", "openSSOSession":"Open your SSO session",
"openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.", "openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.",
@ -338,4 +338,4 @@
"yourProfile":"Know your profile", "yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key", "yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Entrez le code TOTP", "enterTotpCode":"Entrez le code TOTP",
"enterYubikey":"Utilisez votre Yubikey", "enterYubikey":"Utilisez votre Yubikey",
"errorMsg":"Message d'erreur", "errorMsg":"Message d'erreur",
"expired2Fremoved":"%s seconds facteurs expirés ont été supprimés !", "expired2Fremoved":"%s seconds facteurs expirés ont été supprimés (%s) !",
"explorer":"Explorateur", "explorer":"Explorateur",
"ext2f":"Code de vérification", "ext2f":"Code de vérification",
"firstName":"Prénom", "firstName":"Prénom",
@ -225,7 +225,7 @@
"oidcConsent":"L'application %s voudrait :", "oidcConsent":"L'application %s voudrait :",
"oidcConsents":"Accords OIDC", "oidcConsents":"Accords OIDC",
"oidcConsentsFull":"Accords OpenID Connect", "oidcConsentsFull":"Accords OpenID Connect",
"oneExpired2Fremoved":"Un second facteur expiré a été supprimé !", "oneExpired2Fremoved":"Un second facteur expiré a été supprimé (%s) !",
"openIdExample":"par exemple : http://myopenid.org/toto", "openIdExample":"par exemple : http://myopenid.org/toto",
"openSSOSession":"Ouvrir une session SSO", "openSSOSession":"Ouvrir une session SSO",
"openSessionSpace":"Cet espace vous permet d'ouvrir une session SSO. Celle-ci vous aidera à accéder de manière totalement sécurisée à l'ensemble des applications autorisées par votre profil utilisateur.", "openSessionSpace":"Cet espace vous permet d'ouvrir une session SSO. Celle-ci vous aidera à accéder de manière totalement sécurisée à l'ensemble des applications autorisées par votre profil utilisateur.",

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Inserisci il codice TOTP", "enterTotpCode":"Inserisci il codice TOTP",
"enterYubikey":"Utilizza il tuo Yubikey", "enterYubikey":"Utilizza il tuo Yubikey",
"errorMsg":"Messaggio di errore", "errorMsg":"Messaggio di errore",
"expired2Fremoved":"%s expired 2F devices have been removed!", "expired2Fremoved":"%s expired 2F devices have been removed (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Verification code", "ext2f":"Verification code",
"firstName":"Nome", "firstName":"Nome",
@ -225,7 +225,7 @@
"oidcConsent":"L'applicazione %s vorrebbe sapere:", "oidcConsent":"L'applicazione %s vorrebbe sapere:",
"oidcConsents":"Consensi OIDC", "oidcConsents":"Consensi OIDC",
"oidcConsentsFull":"Consensi OpenID Connect", "oidcConsentsFull":"Consensi OpenID Connect",
"oneExpired2Fremoved":"An expired 2F device has been removed!", "oneExpired2Fremoved":"An expired 2F device has been removed (%s)!",
"openIdExample":"per esempio:http://myopenid.org/toto", "openIdExample":"per esempio:http://myopenid.org/toto",
"openSSOSession":"Apri la sessione SSO", "openSSOSession":"Apri la sessione SSO",
"openSessionSpace":"Questo spazio consente di aprire una sessione SSO. Questo vi aiuterà ad accedere in modo sicuro a tutte le applicazioni autorizzate dal tuo profilo.", "openSessionSpace":"Questo spazio consente di aprire una sessione SSO. Questo vi aiuterà ad accedere in modo sicuro a tutte le applicazioni autorizzate dal tuo profilo.",
@ -292,7 +292,7 @@
"submit":"Invia", "submit":"Invia",
"switchContext":"Switch context", "switchContext":"Switch context",
"totp2f":"OTP App", "totp2f":"OTP App",
"totpExistingKey":"Un segreto TOTP esiste già", "totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application", "totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application", "totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application", "totpRegisterCode":"Input the code provided by your application",
@ -338,4 +338,4 @@
"yourProfile":"Know your profile", "yourProfile":"Know your profile",
"yourTotpKey":"La tua chiave TOTP", "yourTotpKey":"La tua chiave TOTP",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Enter TOTP code", "enterTotpCode":"Enter TOTP code",
"enterYubikey":"Please use your Yubikey", "enterYubikey":"Please use your Yubikey",
"errorMsg":"Error Message", "errorMsg":"Error Message",
"expired2Fremoved":"%s expired 2F devices have been removed!", "expired2Fremoved":"%s expired 2F devices have been removed (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Verification code", "ext2f":"Verification code",
"firstName":"First name", "firstName":"First name",
@ -225,7 +225,7 @@
"oidcConsent":"The application %s would like to:", "oidcConsent":"The application %s would like to:",
"oidcConsents":"OIDC consents", "oidcConsents":"OIDC consents",
"oidcConsentsFull":"OpenID Connect consents", "oidcConsentsFull":"OpenID Connect consents",
"oneExpired2Fremoved":"An expired 2F device has been removed!", "oneExpired2Fremoved":"An expired 2F device has been removed (%s)!",
"openIdExample":"for example:http://myopenid.org/toto", "openIdExample":"for example:http://myopenid.org/toto",
"openSSOSession":"Open your SSO session", "openSSOSession":"Open your SSO session",
"openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.", "openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.",
@ -338,4 +338,4 @@
"yourProfile":"Know your profile", "yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key", "yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Wpisz kod TOTP", "enterTotpCode":"Wpisz kod TOTP",
"enterYubikey":"Proszę użyć klucza Yubikey", "enterYubikey":"Proszę użyć klucza Yubikey",
"errorMsg":"Komunikat o błędzie", "errorMsg":"Komunikat o błędzie",
"expired2Fremoved":"%s przeterminowane urządzenia 2F zostały usunięte!", "expired2Fremoved":"%s przeterminowane urządzenia 2F zostały usunięte (%s)!",
"explorer":"Eksplorator", "explorer":"Eksplorator",
"ext2f":"Kod weryfikacyjny", "ext2f":"Kod weryfikacyjny",
"firstName":"Imię", "firstName":"Imię",
@ -225,7 +225,7 @@
"oidcConsent":"Aplikacja %s chciałaby znać:", "oidcConsent":"Aplikacja %s chciałaby znać:",
"oidcConsents":"OIDC wyraża zgodę", "oidcConsents":"OIDC wyraża zgodę",
"oidcConsentsFull":"Zgody OpenID-Connect", "oidcConsentsFull":"Zgody OpenID-Connect",
"oneExpired2Fremoved":"Przeterminowane urządzenie 2F zostało usunięte!", "oneExpired2Fremoved":"Przeterminowane urządzenie 2F zostało usunięte (%s)!",
"openIdExample":"na przykład: http://myopenid.org/toto", "openIdExample":"na przykład: http://myopenid.org/toto",
"openSSOSession":"Otwórz sesję logowania jednokrotnego", "openSSOSession":"Otwórz sesję logowania jednokrotnego",
"openSessionSpace":"Ta przestrzeń umożliwia otwarcie sesji SSO. Pomoże to w bezpiecznym dostępie do wszystkich aplikacji autoryzowanych przez Twój profil.", "openSessionSpace":"Ta przestrzeń umożliwia otwarcie sesji SSO. Pomoże to w bezpiecznym dostępie do wszystkich aplikacji autoryzowanych przez Twój profil.",
@ -292,7 +292,7 @@
"submit":"Zatwierdź", "submit":"Zatwierdź",
"switchContext":"Przełącz kontekst", "switchContext":"Przełącz kontekst",
"totp2f":"Aplikacja OTP", "totp2f":"Aplikacja OTP",
"totpExistingKey":"Sekret TOTP już istnieje", "totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application", "totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application", "totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application", "totpRegisterCode":"Input the code provided by your application",
@ -338,4 +338,4 @@
"yourProfile":"Twój profil", "yourProfile":"Twój profil",
"yourTotpKey":"Twój klucz TOTP", "yourTotpKey":"Twój klucz TOTP",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Enter TOTP code", "enterTotpCode":"Enter TOTP code",
"enterYubikey":"Please use your Yubikey", "enterYubikey":"Please use your Yubikey",
"errorMsg":"Error Message", "errorMsg":"Error Message",
"expired2Fremoved":"%s expired 2F devices have been removed!", "expired2Fremoved":"%s expired 2F devices have been removed (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Verification code", "ext2f":"Verification code",
"firstName":"First name", "firstName":"First name",
@ -225,7 +225,7 @@
"oidcConsent":"The application %s would like to:", "oidcConsent":"The application %s would like to:",
"oidcConsents":"OIDC consents", "oidcConsents":"OIDC consents",
"oidcConsentsFull":"OpenID Connect consents", "oidcConsentsFull":"OpenID Connect consents",
"oneExpired2Fremoved":"An expired 2F device has been removed!", "oneExpired2Fremoved":"An expired 2F device has been removed (%s)!",
"openIdExample":"for example:http://myopenid.org/toto", "openIdExample":"for example:http://myopenid.org/toto",
"openSSOSession":"Open your SSO session", "openSSOSession":"Open your SSO session",
"openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.", "openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.",
@ -338,4 +338,4 @@
"yourProfile":"Know your profile", "yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key", "yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Enter TOTP code", "enterTotpCode":"Enter TOTP code",
"enterYubikey":"Please use your Yubikey", "enterYubikey":"Please use your Yubikey",
"errorMsg":"Error Message", "errorMsg":"Error Message",
"expired2Fremoved":"%s expired 2F devices have been removed!", "expired2Fremoved":"%s expired 2F devices have been removed (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Verification code", "ext2f":"Verification code",
"firstName":"First name", "firstName":"First name",
@ -225,7 +225,7 @@
"oidcConsent":"The application %s would like to:", "oidcConsent":"The application %s would like to:",
"oidcConsents":"OIDC consents", "oidcConsents":"OIDC consents",
"oidcConsentsFull":"OpenID Connect consents", "oidcConsentsFull":"OpenID Connect consents",
"oneExpired2Fremoved":"An expired 2F device has been removed!", "oneExpired2Fremoved":"An expired 2F device has been removed (%s)!",
"openIdExample":"for example:http://myopenid.org/toto", "openIdExample":"for example:http://myopenid.org/toto",
"openSSOSession":"Open your SSO session", "openSSOSession":"Open your SSO session",
"openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.", "openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.",
@ -338,4 +338,4 @@
"yourProfile":"Know your profile", "yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key", "yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"TOTP kodunu gir", "enterTotpCode":"TOTP kodunu gir",
"enterYubikey":"Lütfen Yubikey'inizi kullanın", "enterYubikey":"Lütfen Yubikey'inizi kullanın",
"errorMsg":"Hata Mesajı", "errorMsg":"Hata Mesajı",
"expired2Fremoved":"Kullanım süresi dolan %s2F cihazı kaldırıldı!", "expired2Fremoved":"Kullanım süresi dolan %s2F cihazı kaldırıldı (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Doğrulama kodu", "ext2f":"Doğrulama kodu",
"firstName":"Ad", "firstName":"Ad",
@ -225,7 +225,7 @@
"oidcConsent":"%s uygulaması şunları yapmak istiyor:", "oidcConsent":"%s uygulaması şunları yapmak istiyor:",
"oidcConsents":"OIDC izinleri", "oidcConsents":"OIDC izinleri",
"oidcConsentsFull":"OpenID Connect izinleri", "oidcConsentsFull":"OpenID Connect izinleri",
"oneExpired2Fremoved":"Kullanım süresi dolan bir 2F cihazı kaldırıldı!", "oneExpired2Fremoved":"Kullanım süresi dolan bir 2F cihazı kaldırıldı (%s)!",
"openIdExample":"örneğin: http://myopenid.org/toto", "openIdExample":"örneğin: http://myopenid.org/toto",
"openSSOSession":"TOA oturumunuzu açın", "openSSOSession":"TOA oturumunuzu açın",
"openSessionSpace":"Bu alan bir TOA oturumu açmanıza izin verir. Oturum açtığınızda profiliniz için yetkilendirilmiş tüm uygulamalara güvenli bir şekilde erişebilirsiniz.", "openSessionSpace":"Bu alan bir TOA oturumu açmanıza izin verir. Oturum açtığınızda profiliniz için yetkilendirilmiş tüm uygulamalara güvenli bir şekilde erişebilirsiniz.",
@ -292,7 +292,7 @@
"submit":"Gönder", "submit":"Gönder",
"switchContext":"Bağlam değiştir", "switchContext":"Bağlam değiştir",
"totp2f":"OTP Uygulaması", "totp2f":"OTP Uygulaması",
"totpExistingKey":"Bir TOTP sırrı zaten mevcut", "totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application", "totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application", "totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application", "totpRegisterCode":"Input the code provided by your application",
@ -338,4 +338,4 @@
"yourProfile":"Profilini bil", "yourProfile":"Profilini bil",
"yourTotpKey":"TOTP anahtarınız", "yourTotpKey":"TOTP anahtarınız",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Enter TOTP code", "enterTotpCode":"Enter TOTP code",
"enterYubikey":"Vui lòng sử dụng Yubikey của bạn", "enterYubikey":"Vui lòng sử dụng Yubikey của bạn",
"errorMsg":"Thông báo lỗi", "errorMsg":"Thông báo lỗi",
"expired2Fremoved":"%s expired 2F devices have been removed!", "expired2Fremoved":"%s expired 2F devices have been removed (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Verification code", "ext2f":"Verification code",
"firstName":"Tên", "firstName":"Tên",
@ -225,7 +225,7 @@
"oidcConsent":"Ứng dụng %s muốn biết:", "oidcConsent":"Ứng dụng %s muốn biết:",
"oidcConsents":"OIDC consents", "oidcConsents":"OIDC consents",
"oidcConsentsFull":"OpenID Connect consents", "oidcConsentsFull":"OpenID Connect consents",
"oneExpired2Fremoved":"An expired 2F device has been removed!", "oneExpired2Fremoved":"An expired 2F device has been removed (%s)!",
"openIdExample":"ví dụ: http: //myopenid.org/toto", "openIdExample":"ví dụ: http: //myopenid.org/toto",
"openSSOSession":"Mở phiên SSO của bạn", "openSSOSession":"Mở phiên SSO của bạn",
"openSessionSpace":"Không gian này cho phép bạn mở phiên SSO. Điều này sẽ giúp bạn truy cập an toàn vào tất cả các ứng dụng được cho phép bởi profile của bạn. ", "openSessionSpace":"Không gian này cho phép bạn mở phiên SSO. Điều này sẽ giúp bạn truy cập an toàn vào tất cả các ứng dụng được cho phép bởi profile của bạn. ",
@ -338,4 +338,4 @@
"yourProfile":"Know your profile", "yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key", "yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"Enter TOTP code", "enterTotpCode":"Enter TOTP code",
"enterYubikey":"请使用您的Yubikey", "enterYubikey":"请使用您的Yubikey",
"errorMsg":"错误消息", "errorMsg":"错误消息",
"expired2Fremoved":"%s expired 2F devices have been removed!", "expired2Fremoved":"%s expired 2F devices have been removed (%s)!",
"explorer":"Explorer", "explorer":"Explorer",
"ext2f":"Verification code", "ext2f":"Verification code",
"firstName":"名", "firstName":"名",
@ -225,7 +225,7 @@
"oidcConsent":"The application %s would like to:", "oidcConsent":"The application %s would like to:",
"oidcConsents":"OIDC consents", "oidcConsents":"OIDC consents",
"oidcConsentsFull":"OpenID Connect consents", "oidcConsentsFull":"OpenID Connect consents",
"oneExpired2Fremoved":"An expired 2F device has been removed!", "oneExpired2Fremoved":"An expired 2F device has been removed (%s)!",
"openIdExample":"例如http://myopenid.org/toto", "openIdExample":"例如http://myopenid.org/toto",
"openSSOSession":"Open your SSO session", "openSSOSession":"Open your SSO session",
"openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.", "openSessionSpace":"This space allow you to open a SSO session. This will help you to securely access to all applications authorized by your profile.",
@ -338,4 +338,4 @@
"yourProfile":"Know your profile", "yourProfile":"Know your profile",
"yourTotpKey":"Your TOTP key", "yourTotpKey":"Your TOTP key",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -165,7 +165,7 @@
"enterTotpCode":"輸入 TOTP 代碼", "enterTotpCode":"輸入 TOTP 代碼",
"enterYubikey":"請使用您的 Yubikey", "enterYubikey":"請使用您的 Yubikey",
"errorMsg":"錯誤訊息", "errorMsg":"錯誤訊息",
"expired2Fremoved":"%s 個過期的雙因素驗證已被移除", "expired2Fremoved":"%s 個過期的雙因素驗證已被移除 (%s)",
"explorer":"探索者", "explorer":"探索者",
"ext2f":"驗證代碼", "ext2f":"驗證代碼",
"firstName":"名", "firstName":"名",
@ -225,7 +225,7 @@
"oidcConsent":"應用程式 %s 想要:", "oidcConsent":"應用程式 %s 想要:",
"oidcConsents":"OIDC 同意", "oidcConsents":"OIDC 同意",
"oidcConsentsFull":"OpenID 連線同意", "oidcConsentsFull":"OpenID 連線同意",
"oneExpired2Fremoved":"過期的雙因素驗證裝置已被移除", "oneExpired2Fremoved":"過期的雙因素驗證裝置已被移除 (%s)",
"openIdExample":"例如http://myopenid.org/toto", "openIdExample":"例如http://myopenid.org/toto",
"openSSOSession":"開啟您的 SSO 工作階段", "openSSOSession":"開啟您的 SSO 工作階段",
"openSessionSpace":"此空間讓您可以開啟 SSO 工作階段。這將協助您安全地存取您個人檔案授權的所有應用程式。", "openSessionSpace":"此空間讓您可以開啟 SSO 工作階段。這將協助您安全地存取您個人檔案授權的所有應用程式。",
@ -292,7 +292,7 @@
"submit":"遞交", "submit":"遞交",
"switchContext":"切換內容", "switchContext":"切換內容",
"totp2f":"OTP 應用程式", "totp2f":"OTP 應用程式",
"totpExistingKey":"TOTP 祕密已存在", "totpExistingKey":"A TOTP device is already registered, you must remove it before adding a new TOTP device",
"totpMissingCode":"Please enter the code supplied by your TOTP application", "totpMissingCode":"Please enter the code supplied by your TOTP application",
"totpQrCode":"Scan this QR code in your TOTP application", "totpQrCode":"Scan this QR code in your TOTP application",
"totpRegisterCode":"Input the code provided by your application", "totpRegisterCode":"Input the code provided by your application",
@ -338,4 +338,4 @@
"yourProfile":"知道您的個人檔案", "yourProfile":"知道您的個人檔案",
"yourTotpKey":"您的 TOTP 金鑰", "yourTotpKey":"您的 TOTP 金鑰",
"yubikey2f":"Yubikey" "yubikey2f":"Yubikey"
} }

View File

@ -6,7 +6,7 @@ use JSON qw(to_json from_json);
BEGIN { BEGIN {
require 't/test-lib.pm'; require 't/test-lib.pm';
} }
my $maintests = 64; my $maintests = 88;
SKIP: { SKIP: {
require Lemonldap::NG::Common::TOTP; require Lemonldap::NG::Common::TOTP;
@ -133,6 +133,7 @@ SKIP: {
ok( $res->{result} == 1, 'TOTP is registered' ); ok( $res->{result} == 1, 'TOTP is registered' );
## Try to register an U2F key ## Try to register an U2F key
Time::Fake->offset("+3s");
ok( ok(
$res = $client->_get( $res = $client->_get(
'/2fregisters/u', '/2fregisters/u',
@ -278,6 +279,26 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
expectOK($res); expectOK($res);
expectAuthenticatedAs( $res, 'rtyler' ); expectAuthenticatedAs( $res, 'rtyler' );
# 2fregisters
ok(
$res = $client->_get(
'/2fregisters',
cookie => "lemonldap=$id",
accept => 'text/html',
),
'Form 2fregisters'
);
ok( $res->[2]->[0] =~ /<span id="msg" trspan="choose2f">/,
'Found choose 2F' )
or print STDERR Dumper( $res->[2]->[0] );
my $devices;
ok(
$devices = $res->[2]->[0] =~ s%<span device=\'(?:TOTP|U2F)\' epoch=\'\d{10}\'%%g,
'2F device found'
) or print STDERR Dumper( $res->[2]->[0] );
ok( $devices == 2, '2F devices found' )
or explain( $devices, '2F devices registered' );
# Try to switch context 'dwho' # Try to switch context 'dwho'
# ContextSwitching form # ContextSwitching form
ok( ok(
@ -321,25 +342,8 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_OFF">%, ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_OFF">%,
'Found trspan="contextSwitching_OFF"' ) 'Found trspan="contextSwitching_OFF"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_OFF"' ); or explain( $res->[2]->[0], 'trspan="contextSwitching_OFF"' );
ok( $id2 ne $id, 'New SSO session created' )
# 2fregisters or explain( $id2, 'New SSO session created' );
ok(
$res = $client->_get(
'/2fregisters',
cookie => "lemonldap=$id2",
accept => 'text/html',
),
'Form 2fregisters'
);
ok( $res->[2]->[0] =~ /<span id="msg" trspan="choose2f">/,
'Found choose 2F' )
or print STDERR Dumper( $res->[2]->[0] );
my $devices;
ok( $devices = $res->[2]->[0] =~ s%<span device=\'(TOTP|U2F)\' epoch=\'\d{10}\'%%g,
'2F devices found' )
or print STDERR Dumper( $res->[2]->[0] );
ok( $devices == 2, 'two 2F devices found' )
or explain( $devices, 'Two 2F devices registered' );
## Try to register a TOTP ## Try to register a TOTP
# TOTP form # TOTP form
@ -351,9 +355,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
), ),
'Form registration' 'Form registration'
); );
ok( $res->[2]->[0] =~ /totpregistration\.(?:min\.)?js/, 'Found TOTP js' ) ok( $res->[2]->[0] =~ /totpregistration\.(?:min\.)?js/, 'Found TOTP js' );
or print STDERR Dumper( $res->[2]->[0] );
ok( ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%, $res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%,
'Found custom Main Logo' 'Found custom Main Logo'
@ -371,28 +373,18 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
eval { $res = JSON::from_json( $res->[2]->[0] ) }; eval { $res = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), 'Content is JSON' ) ok( not($@), 'Content is JSON' )
or explain( $res->[2]->[0], 'JSON content' ); or explain( $res->[2]->[0], 'JSON content' );
ok( $res->{error} eq 'totpExistingKey', 'TOTP already registered' ) ok( $key = $res->{secret}, 'Found secret' ) or print STDERR Dumper($res);
or explain( $res, 'Bad result' ); ok( $token = $res->{token}, 'Found token' ) or print STDERR Dumper($res);
ok( $res->{user} eq 'dwho', 'Found user' )
or print STDERR Dumper($res);
$key = Convert::Base32::decode_base32($key);
# Try to unregister TOTP # Post code
ok( ok( $code = Lemonldap::NG::Common::TOTP::_code( undef, $key, 0, 30, 6 ),
$res = $client->_post( 'Code' );
'/2fregisters/totp/delete', ok( $code =~ /^\d{6}$/, 'Code contains 6 digits' );
IO::String->new("epoch=1234567890"), my $s = "code=$code&token=$token&TOTPName=myTOTP";
length => 16, my $epoch = time();
cookie => "lemonldap=$id2",
),
'Delete TOTP query'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok(
$data->{error} eq '2FDeviceNotFound', '2F device not found'
) or explain( $data, 'Bad result' );
# Try to verify TOTP
$s = "code=123456&token=1234567890&TOTPName=myTOTP";
ok( ok(
$res = $client->_post( $res = $client->_post(
'/2fregisters/totp/verify', '/2fregisters/totp/verify',
@ -402,61 +394,199 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
), ),
'Post code' 'Post code'
); );
eval { $data = JSON::from_json( $res->[2]->[0] ) }; eval { $res = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' ) ok( not($@), 'Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' ); or explain( $res->[2]->[0], 'JSON content' );
ok( $data->{error} eq 'PE82', 'PE82' ) ok( $res->{result} == 1, 'TOTP is registered' );
or explain( $data, 'Bad result' );
## Try to register an U2F key # 2fregisters
# U2F form
ok( ok(
$res = $client->_get( $res = $client->_get(
'/2fregisters/u', '/2fregisters',
cookie => "lemonldap=$id2", cookie => "lemonldap=$id2",
accept => 'text/html', accept => 'text/html',
), ),
'Form registration' 'Form 2fregisters'
); );
ok( $res->[2]->[0] =~ /u2fregistration\.(?:min\.)?js/, 'Found U2F js' ); ok( $res->[2]->[0] =~ /<span id="msg" trspan="choose2f">/,
'Found choose 2F' )
or print STDERR Dumper( $res->[2]->[0] );
my $devices;
ok( ok(
$res->[2]->[0] =~ qr%<img src="/static/common/logos/logo_llng_old.png"%, $devices = $res->[2]->[0] =~ s%<span device=\'TOTP\' epoch=\'\d{10}\'%%g,
'Found custom Main Logo' '2F device found'
) or print STDERR Dumper( $res->[2]->[0] ); ) or print STDERR Dumper( $res->[2]->[0] );
ok( $devices == 1, '2F device found' )
or explain( $devices, '2F device registered' );
# Ajax registration request # Try to unregister TOTP
ok( ok(
$res = $client->_post( $res = $client->_post(
'/2fregisters/u/register', IO::String->new(''), '/2fregisters/totp/delete',
accept => 'application/json', IO::String->new("epoch=$epoch"),
cookie => "lemonldap=$id2",
length => 0,
),
'Get registration challenge'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok(
$data->{challenge} =~ /\w+/, 'Get challenge'
) or explain( $data, 'Bad result' );
# Try to unregister U2F key
ok(
$res = $client->_post(
'/2fregisters/u/delete',
IO::String->new("epoch=1234567890"),
length => 16, length => 16,
cookie => "lemonldap=$id2", cookie => "lemonldap=$id2",
), ),
'Delete U2F key query' 'Delete TOTP query'
); );
eval { $data = JSON::from_json( $res->[2]->[0] ) }; eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' ) ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' ); or explain( [ $@, $res->[2] ], 'JSON content' );
ok( $data->{result} == 1, 'TOTP removed' )
or explain( $data, '"result":1' );
$client->logout($id);
$client->logout($id2);
## Try to authenticate
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
( $host, $url, $query ) =
expectForm( $res, '#', undef, 'user', 'password' );
$query =~ s/user=/user=dwho/;
$query =~ s/password=/password=dwho/;
ok( ok(
$data->{error} eq '2FDeviceNotFound', '2F device not found' $res = $client->_post(
) or explain( $data, 'Bad result' ); '/',
IO::String->new($query),
length => length($query),
accept => 'text/html',
),
'Auth query'
);
$id = expectCookie($res);
expectRedirection( $res, 'http://auth.example.com/' );
# Get Menu
# ------------------------
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'Get Menu',
);
expectOK($res);
ok(
$res->[2]->[0] =~
m%<span trspan="connectedAs">Connected as</span> dwho%,
'Connected as dwho'
) or print STDERR Dumper( $res->[2]->[0] );
expectAuthenticatedAs( $res, 'dwho' );
ok(
$res->[2]->[0] =~
m%<span trspan="contextSwitching_ON">contextSwitching_ON</span>%,
'contextSwitching allowed'
) or print STDERR Dumper( $res->[2]->[0] );
# Try to switch context 'rtyler'
# ContextSwitching form
ok(
$res = $client->_get(
'/switchcontext',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'ContextSwitching form',
);
( $host, $url, $query ) =
expectForm( $res, undef, '/switchcontext', 'spoofId' );
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_ON">%,
'Found trspan="contextSwitching_ON"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_ON"' );
## POST form
$query =~ s/spoofId=/spoofId=rtyler/;
ok(
$res = $client->_post(
'/switchcontext',
IO::String->new($query),
cookie => "lemonldap=$id",
length => length($query),
accept => 'text/html',
),
'POST switchcontext'
);
expectRedirection( $res, 'http://auth.example.com/' );
$id2 = expectCookie($res);
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id2",
accept => 'text/html'
),
'Get Menu',
);
expectAuthenticatedAs( $res, 'rtyler' );
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_OFF">%,
'Found trspan="contextSwitching_OFF"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_OFF"' );
ok( $id2 ne $id, 'New SSO session created' )
or explain( $id2, 'New SSO session created' );
# 2fregisters
ok(
$res = $client->_get(
'/2fregisters',
cookie => "lemonldap=$id2",
accept => 'text/html',
),
'Form 2fregisters'
);
ok( $res->[2]->[0] =~ /<span id="msg" trspan="choose2f">/,
'Found choose 2F' )
or print STDERR Dumper( $res->[2]->[0] );
ok(
$res->[2]->[0] =~ m%<span device=\'TOTP\' epoch=\'(\d{10})\'%,
'TOTP found'
) or print STDERR Dumper( $res->[2]->[0] );
$epoch = $1;
ok(
$devices = $res->[2]->[0] =~ s%<span device=\'(?:TOTP|U2F)\' epoch=\'(?:\d{10})\'%%g,
'2F devices found'
) or print STDERR Dumper( $res->[2]->[0] );
ok( $devices == 2, '2F devices registered' )
or explain( $devices, '2F devices registered' );
# Try to unregister TOTP
ok(
$res = $client->_post(
'/2fregisters/totp/delete',
IO::String->new("epoch=$epoch"),
length => 16,
cookie => "lemonldap=$id2",
),
'Delete TOTP query'
);
eval { $data = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), ' Content is JSON' )
or explain( [ $@, $res->[2] ], 'JSON content' );
ok( $data->{result} == 1, '2F removed' )
or explain( $data, '"result":1' );
# 2fregisters
ok(
$res = $client->_get(
'/2fregisters',
cookie => "lemonldap=$id2",
accept => 'text/html',
),
'Form 2fregisters'
);
ok( $res->[2]->[0] =~ /<span trspan="remove2fWarning">/,
'Found 2F modal' )
or print STDERR Dumper( $res->[2]->[0] );
ok( $res->[2]->[0] =~ /<span id="msg" trspan="choose2f">/,
'Found choose 2F' )
or print STDERR Dumper( $res->[2]->[0] );
ok(
$devices = $res->[2]->[0] =~ s%<span device=\'(?:TOTP|U2F)\' epoch=\'(\d{10})\'%%g,
'2F device found'
) or print STDERR Dumper( $res->[2]->[0] );
ok( $devices == 1, '2F device registered' )
or explain( $devices, '2F device registered' );
$client->logout($id); $client->logout($id);
$client->logout($id2); $client->logout($id2);

View File

@ -6,7 +6,7 @@ use JSON qw(to_json from_json);
BEGIN { BEGIN {
require 't/test-lib.pm'; require 't/test-lib.pm';
} }
my $maintests = 63; my $maintests = 76;
SKIP: { SKIP: {
require Lemonldap::NG::Common::TOTP; require Lemonldap::NG::Common::TOTP;
@ -460,6 +460,108 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
$client->logout($id); $client->logout($id);
$client->logout($id2); $client->logout($id2);
## Try to authenticate
ok( $res = $client->_get( '/', accept => 'text/html' ), 'Get Menu', );
( $host, $url, $query ) =
expectForm( $res, '#', undef, 'user', 'password' );
$query =~ s/user=/user=dwho/;
$query =~ s/password=/password=dwho/;
ok(
$res = $client->_post(
'/',
IO::String->new($query),
length => length($query),
accept => 'text/html',
),
'Auth query'
);
$id = expectCookie($res);
expectRedirection( $res, 'http://auth.example.com/' );
# Get Menu
# ------------------------
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'Get Menu',
);
expectOK($res);
ok(
$res->[2]->[0] =~
m%<span trspan="connectedAs">Connected as</span> dwho%,
'Connected as dwho'
) or print STDERR Dumper( $res->[2]->[0] );
expectAuthenticatedAs( $res, 'dwho' );
ok(
$res->[2]->[0] =~
m%<span trspan="contextSwitching_ON">contextSwitching_ON</span>%,
'contextSwitching allowed'
) or print STDERR Dumper( $res->[2]->[0] );
# Try to switch context 'rtyler'
# ContextSwitching form
ok(
$res = $client->_get(
'/switchcontext',
cookie => "lemonldap=$id",
accept => 'text/html'
),
'ContextSwitching form',
);
( $host, $url, $query ) =
expectForm( $res, undef, '/switchcontext', 'spoofId' );
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_ON">%,
'Found trspan="contextSwitching_ON"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_ON"' );
## POST form
$query =~ s/spoofId=/spoofId=rtyler/;
ok(
$res = $client->_post(
'/switchcontext',
IO::String->new($query),
cookie => "lemonldap=$id",
length => length($query),
accept => 'text/html',
),
'POST switchcontext'
);
expectRedirection( $res, 'http://auth.example.com/' );
$id2 = expectCookie($res);
ok(
$res = $client->_get(
'/',
cookie => "lemonldap=$id2",
accept => 'text/html'
),
'Get Menu',
);
expectAuthenticatedAs( $res, 'rtyler' );
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_OFF">%,
'Found trspan="contextSwitching_OFF"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_OFF"' );
# 2fregisters
ok(
$res = $client->_get(
'/2fregisters',
cookie => "lemonldap=$id2",
accept => 'text/html',
),
'Form 2fregisters'
);
ok( $res->[2]->[0] =~ /<span id="msg" trspan="notAuthorized">/,
'Found choose 2F' )
or print STDERR Dumper( $res->[2]->[0] );
ok( $res->[2]->[0] !~ m%<span device=\'(TOTP|U2F)\' epoch=\'\d{10}\'%g,
'No 2F device found' )
or print STDERR Dumper( $res->[2]->[0] );
} }
count($maintests); count($maintests);

View File

@ -99,8 +99,11 @@ ok(
'POST switchcontext' 'POST switchcontext'
); );
expectRedirection( $res, 'http://auth.example.com/' ); expectRedirection( $res, 'http://auth.example.com/' );
# Refresh cookie value # Refresh cookie value
my $id2 = expectCookie($res); my $id2 = expectCookie($res);
ok( $id2 ne $id, 'New SSO session created' )
or explain( $id2, 'New SSO session created' );
ok( ok(
$res = $client->_get( $res = $client->_get(
'/', '/',
@ -121,10 +124,17 @@ ok(
), ),
'Stop context switching rtyler', 'Stop context switching rtyler',
); );
count(6); ok(
$res = $client->_get(
# Refresh cookie value '/',
$id = expectCookie($res); cookie => "lemonldap=$id2",
accept => 'text/html'
),
'Get Menu',
);
ok( $res->[2]->[0] =~ m%<span trmsg="1">%, 'Found PE_SESSIONEXPIRED' )
or explain( $res->[2]->[0], 'Session expired' );
count(9);
# ContextSwitching form: dwho -> french # ContextSwitching form: dwho -> french
# ------------------------ # ------------------------
@ -153,8 +163,11 @@ ok(
'POST switchcontext' 'POST switchcontext'
); );
expectRedirection( $res, 'http://auth.example.com/' ); expectRedirection( $res, 'http://auth.example.com/' );
# Refresh cookie value # Refresh cookie value
$id2 = expectCookie($res); $id2 = expectCookie($res);
ok( $id2 ne $id, 'New SSO session created' )
or explain( $id2, 'New SSO session created' );
ok( ok(
$res = $client->_get( $res = $client->_get(
'/', '/',
@ -167,7 +180,7 @@ expectAuthenticatedAs( $res, 'french' );
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_OFF">%, ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_OFF">%,
'Found trspan="contextSwitching_OFF"' ) 'Found trspan="contextSwitching_OFF"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_OFF"' ); or explain( $res->[2]->[0], 'trspan="contextSwitching_OFF"' );
count(5); count(6);
# CheckUser request # CheckUser request
ok( ok(
@ -180,11 +193,14 @@ eval { $res = JSON::from_json( $res->[2]->[0] ) };
ok( not($@), 'Content is JSON' ) ok( not($@), 'Content is JSON' )
or explain( $res->[2]->[0], 'JSON content' ); or explain( $res->[2]->[0], 'JSON content' );
my @sessions_id = my @sessions_id =
map { $_->{key} =~ /_session_id$/ ? $_ : () } @{ $res->{ATTRIBUTES} }; map { $_->{key} =~ /^switching_session_id$/ ? $_ : () }
@{ $res->{ATTRIBUTES} };
ok( $sessions_id[0]->{value} eq $id, 'Good switching_id found' ) ok( $sessions_id[0]->{value} eq $id, 'Good switching_id found' )
or explain( $sessions_id[0]->{value}, 'Switching_session_id' ); or explain( $sessions_id[0]->{value}, 'switching_session_id' );
ok( $sessions_id[1]->{value} eq $id, 'Good Real_session_id found' ) my @real_values =
or explain( $sessions_id[1]->{value}, 'Real_session_id' ); map { $_->{key} =~ /^real_/ ? $_ : () } @{ $res->{ATTRIBUTES} };
ok( scalar @real_values == 0, 'No real value found' )
or explain( scalar(@real_values), 'Found real value' );
count(4); count(4);
ok( ok(

View File

@ -287,12 +287,14 @@ ok(
'POST switchcontext' 'POST switchcontext'
); );
# Refresh cookie value # Get cookie value
$id = expectCookie($res); my $id1 = expectCookie($res);
ok( $id1 ne $id, 'New SSO session created' )
or explain( $id1, 'New SSO session created' );
ok( ok(
$res = $client->_get( $res = $client->_get(
'/', '/',
cookie => "lemonldap=$id", cookie => "lemonldap=$id1",
accept => 'text/html' accept => 'text/html'
), ),
'Get Menu', 'Get Menu',
@ -305,35 +307,37 @@ ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_OFF">%,
ok( ok(
$res = $client->_get( $res = $client->_get(
'/switchcontext', '/switchcontext',
cookie => "lemonldap=$id", cookie => "lemonldap=$id1",
accept => 'text/html' accept => 'text/html'
), ),
'Stop context switching', 'Stop context switching',
); );
count(2);
# Refresh cookie value # Get cookie value
my $id1 = expectCookie($res); my $id0 = expectCookie($res);
ok( $id0 eq $id, 'New SSO session created' )
or explain( $id0, 'New SSO session created' );
ok( ok(
$res = $client->_get( $res = $client->_get(
'/', '/',
cookie => "lemonldap=$id1", cookie => "lemonldap=$id",
accept => 'text/html' accept => 'text/html'
), ),
'Get Menu', 'Get Menu',
); );
count(3);
expectAuthenticatedAs( $res, 'dwho' ); expectAuthenticatedAs( $res, 'dwho' );
ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_ON">%, ok( $res->[2]->[0] =~ m%<span trspan="contextSwitching_ON">%,
'Found trspan="contextSwitching_ON"' ) 'Found trspan="contextSwitching_ON"' )
or explain( $res->[2]->[0], 'trspan="contextSwitching_ON"' ); or explain( $res->[2]->[0], 'trspan="contextSwitching_ON"' );
count(1); count(4);
# ContextSwitching form -> PE_OK # ContextSwitching form -> PE_OK
# ------------------------ # ------------------------
ok( ok(
$res = $client->_get( $res = $client->_get(
'/switchcontext', '/switchcontext',
cookie => "lemonldap=$id1", cookie => "lemonldap=$id",
accept => 'text/html' accept => 'text/html'
), ),
'ContextSwitching form', 'ContextSwitching form',
@ -349,16 +353,20 @@ ok(
$res = $client->_post( $res = $client->_post(
'/switchcontext', '/switchcontext',
IO::String->new($query), IO::String->new($query),
cookie => "lemonldap=$id1", cookie => "lemonldap=$id",
length => length($query), length => length($query),
accept => 'text/html', accept => 'text/html',
), ),
'POST switchcontext' 'POST switchcontext'
); );
count(3);
# Refresh cookie value # Refresh cookie value
my $id2 = expectCookie($res); my $id2 = expectCookie($res);
$client->logout($id1); ok( $id2 ne $id, 'New SSO session created' )
or explain( $id2, 'New SSO session created' );
$client->logout($id);
ok( ok(
$res = $client->_get( $res = $client->_get(
@ -382,7 +390,7 @@ ok(
), ),
'Stop context switching', 'Stop context switching',
); );
count(6); count(4);
ok( $res->[2]->[0] =~ m%<span trmsg="1">%, 'Found PE_SESSIONEXPIRED' ) ok( $res->[2]->[0] =~ m%<span trmsg="1">%, 'Found PE_SESSIONEXPIRED' )
or explain( $res->[2]->[0], 'Session expired' ); or explain( $res->[2]->[0], 'Session expired' );

View File

@ -263,7 +263,7 @@ qr%<input type="hidden" name="reference1x1" value="RemoveSF-(\d{10})"/>%,
or print STDERR Dumper( $res->[2]->[0] ), time(), " / $1"; or print STDERR Dumper( $res->[2]->[0] ), time(), " / $1";
ok( ok(
$res->[2]->[0] =~ $res->[2]->[0] =~
qr%<p class="notifText">1 expired second factor\(s\) has/have been removed!</p>%, qr%<p class="notifText">1 expired second factor\(s\) has/have been removed \(\d{10}\)!</p>%,
'Notification message found' 'Notification message found'
) or print STDERR Dumper( $res->[2]->[0] ); ) or print STDERR Dumper( $res->[2]->[0] );
$id = expectCookie($res); $id = expectCookie($res);
@ -298,7 +298,7 @@ qr%<input type="hidden" name="reference1x2" value="RemoveSF-(\d{10})"/>%,
or print STDERR Dumper( $res->[2]->[0] ), time(), " / $1"; or print STDERR Dumper( $res->[2]->[0] ), time(), " / $1";
my @notifs = my @notifs =
( $res->[2]->[0] =~ ( $res->[2]->[0] =~
m%<p class="notifText">1 expired second factor\(s\) has/have been removed!</p>%gs m%<p class="notifText">1 expired second factor\(s\) has/have been removed \((?:myTOTP|\d{10})\)!</p>%gs
); );
ok( 2 == @notifs, '2 notifications found' ) ok( 2 == @notifs, '2 notifications found' )
or print STDERR Dumper( $res->[2]->[0] ); or print STDERR Dumper( $res->[2]->[0] );

View File

@ -14,16 +14,17 @@ SKIP: {
my $client = LLNG::Manager::Test->new( { my $client = LLNG::Manager::Test->new( {
ini => { ini => {
logLevel => 'error', logLevel => 'error',
totp2fSelfRegistration => 1, totp2fSelfRegistration => 1,
totp2fActivation => 1, totp2fActivation => 1,
totp2fTTL => 120, totp2fTTL => 120,
sfRemovedMsgRule => '$uid eq "dwho"', sfRemovedMsgRule => '$uid eq "dwho"',
sfRemovedUseNotif => 1, sfRemovedUseNotif => 1,
sfRemovedNotifRef => 'Remov_e_TOTP', sfRemovedNotifRef => 'Remov_e_TOTP',
portalMainLogo => 'common/logos/logo_llng_old.png', sfRemovedNotifMsg => '_removedSF_ SF removed = _nameSF_',
notification => 1, portalMainLogo => 'common/logos/logo_llng_old.png',
notificationStorage => 'File', notification => 1,
notificationStorage => 'File',
notificationStorageOptions => { dirName => $main::tmpDir }, notificationStorageOptions => { dirName => $main::tmpDir },
oldNotifFormat => 0, oldNotifFormat => 0,
} }
@ -153,7 +154,7 @@ qr%<input type="hidden" name="reference1x1" value="Remov-e-TOTP-(\d{10})"/>%,
or print STDERR Dumper( $res->[2]->[0] ), time(), " / $1"; or print STDERR Dumper( $res->[2]->[0] ), time(), " / $1";
ok( ok(
$res->[2]->[0] =~ $res->[2]->[0] =~
qr%<p class="notifText">1 expired second factor\(s\) has/have been removed!</p>%, qr%<p class="notifText">1 SF removed = myTOTP</p>%,
'Notification message found' 'Notification message found'
) or print STDERR Dumper( $res->[2]->[0] ); ) or print STDERR Dumper( $res->[2]->[0] );
$id = expectCookie($res); $id = expectCookie($res);

View File

@ -157,7 +157,7 @@ qr%<input type="hidden" name="reference1x1" value="Remove-TOTP-(\d{10})">%,
or print STDERR Dumper( $res->[2]->[0] ), time(), " / $1"; or print STDERR Dumper( $res->[2]->[0] ), time(), " / $1";
ok( ok(
$res->[2]->[0] =~ $res->[2]->[0] =~
qr%<p class="notifText">1 expired second factor\(s\) has/have been removed!</p>%, qr%<p class="notifText">1 expired second factor\(s\) has/have been removed \(myTOTP\)!</p>%,
'Notification message found' 'Notification message found'
) or print STDERR Dumper( $res->[2]->[0] ); ) or print STDERR Dumper( $res->[2]->[0] );
$id = expectCookie($res); $id = expectCookie($res);

View File

@ -218,7 +218,7 @@ JjTJecOOS+88fK8qL1TrYv5rapIdqUI7aQ==
expectOK($res); expectOK($res);
ok( ok(
$res->[2]->[0] =~ $res->[2]->[0] =~
qr%<h3 trspan="oneExpired2Fremoved">oneExpired2Fremoved</h3>%, qr%<h3 trspan="oneExpired2Fremoved, \d{10}">oneExpired2Fremoved, \d{10}</h3>%,
'Found expired 2F message' 'Found expired 2F message'
) or print STDERR Dumper( $res->[2]->[0] ); ) or print STDERR Dumper( $res->[2]->[0] );
my $c = getCookies($res); my $c = getCookies($res);