Merge branch 'v2.0'
This commit is contained in:
commit
2323c031ec
|
@ -60,6 +60,7 @@ sub defaultValues {
|
|||
'cspStyle' => '\'self\'',
|
||||
'dbiAuthnLevel' => 2,
|
||||
'dbiExportedVars' => {},
|
||||
'decryptValueRule' => 0,
|
||||
'demoExportedVars' => {
|
||||
'cn' => 'cn',
|
||||
'mail' => 'mail',
|
||||
|
|
|
@ -800,8 +800,13 @@ sub getKey {
|
|||
unless ($key) {
|
||||
return $self->metadata($req);
|
||||
}
|
||||
$self->userLogger->info(
|
||||
'User ' . $self->userId($req) . " asks for key $key" );
|
||||
if ( $self->can('userId') ) {
|
||||
$self->userLogger->info(
|
||||
'User ' . $self->userId($req) . " asks for key $key" );
|
||||
}
|
||||
else {
|
||||
$self->logger->info("REST request to get configuration key $key");
|
||||
}
|
||||
my $value = $self->getConfKey( $req, $key );
|
||||
return $self->sendError( $req, undef, 400 ) if ( $req->error );
|
||||
|
||||
|
|
|
@ -55,6 +55,9 @@ t/64-Lemonldap-NG-Handler-PSGI-DevOps.t
|
|||
t/65-Lemonldap-NG-Handler-PSGI-ServiceToken.t
|
||||
t/66-Lemonldap-NG-Handler-PSGI-wildcard.t
|
||||
t/67-Lemonldap-NG-Handler-PSGI-vhostoptions.t
|
||||
t/68-Lemonldap-NG-Handler-PSGI-Zimbra.t
|
||||
t/69-Lemonldap-NG-Handler-PSGI-SecureToken.t
|
||||
t/70-Lemonldap-NG-Handler-PSGI-AuthBasic.t
|
||||
t/99-pod.t
|
||||
t/lmConf-1.json
|
||||
t/sessions/lock/Apache-Session-f5eec18ebb9bc96352595e2d8ce962e8ecf7af7c9a98cb9a43f9cd181cf4b545.lock
|
||||
|
|
|
@ -15,6 +15,7 @@ our $VERSION = '2.1.0';
|
|||
our @ISA = ('Exporter');
|
||||
our @EXPORT = qw(fetchId retrieveSession createSession hideCookie goToPortal);
|
||||
our @EXPORT_OK = @EXPORT;
|
||||
our $_ua;
|
||||
|
||||
## @rmethod protected fetchId
|
||||
# Get user session id from Authorization header
|
||||
|
@ -162,8 +163,6 @@ sub goToPortal {
|
|||
}
|
||||
}
|
||||
|
||||
our $_ua;
|
||||
|
||||
sub ua {
|
||||
my ($class) = @_;
|
||||
return $_ua if ($_ua);
|
||||
|
@ -173,7 +172,6 @@ sub ua {
|
|||
}
|
||||
);
|
||||
|
||||
# TODO: auth basic
|
||||
return $_ua;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ sub run {
|
|||
my ( $class, $req, $rule, $protection ) = @_;
|
||||
my $uri = $req->{env}->{REQUEST_URI};
|
||||
my $cn = $class->tsv->{cookieName};
|
||||
my ( $id, $session );
|
||||
my ( $id, $ret, $session );
|
||||
if ( $uri =~ s/[\?&;]${cn}cda=(\w+)$//oi ) {
|
||||
if ( $id = $class->fetchId($req)
|
||||
and $session = $class->retrieveSession( $req, $id ) )
|
||||
|
@ -48,8 +48,10 @@ sub run {
|
|||
return $class->REDIRECT;
|
||||
}
|
||||
}
|
||||
return $class->Lemonldap::NG::Handler::Main::run( $req, $rule,
|
||||
$protection );
|
||||
( $ret, $session ) =
|
||||
$class->Lemonldap::NG::Handler::Main::run( $req, $rule, $protection );
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
## @rmethod protected hash getCDAInfos(id)
|
||||
|
|
|
@ -32,7 +32,7 @@ BEGIN {
|
|||
# @return Apache2::Const value ($class->OK, $class->FORBIDDEN, $class->REDIRECT or $class->SERVER_ERROR)
|
||||
sub run {
|
||||
my $class = shift;
|
||||
my $r = $_[0];
|
||||
my $r = shift;
|
||||
my ( $ret, $session ) = $class->Lemonldap::NG::Handler::Main::run($r);
|
||||
|
||||
# Continue only if user is authorized
|
||||
|
@ -106,7 +106,7 @@ sub run {
|
|||
# Remove token
|
||||
eval 'use Apache2::Filter' unless ( $INC{"Apache2/Filter.pm"} );
|
||||
|
||||
if ( $INC{"Apache2/Filter.pm"} ) {
|
||||
if ( $INC{"Apache2/Filter.pm"} and defined $r->{env}->{'psgi.r'} ) {
|
||||
$r->{env}->{'psgi.r'}->add_output_filter(
|
||||
sub {
|
||||
my $f = shift;
|
||||
|
@ -121,7 +121,6 @@ sub run {
|
|||
);
|
||||
}
|
||||
|
||||
# Return $class->OK
|
||||
return $class->OK;
|
||||
}
|
||||
|
||||
|
@ -150,9 +149,7 @@ sub _createMemcachedConnection {
|
|||
# @return Token key
|
||||
sub _setToken {
|
||||
my ( $class, $value, $secureTokenExpiration ) = @_;
|
||||
|
||||
my $key = Apache::Session::Generate::MD5::generate();
|
||||
|
||||
my $res =
|
||||
$secureTokenMemcachedConnection->set( $key, $value,
|
||||
$secureTokenExpiration );
|
||||
|
@ -173,7 +170,6 @@ sub _setToken {
|
|||
# @return result
|
||||
sub _deleteToken {
|
||||
my ( $class, $key ) = @_;
|
||||
|
||||
my $res = $secureTokenMemcachedConnection->delete($key);
|
||||
|
||||
unless ($res) {
|
||||
|
@ -192,16 +188,13 @@ sub _deleteToken {
|
|||
# @return result
|
||||
sub _isAlive {
|
||||
my ($class) = @_;
|
||||
|
||||
return 0 unless defined $secureTokenMemcachedConnection;
|
||||
|
||||
my $stats = $secureTokenMemcachedConnection->stats();
|
||||
|
||||
if ( $stats and defined $stats->{'total'} ) {
|
||||
my $total_c = $stats->{'total'}->{'connection_structures'};
|
||||
my $total_i = $stats->{'total'}->{'total_items'};
|
||||
|
||||
$class->logger->debug->(
|
||||
$class->logger->debug(
|
||||
"Memcached connection is alive ($total_c connections / $total_i items)"
|
||||
);
|
||||
|
||||
|
|
|
@ -98,9 +98,10 @@ sub portalConsts {
|
|||
'92' => 'PE_GET_SERVICE_NOT_ALLOWED',
|
||||
'93' => 'PE_IMPERSONATION_SERVICE_NOT_ALLOWED',
|
||||
'94' => 'PE_ISSUERMISSINGREQATTR',
|
||||
'95' => 'PE_RESETCERTIFICATE_INVALID',
|
||||
'96' => 'PE_RESETCERTIFICATE_FORMEMPTY',
|
||||
'97' => 'PE_RESETCERTIFICATE_FIRSTACCESS'
|
||||
'95' => 'PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED',
|
||||
'96' => 'PE_RESETCERTIFICATE_INVALID',
|
||||
'97' => 'PE_RESETCERTIFICATE_FORMEMPTY',
|
||||
'98' => 'PE_RESETCERTIFICATE_FIRSTACCESS'
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ my $dir = dirname( abs_path($0) );
|
|||
|
||||
print $ini "[all]
|
||||
logger = Lemonldap::NG::Common::Logger::Std
|
||||
logLeval = error
|
||||
logLevel = error
|
||||
[configuration]
|
||||
type=File
|
||||
dirName=$dir
|
||||
|
@ -32,7 +32,6 @@ open STDERR, '>/dev/null';
|
|||
|
||||
# Insert your test code below, the Test::More module is used here so read
|
||||
# its man page ( perldoc Test::More ) for help writing this test script.
|
||||
|
||||
SKIP: {
|
||||
eval { require Cache::Memcached };
|
||||
skip
|
||||
|
|
|
@ -15,6 +15,7 @@ my $dir = dirname( abs_path($0) );
|
|||
|
||||
print $ini "[all]
|
||||
logger = Lemonldap::NG::Common::Logger::Std
|
||||
logLevel = error
|
||||
[configuration]
|
||||
type=File
|
||||
dirName=$dir
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
use Test::More;
|
||||
|
||||
BEGIN {
|
||||
require 't/test-psgi-lib.pm';
|
||||
}
|
||||
|
||||
my $maintests = 8;
|
||||
|
||||
SKIP: {
|
||||
eval { require Digest::HMAC_SHA1; };
|
||||
if ($@) {
|
||||
skip 'Digest::HMAC_SHA1 not found', $maintests;
|
||||
}
|
||||
init(
|
||||
'Lemonldap::NG::Handler::Server',
|
||||
{
|
||||
logLevel => 'error',
|
||||
zimbraPreAuthKey => '1234567890',
|
||||
zimbraUrl => '/service/preauthtest',
|
||||
zimbraSsoUrl => '^/testsso',
|
||||
vhostOptions => {
|
||||
'test1.example.com' => {
|
||||
vhostHttps => 0,
|
||||
vhostPort => 80,
|
||||
vhostMaintenance => 0,
|
||||
vhostServiceTokenTTL => -1,
|
||||
},
|
||||
},
|
||||
exportedHeaders => {
|
||||
'test1.example.com' => {
|
||||
'Auth-User' => '$uid',
|
||||
},
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
# Request a non-Zimbra URL
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/test', undef,
|
||||
'test1.example.com', "lemonldap=$sessionId",
|
||||
VHOSTTYPE => 'ZimbraPreAuth',
|
||||
),
|
||||
'Non-Zimbra URL Query'
|
||||
);
|
||||
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res->[0], 200 );
|
||||
|
||||
# Check headers
|
||||
%h = @{ $res->[1] };
|
||||
ok( !defined $h{'Location'}, 'Location is undefined' )
|
||||
or explain( \%h, 'Location => "URL"' );
|
||||
ok( $h{'Auth-User'} eq 'dwho', 'Header Auth-User is set to "dwho"' )
|
||||
or explain( \%h, 'Auth-User => "dwho"' );
|
||||
|
||||
# Request Zimbra URL
|
||||
my $timestamp = time() * 1000;
|
||||
my $value =
|
||||
Digest::HMAC_SHA1::hmac_sha1_hex( "dwho|id|0|$timestamp", '1234567890' );
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/testsso', undef,
|
||||
'test1.example.com', "lemonldap=$sessionId",
|
||||
VHOSTTYPE => 'ZimbraPreAuth',
|
||||
),
|
||||
'Zimbra URL Query'
|
||||
);
|
||||
ok( $res->[0] == 302, 'Code is 302' ) or explain( $res->[0], 302 );
|
||||
|
||||
# Check headers
|
||||
%h = @{ $res->[1] };
|
||||
ok(
|
||||
$h{'Location'} =~
|
||||
m%^/service/preauthtest\?account=dwho&by=id×tamp=$timestamp&expires=0&preauth=$value$%,
|
||||
'Header Location is set to Zimbra URL'
|
||||
) or explain( \%h, 'Location => "Zimbra URL"' );
|
||||
ok( $h{'Auth-User'} eq 'dwho', 'Header Auth-User is set to "dwho"' )
|
||||
or explain( \%h, 'Auth-User => "dwho"' );
|
||||
}
|
||||
|
||||
count($maintests);
|
||||
done_testing( count() );
|
||||
clean();
|
|
@ -0,0 +1,99 @@
|
|||
use Test::More;
|
||||
|
||||
BEGIN {
|
||||
require 't/test-psgi-lib.pm';
|
||||
}
|
||||
|
||||
my $maintests = 12;
|
||||
|
||||
SKIP: {
|
||||
eval { require Cache::Memcached; };
|
||||
if ($@) {
|
||||
skip 'Cache::Memcached not found', $maintests;
|
||||
}
|
||||
eval { require Apache::Session::Generate::MD5; };
|
||||
if ($@) {
|
||||
skip 'Apache::Session::Generate::MD5 not found', $maintests;
|
||||
}
|
||||
init(
|
||||
'Lemonldap::NG::Handler::Server',
|
||||
{
|
||||
logLevel => 'error',
|
||||
secureTokenUrls => [ '^/secured$', '/test$' ],
|
||||
secureTokenHeader => 'AuthToken',
|
||||
vhostOptions => {
|
||||
'test1.example.com' => {
|
||||
vhostHttps => 0,
|
||||
vhostPort => 80,
|
||||
vhostMaintenance => 0,
|
||||
vhostServiceTokenTTL => -1,
|
||||
},
|
||||
},
|
||||
exportedHeaders => {
|
||||
'test1.example.com' => {
|
||||
'Auth-User' => '$uid',
|
||||
},
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
## Request secured URLs
|
||||
# First URL
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/secured', undef,
|
||||
'test1.example.com', "lemonldap=$sessionId",
|
||||
VHOSTTYPE => 'SecureToken',
|
||||
),
|
||||
'Auth secured URL query 1'
|
||||
);
|
||||
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res->[0], 200 );
|
||||
|
||||
# Check headers
|
||||
%h = @{ $res->[1] };
|
||||
ok( $h{'AuthToken'} =~ m%[0-9a-f]{32}%, 'Header "AuthToken" found' )
|
||||
or explain( \%h, 'AuthToken => "md5 value"' );
|
||||
ok( $h{'Auth-User'} eq 'dwho', 'Header Auth-User is set to "dwho"' )
|
||||
or explain( \%h, 'Auth-User => "dwho"' );
|
||||
|
||||
# Second URL
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/try/test', undef,
|
||||
'test1.example.com', "lemonldap=$sessionId",
|
||||
VHOSTTYPE => 'SecureToken',
|
||||
),
|
||||
'Auth secured URL query 2'
|
||||
);
|
||||
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res->[0], 200 );
|
||||
|
||||
# Check headers
|
||||
%h = @{ $res->[1] };
|
||||
ok( $h{'AuthToken'} =~ m%[0-9a-f]{32}%, 'Header "AuthToken" found' )
|
||||
or explain( \%h, 'AuthToken => "md5 value"' );
|
||||
ok( $h{'Auth-User'} eq 'dwho', 'Header Auth-User is set to "dwho"' )
|
||||
or explain( \%h, 'Auth-User => "dwho"' );
|
||||
|
||||
## Request an unsecured URL
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/try', undef,
|
||||
'test1.example.com', "lemonldap=$sessionId",
|
||||
VHOSTTYPE => 'SecureToken',
|
||||
),
|
||||
'Auth unsecured URL query'
|
||||
);
|
||||
ok( $res->[0] == 200, 'Code is 200' ) or explain( $res->[0], 200 );
|
||||
|
||||
# Check headers
|
||||
%h = @{ $res->[1] };
|
||||
ok( !defined $h{'AuthToken'}, 'Header "AuthToken" not found' )
|
||||
or explain( \%h, 'AuthToken => "md5 value"' );
|
||||
ok( $h{'Auth-User'} eq 'dwho', 'Header Auth-User is set to "dwho"' )
|
||||
or explain( \%h, 'Auth-User => "dwho"' );
|
||||
|
||||
}
|
||||
|
||||
count($maintests);
|
||||
done_testing( count() );
|
||||
clean();
|
|
@ -0,0 +1,68 @@
|
|||
use Test::More;
|
||||
use MIME::Base64;
|
||||
|
||||
BEGIN {
|
||||
require 't/test-psgi-lib.pm';
|
||||
}
|
||||
|
||||
my $maintests = 3;
|
||||
|
||||
init(
|
||||
'Lemonldap::NG::Handler::Server',
|
||||
{
|
||||
# authentication => 'Demo',
|
||||
# userDB => 'Same',
|
||||
# restSessionServer => 1,
|
||||
logLevel => 'error',
|
||||
vhostOptions => {
|
||||
'test1.example.com' => {
|
||||
vhostHttps => 0,
|
||||
vhostPort => 80,
|
||||
vhostMaintenance => 0,
|
||||
vhostServiceTokenTTL => -1,
|
||||
},
|
||||
},
|
||||
exportedHeaders => {
|
||||
'test1.example.com' => {
|
||||
'Auth-User' => '$uid',
|
||||
},
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
ok(
|
||||
$res = $client->_get(
|
||||
'/', undef, 'test1.example.com', undef, VHOSTTYPE => 'AuthBasic',
|
||||
),
|
||||
'Query'
|
||||
);
|
||||
ok( $res->[0] == 401, 'Code is 401' ) or explain( $res->[0], 302 );
|
||||
|
||||
# Check headers
|
||||
%h = @{ $res->[1] };
|
||||
ok(
|
||||
$h{'WWW-Authenticate'} =~ m%^Basic realm="LemonLDAP::NG"$%,
|
||||
'Header WWW-Authenticate is set to Basic realm="LemonLDAP::NG"'
|
||||
) or explain( \%h, 'WWW-Authenticate => realm' );
|
||||
|
||||
# my $login = encode_base64("dwho:dwho");
|
||||
# ok(
|
||||
# $res = $client->_get(
|
||||
# '/', undef, 'test1.example.com', undef,
|
||||
# VHOSTTYPE => 'AuthBasic',
|
||||
# HTTP_X_FORWARDED_FOR => '127.0.0.1',
|
||||
# HTTP_AUTHORIZATION => "Basic $login"
|
||||
# ),
|
||||
# 'AuthBasic query'
|
||||
# );
|
||||
#
|
||||
# print STDERR Data::Dumper::Dumper($res);
|
||||
#
|
||||
# # Check headers
|
||||
# %h = @{ $res->[1] };
|
||||
# ok( $h{'Auth-User'} eq 'dwho', 'Header Auth-User is set to "dwho"' )
|
||||
# or explain( \%h, 'Auth-User => "dwho"' );
|
||||
|
||||
count($maintests);
|
||||
done_testing( count() );
|
||||
clean();
|
|
@ -1139,6 +1139,10 @@ qr/(?:(?:https?):\/\/(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.]
|
|||
'dbiUserUser' => {
|
||||
'type' => 'text'
|
||||
},
|
||||
'decryptValueRule' => {
|
||||
'default' => 0,
|
||||
'type' => 'boolOrExpr'
|
||||
},
|
||||
'demoExportedVars' => {
|
||||
'default' => {
|
||||
'cn' => 'cn',
|
||||
|
|
|
@ -534,6 +534,12 @@ sub attributes {
|
|||
documentation => 'Stop context switching by logout',
|
||||
flags => 'p',
|
||||
},
|
||||
decryptValueRule => {
|
||||
type => 'boolOrExpr',
|
||||
default => 0,
|
||||
documentation => 'Decrypt value activation rule',
|
||||
flags => 'p',
|
||||
},
|
||||
skipRenewConfirmation => {
|
||||
type => 'bool',
|
||||
default => 0,
|
||||
|
|
|
@ -102,9 +102,10 @@ sub portalConstants {
|
|||
PE_GET_SERVICE_NOT_ALLOWED => 92,
|
||||
PE_IMPERSONATION_SERVICE_NOT_ALLOWED => 93,
|
||||
PE_ISSUERMISSINGREQATTR => 94,
|
||||
PE_RESETCERTIFICATE_INVALID => 95,
|
||||
PE_RESETCERTIFICATE_FORMEMPTY => 96,
|
||||
PE_RESETCERTIFICATE_FIRSTACCESS => 97,
|
||||
PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED => 95,
|
||||
PE_RESETCERTIFICATE_INVALID => 96,
|
||||
PE_RESETCERTIFICATE_FORMEMPTY => 97,
|
||||
PE_RESETCERTIFICATE_FIRSTACCESS => 98,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -753,6 +753,14 @@ sub tree {
|
|||
'contextSwitchingStopWithLogout',
|
||||
]
|
||||
},
|
||||
{
|
||||
title => 'decryptValue',
|
||||
help => 'decryptValueRule.html',
|
||||
form => 'simpleInputContainer',
|
||||
nodes => [
|
||||
'decryptValueRule',
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -245,6 +245,8 @@
|
|||
"dbiPasswordMailCol":"اسم حقل البريد",
|
||||
"dbiSchema":"مخطط",
|
||||
"dbiUserTable":"جدول المستخدم",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"الاعْتيادي",
|
||||
"defaultRule":"القاعدة الاعتيادية ",
|
||||
"demoModeOn":"هذا المدير يعمل في طريقة العرض",
|
||||
|
|
|
@ -244,6 +244,8 @@
|
|||
"dbiPasswordMailCol":"Mail field name",
|
||||
"dbiSchema":"Schema",
|
||||
"dbiUserTable":"User table",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"Default",
|
||||
"defaultRule":"Default rule",
|
||||
"demoModeOn":"This manager runs in demo mode",
|
||||
|
|
|
@ -244,6 +244,8 @@
|
|||
"dbiPasswordMailCol":"Mail field name",
|
||||
"dbiSchema":"Schema",
|
||||
"dbiUserTable":"User table",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"Default",
|
||||
"defaultRule":"Default rule",
|
||||
"demoModeOn":"This manager runs in demo mode",
|
||||
|
|
|
@ -244,6 +244,8 @@
|
|||
"dbiPasswordMailCol":"Champ mail",
|
||||
"dbiSchema":"Schéma",
|
||||
"dbiUserTable":"Table des utilisateurs",
|
||||
"decryptValue":"Déchiffrement",
|
||||
"decryptValueRule":"Règle d'utilisation",
|
||||
"default":"Défaut",
|
||||
"defaultRule":"Règle par défaut",
|
||||
"demoModeOn":"Ce manager fonctionne en mode Demo",
|
||||
|
|
|
@ -244,6 +244,8 @@
|
|||
"dbiPasswordMailCol":"Nome del campo di posta",
|
||||
"dbiSchema":"Schema",
|
||||
"dbiUserTable":"Tabella utente",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"Predefinito",
|
||||
"defaultRule":"Regola predefinita",
|
||||
"demoModeOn":"Questo gestore viene eseguito in modalità demo",
|
||||
|
|
|
@ -244,6 +244,8 @@
|
|||
"dbiPasswordMailCol":"Tên trường thư",
|
||||
"dbiSchema":"Giản đồ",
|
||||
"dbiUserTable":"Bảng người dùng",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"Mặc định",
|
||||
"defaultRule":"Quy tắc mặc định",
|
||||
"demoModeOn":"Trình quản lý này chạy ở chế độ demo",
|
||||
|
|
|
@ -244,6 +244,8 @@
|
|||
"dbiPasswordMailCol":"Mail field name",
|
||||
"dbiSchema":"Schema",
|
||||
"dbiUserTable":"用户表",
|
||||
"decryptValue":"Decrypt value",
|
||||
"decryptValueRule":"Use rule",
|
||||
"default":"默认",
|
||||
"defaultRule":"默认规则",
|
||||
"demoModeOn":"This manager runs in demo mode",
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -106,6 +106,7 @@ lib/Lemonldap/NG/Portal/Plugins/CertificateResetByMail.pm
|
|||
lib/Lemonldap/NG/Portal/Plugins/CheckState.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/CheckUser.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/ContextSwitching.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/DecryptValue.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/FavApps.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/ForceAuthn.pm
|
||||
lib/Lemonldap/NG/Portal/Plugins/GrantSession.pm
|
||||
|
@ -377,6 +378,7 @@ site/templates/bootstrap/customhead.tpl
|
|||
site/templates/bootstrap/customheader.tpl
|
||||
site/templates/bootstrap/customLoginFooter.tpl
|
||||
site/templates/bootstrap/customLoginHeader.tpl
|
||||
site/templates/bootstrap/decryptvalue.tpl
|
||||
site/templates/bootstrap/error.tpl
|
||||
site/templates/bootstrap/ext2fcheck.tpl
|
||||
site/templates/bootstrap/footer.tpl
|
||||
|
@ -431,6 +433,7 @@ site/templates/common/mail/en.json
|
|||
site/templates/common/mail/fi.json
|
||||
site/templates/common/mail/fr.json
|
||||
site/templates/common/mail/it.json
|
||||
site/templates/common/mail/ms.json
|
||||
site/templates/common/mail/vi.json
|
||||
site/templates/common/mail/zh_CN.json
|
||||
site/templates/common/mail_2fcode.tpl
|
||||
|
|
|
@ -1510,7 +1510,7 @@ sub getIDP {
|
|||
if ( $idpName eq $idpConfKey ) {
|
||||
$idp = $_;
|
||||
$self->logger->debug(
|
||||
"IDP $idp found from idpName URL Parameter ($idpName)");
|
||||
"IDP $idp selected from idpName URL Parameter ($idpName)");
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
@ -1518,7 +1518,7 @@ sub getIDP {
|
|||
|
||||
# Case 3: Recover IDP from cookie
|
||||
if ( !$idp and $idp = $idp_cookie ) {
|
||||
$self->logger->debug("IDP $idp found in IDP resolution cookie");
|
||||
$self->logger->debug("IDP $idp selected from IDP resolution cookie");
|
||||
}
|
||||
|
||||
# Case 4: check all IDP resolution rules
|
||||
|
@ -1526,19 +1526,19 @@ sub getIDP {
|
|||
else {
|
||||
foreach ( keys %{ $self->idpList } ) {
|
||||
my $idpConfKey = $self->idpList->{$_}->{confKey};
|
||||
my $cond = $self->idpRules->{$idpConfKey} or next;
|
||||
my $cond = $self->idpRules->{$_} or next;
|
||||
if ( $cond->( $req, $req->sessionInfo ) ) {
|
||||
$self->logger->debug(
|
||||
"IDP $idpConfKey resolution rule match");
|
||||
"IDP $idpConfKey selected from resolution rule");
|
||||
$idp = $_;
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
$self->logger->debug('No IDP found') unless ($idp);
|
||||
$self->logger->debug('No IDP selected') unless ($idp);
|
||||
}
|
||||
else {
|
||||
$self->logger->debug("IDP $idp found from idp URL Parameter");
|
||||
$self->logger->debug("IDP $idp selected from idp URL Parameter");
|
||||
}
|
||||
|
||||
# Case 6: auto select IDP if only one IDP defined
|
||||
|
|
|
@ -85,7 +85,11 @@ sub storeEnvAndCheckGateway {
|
|||
$self->logger->debug(
|
||||
"Gateway mode requested, redirect without authentication");
|
||||
$req->response( [ 302, [ Location => $service ], [] ] );
|
||||
$req->pdata( {} );
|
||||
for my $s ( $self->ipath, $self->ipath . 'Path' ) {
|
||||
$self->logger->debug("Removing $s from pdata")
|
||||
if delete $req->pdata->{$s};
|
||||
}
|
||||
|
||||
return PE_SENDRESPONSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,9 +98,10 @@ use constant {
|
|||
PE_GET_SERVICE_NOT_ALLOWED => 92,
|
||||
PE_IMPERSONATION_SERVICE_NOT_ALLOWED => 93,
|
||||
PE_ISSUERMISSINGREQATTR => 94,
|
||||
PE_RESETCERTIFICATE_INVALID => 95,
|
||||
PE_RESETCERTIFICATE_FORMEMPTY => 96,
|
||||
PE_RESETCERTIFICATE_FIRSTACCESS => 97,
|
||||
PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED => 95,
|
||||
PE_RESETCERTIFICATE_INVALID => 96,
|
||||
PE_RESETCERTIFICATE_FORMEMPTY => 97,
|
||||
PE_RESETCERTIFICATE_FIRSTACCESS => 98,
|
||||
};
|
||||
|
||||
sub portalConsts {
|
||||
|
@ -195,9 +196,10 @@ sub portalConsts {
|
|||
'92' => 'PE_GET_SERVICE_NOT_ALLOWED',
|
||||
'93' => 'PE_IMPERSONATION_SERVICE_NOT_ALLOWED',
|
||||
'94' => 'PE_ISSUERMISSINGREQATTR',
|
||||
'95' => 'PE_RESETCERTIFICATE_INVALID',
|
||||
'96' => 'PE_RESETCERTIFICATE_FORMEMPTY',
|
||||
'97' => 'PE_RESETCERTIFICATE_FIRSTACCESS'
|
||||
'95' => 'PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED',
|
||||
'96' => 'PE_RESETCERTIFICATE_INVALID',
|
||||
'97' => 'PE_RESETCERTIFICATE_FORMEMPTY',
|
||||
'98' => 'PE_RESETCERTIFICATE_FIRSTACCESS'
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -296,6 +298,7 @@ our @EXPORT_OK = (
|
|||
'PE_GET_SERVICE_NOT_ALLOWED',
|
||||
'PE_IMPERSONATION_SERVICE_NOT_ALLOWED',
|
||||
'PE_ISSUERMISSINGREQATTR',
|
||||
'PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED',
|
||||
'PE_RESETCERTIFICATE_INVALID',
|
||||
'PE_RESETCERTIFICATE_FORMEMPTY',
|
||||
'PE_RESETCERTIFICATE_FIRSTACCESS'
|
||||
|
|
|
@ -140,24 +140,24 @@ sub init {
|
|||
|
||||
# psgi.js
|
||||
->addUnauthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
||||
->addAuthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
||||
->addAuthRoute( 'psgi.js' => 'sendJs', ['GET'] )
|
||||
|
||||
# portal.css
|
||||
->addUnauthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
||||
->addAuthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
||||
->addAuthRoute( 'portal.css' => 'sendCss', ['GET'] )
|
||||
|
||||
# lmerror
|
||||
->addUnauthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
||||
->addAuthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
||||
->addAuthRoute( lmerror => { ':code' => 'lmError' }, ['GET'] )
|
||||
|
||||
# Core REST API
|
||||
->addUnauthRoute( ping => 'pleaseAuth', ['GET'] )
|
||||
->addUnauthRoute( ping => 'pleaseAuth', ['GET'] )
|
||||
->addAuthRoute( ping => 'authenticated', ['GET'] )
|
||||
|
||||
# Refresh session
|
||||
->addAuthRoute( refresh => 'refresh', ['GET'] )
|
||||
|
||||
->addAuthRoute( '*' => 'corsPreflight', ['OPTIONS'] )
|
||||
->addAuthRoute( '*' => 'corsPreflight', ['OPTIONS'] )
|
||||
->addUnauthRoute( '*' => 'corsPreflight', ['OPTIONS'] )
|
||||
|
||||
# Logout
|
||||
|
@ -356,11 +356,18 @@ sub reloadConf {
|
|||
|
||||
# Clean $req->pdata after authentication
|
||||
push @{ $self->endAuth }, sub {
|
||||
unless ( $_[0]->pdata->{keepPdata} ) {
|
||||
$self->logger->debug('Cleaning pdata');
|
||||
$_[0]->pdata( {} );
|
||||
$self->userLogger->notice( $_[0]->user . ' connected' )
|
||||
if $_[0]->user;
|
||||
my $tmp = $_[0]->pdata->{keepPdata} //= [];
|
||||
foreach my $k ( keys %{ $_[0]->pdata } ) {
|
||||
unless ( grep { $_ eq $k } @$tmp ) {
|
||||
$self->logger->debug("Removing $k from pdata");
|
||||
delete $_[0]->pdata->{$k};
|
||||
}
|
||||
}
|
||||
$self->userLogger->notice( $_[0]->user . ' connected' ) if $_[0]->user;
|
||||
if (@$tmp) {
|
||||
$self->logger->debug(
|
||||
'Add ' . join( ',', @$tmp ) . ' in keepPdata' );
|
||||
$_[0]->pdata->{keepPdata} = $tmp;
|
||||
}
|
||||
return PE_OK;
|
||||
};
|
||||
|
|
|
@ -34,9 +34,10 @@ has _ott => (
|
|||
is => 'rw',
|
||||
lazy => 1,
|
||||
default => sub {
|
||||
my $ott = $_[0]->{p}->loadModule('::Lib::OneTimeToken');
|
||||
my $timeout = $_[0]->{conf}->{issuersTimeout} // $_[0]->{conf}->{formTimeout};
|
||||
$ott->timeout( $timeout );
|
||||
my $ott = $_[0]->{p}->loadModule('::Lib::OneTimeToken');
|
||||
my $timeout = $_[0]->{conf}->{issuersTimeout}
|
||||
// $_[0]->{conf}->{formTimeout};
|
||||
$ott->timeout($timeout);
|
||||
return $ott;
|
||||
}
|
||||
);
|
||||
|
@ -86,7 +87,9 @@ sub _redirect {
|
|||
$self->logger->debug('Processing _redirect');
|
||||
$ir = $req->pdata->{ $self->ipath } ||= $self->storeRequest($req);
|
||||
$req->pdata->{ $self->ipath . 'Path' } = \@path;
|
||||
$req->pdata->{keepPdata} = 1;
|
||||
$self->logger->debug(
|
||||
'Add ' . $self->ipath . ', ' . $self->ipath . 'Path in keepPdata' );
|
||||
push @{ $req->pdata->{keepPdata} }, $self->ipath, $self->ipath . 'Path';
|
||||
$req->{urldc} = $self->conf->{portal} . '/' . $self->path;
|
||||
}
|
||||
else {
|
||||
|
@ -111,8 +114,7 @@ sub _redirect {
|
|||
|
||||
# Restore urldc if auth doesn't need to dial with browser
|
||||
$self->restoreRequest( $req, $ir );
|
||||
delete $req->pdata->{ $self->ipath };
|
||||
delete $req->pdata->{ $self->ipath . 'Path' };
|
||||
$self->cleanPdata($req);
|
||||
return $self->run( @_, @path );
|
||||
}
|
||||
: ()
|
||||
|
@ -135,8 +137,9 @@ sub _forAuthUser {
|
|||
|
||||
# Clean pdata: keepPdata has been set, so pdata must be cleaned here
|
||||
$self->logger->debug('Cleaning pdata');
|
||||
$req->pdata( {} );
|
||||
$req->urlNotBase64(1) if ( ref($self) =~ /::CAS$/ );
|
||||
$self->cleanPdata($req);
|
||||
|
||||
$req->maybeNotBase64(1) if ( ref($self) =~ /::CAS$/ );
|
||||
$req->mustRedirect(1);
|
||||
return $self->p->do(
|
||||
$req,
|
||||
|
@ -151,6 +154,27 @@ sub _forAuthUser {
|
|||
);
|
||||
}
|
||||
|
||||
sub cleanPdata {
|
||||
my ( $self, $req ) = @_;
|
||||
for my $s ( $self->ipath, $self->ipath . 'Path' ) {
|
||||
if ( $req->pdata->{$s} ) {
|
||||
$self->logger->debug("Removing $s key from pdata");
|
||||
delete $req->pdata->{$s};
|
||||
}
|
||||
}
|
||||
if ( $req->pdata->{keepPdata} and ref $req->pdata->{keepPdata} ) {
|
||||
@{ $req->pdata->{keepPdata} } =
|
||||
grep {
|
||||
$_ ne $self->ipath
|
||||
and $_ ne $self->ipath . 'Path'
|
||||
? 1
|
||||
: ( $self->logger->debug("Removing $_ from keepPdata") and 0 )
|
||||
} @{ $req->pdata->{keepPdata} };
|
||||
delete $req->pdata->{keepPdata}
|
||||
unless ( @{ $req->pdata->{keepPdata} } );
|
||||
}
|
||||
}
|
||||
|
||||
sub storeRequest {
|
||||
my ( $self, $req ) = @_;
|
||||
$self->logger->debug('Store issuer request');
|
||||
|
@ -191,7 +215,7 @@ qq'<script type="text/javascript" src="$self->{p}->{staticPrefix}/common/js/auto
|
|||
$req->data->{_url} =
|
||||
encode_base64( $self->conf->{portal} . $req->path_info, '' );
|
||||
$req->pdata->{ $self->ipath } = $self->storeRequest($req);
|
||||
$req->pdata->{keepPdata} = 1;
|
||||
push @{ $req->pdata->{keepPdata} }, $self->ipath, $self->ipath . 'Path';
|
||||
return PE_RENEWSESSION;
|
||||
}
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ Custom plugins can be inserted in portal by declaring them in
|
|||
C<lemonldap-ng.ini> file, section C<[portal]>, key C<customPlugins>:
|
||||
|
||||
[portal]
|
||||
customPlugins = My::Plugin1, My::Plugin2
|
||||
customPlugins = ::My::Plugin1, ::My::Plugin2
|
||||
|
||||
Plugins must be valid packages well found in C<@INC>.
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ our @pList = (
|
|||
impersonationRule => '::Plugins::Impersonation',
|
||||
portalDisplayFavApps => '::Plugins::FavApps',
|
||||
contextSwitchingRule => '::Plugins::ContextSwitching',
|
||||
decryptValueRule => '::Plugins::DecryptValue'
|
||||
);
|
||||
|
||||
##@method list enabledPlugins
|
||||
|
|
|
@ -95,12 +95,18 @@ sub controlUrl {
|
|||
}
|
||||
else {
|
||||
if ( $url =~ m#[^A-Za-z0-9\+/=]# ) {
|
||||
$self->userLogger->error(
|
||||
"Value must be BASE64 encoded (param: url | value: $url)");
|
||||
return PE_BADURL;
|
||||
unless ( $req->maybeNotBase64 ) {
|
||||
$self->userLogger->error(
|
||||
"Value must be BASE64 encoded (param: url | value: $url)"
|
||||
);
|
||||
return PE_BADURL;
|
||||
}
|
||||
$req->{urldc} = $url;
|
||||
}
|
||||
else {
|
||||
$req->{urldc} = decode_base64($url);
|
||||
$req->{urldc} =~ s/[\r\n]//sg;
|
||||
}
|
||||
$req->{urldc} = decode_base64($url);
|
||||
$req->{urldc} =~ s/[\r\n]//sg;
|
||||
}
|
||||
|
||||
# For logout request, test if Referer comes from an authorized site
|
||||
|
@ -153,10 +159,12 @@ sub checkLogout {
|
|||
sub authLogout {
|
||||
my ( $self, $req ) = @_;
|
||||
my $res = $self->_authentication->authLogout($req);
|
||||
unless ( $res or $req->pdata->{keepPdata} ) {
|
||||
$self->logger->debug('Cleaning pdata');
|
||||
$req->pdata( {} );
|
||||
$self->logger->debug('Cleaning pdata');
|
||||
my $tmp = $req->pdata->{keepPdata} //= [];
|
||||
foreach my $k ( keys %{ $req->pdata } ) {
|
||||
delete $req->pdata->{$k} unless ( grep { $_ eq $k } @$tmp );
|
||||
}
|
||||
$req->pdata->{keepPdata} = $tmp if @$tmp;
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
@ -309,7 +317,7 @@ sub authenticate {
|
|||
$req->steps( [
|
||||
'setSessionInfo', 'setMacros',
|
||||
'setPersistentSessionInfo', 'storeHistory',
|
||||
@{ $self->afterData }, sub { PE_BADCREDENTIALS }
|
||||
@{ $self->afterData }, sub { PE_BADCREDENTIALS }
|
||||
]
|
||||
);
|
||||
|
||||
|
|
|
@ -57,7 +57,8 @@ has continue => ( is => 'rw' );
|
|||
has checkLogins => ( is => 'rw' );
|
||||
|
||||
# Boolean to indicate that url isn't Base64 encoded
|
||||
has urlNotBase64 => ( is => 'rw' );
|
||||
has urlNotBase64 => ( is => 'rw' );
|
||||
has maybeNotBase64 => ( is => 'rw' );
|
||||
|
||||
# Menu error
|
||||
has menuError => ( is => 'rw' );
|
||||
|
|
|
@ -59,6 +59,66 @@ sub init {
|
|||
}
|
||||
|
||||
# RUNNING METHODS
|
||||
sub display {
|
||||
my ( $self, $req ) = @_;
|
||||
my ( $attrs, $array_attrs ) = ( {}, [] );
|
||||
|
||||
$self->logger->debug("Display current session data...");
|
||||
$self->userLogger->info("Using spoofed SSO groups if exist")
|
||||
if ( $self->conf->{impersonationRule} );
|
||||
$attrs = $req->userData;
|
||||
|
||||
# Create an array of hashes for template loop
|
||||
$self->logger->debug("Delete hidden or empty attributes");
|
||||
if ( $self->conf->{checkUserDisplayEmptyValues} ) {
|
||||
foreach my $k ( sort keys %$attrs ) {
|
||||
|
||||
# Ignore hidden attributes
|
||||
push @$array_attrs, { key => $k, value => $attrs->{$k} }
|
||||
unless ( $self->hAttr =~ /\b$k\b/ );
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach my $k ( sort keys %$attrs ) {
|
||||
|
||||
# Ignore hidden attributes and empty values
|
||||
push @$array_attrs, { key => $k, value => $attrs->{$k} }
|
||||
unless ( $self->hAttr =~ /\b$k\b/ or !$attrs->{$k} );
|
||||
}
|
||||
}
|
||||
|
||||
# ARRAY_REF = [ A_REF GROUPS, A_REF MACROS, A_REF OTHERS ]
|
||||
$array_attrs = $self->_splitAttributes($array_attrs);
|
||||
|
||||
# Display form
|
||||
my $params = {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
SKIN => $self->p->getSkin($req),
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => (
|
||||
$self->{conf}->{impersonationMergeSSOgroups} ? 'checkUserMerged'
|
||||
: 'checkUser'
|
||||
),
|
||||
ALERTE => (
|
||||
$self->{conf}->{impersonationMergeSSOgroups} ? 'alert-warning'
|
||||
: 'alert-info'
|
||||
),
|
||||
LOGIN => $req->{userData}->{ $self->conf->{whatToTrace} },
|
||||
ATTRIBUTES => $array_attrs->[2],
|
||||
MACROS => $array_attrs->[1],
|
||||
GROUPS => $array_attrs->[0],
|
||||
TOKEN => (
|
||||
$self->ottRule->( $req, {} ) ? $self->ott->createToken()
|
||||
: ''
|
||||
)
|
||||
};
|
||||
return $self->sendJSONresponse( $req, $params ) if ( $req->wantJSON );
|
||||
|
||||
# Display form
|
||||
return $self->p->sendHtml( $req, 'checkuser', params => $params, );
|
||||
}
|
||||
|
||||
sub check {
|
||||
my ( $self, $req ) = @_;
|
||||
my ( $attrs, $array_attrs, $array_hdrs ) = ( {}, [], [] );
|
||||
|
@ -93,7 +153,7 @@ sub check {
|
|||
};
|
||||
return $self->p->sendJSONresponse( $req, $params )
|
||||
if ( $req->wantJSON );
|
||||
return $self->p->sendHtml( $req, 'checkuser', params => $params, )
|
||||
return $self->p->sendHtml( $req, 'checkuser', params => $params )
|
||||
if $msg;
|
||||
}
|
||||
|
||||
|
@ -274,65 +334,7 @@ sub check {
|
|||
return $self->p->sendJSONresponse( $req, $params ) if ( $req->wantJSON );
|
||||
|
||||
# Display form
|
||||
return $self->p->sendHtml( $req, 'checkuser', params => $params, );
|
||||
}
|
||||
|
||||
sub display {
|
||||
my ( $self, $req ) = @_;
|
||||
my ( $attrs, $array_attrs ) = ( {}, [] );
|
||||
|
||||
$self->logger->debug("Display current session data...");
|
||||
$self->userLogger->info("Using spoofed SSO groups if exist")
|
||||
if ( $self->conf->{impersonationRule} );
|
||||
$attrs = $req->userData;
|
||||
|
||||
# Create an array of hashes for template loop
|
||||
$self->logger->debug("Delete hidden or empty attributes");
|
||||
if ( $self->conf->{checkUserDisplayEmptyValues} ) {
|
||||
foreach my $k ( sort keys %$attrs ) {
|
||||
|
||||
# Ignore hidden attributes
|
||||
push @$array_attrs, { key => $k, value => $attrs->{$k} }
|
||||
unless ( $self->hAttr =~ /\b$k\b/ );
|
||||
}
|
||||
}
|
||||
else {
|
||||
foreach my $k ( sort keys %$attrs ) {
|
||||
|
||||
# Ignore hidden attributes and empty values
|
||||
push @$array_attrs, { key => $k, value => $attrs->{$k} }
|
||||
unless ( $self->hAttr =~ /\b$k\b/ or !$attrs->{$k} );
|
||||
}
|
||||
}
|
||||
|
||||
# ARRAY_REF = [ A_REF GROUPS, A_REF MACROS, A_REF OTHERS ]
|
||||
$array_attrs = $self->_splitAttributes($array_attrs);
|
||||
|
||||
# Display form
|
||||
my $params = {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
SKIN => $self->p->getSkin($req),
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => (
|
||||
$self->{conf}->{impersonationMergeSSOgroups} ? 'checkUserMerged'
|
||||
: 'checkUser'
|
||||
),
|
||||
ALERTE => (
|
||||
$self->{conf}->{impersonationMergeSSOgroups} ? 'alert-warning'
|
||||
: 'alert-info'
|
||||
),
|
||||
LOGIN => $req->{userData}->{ $self->conf->{whatToTrace} },
|
||||
ATTRIBUTES => $array_attrs->[2],
|
||||
MACROS => $array_attrs->[1],
|
||||
GROUPS => $array_attrs->[0],
|
||||
TOKEN => (
|
||||
$self->ottRule->( $req, {} ) ? $self->ott->createToken()
|
||||
: ''
|
||||
)
|
||||
};
|
||||
return $self->sendJSONresponse( $req, $params ) if ( $req->wantJSON );
|
||||
return $self->p->sendHtml( $req, 'checkuser', params => $params, );
|
||||
return $self->p->sendHtml( $req, 'checkuser', params => $params );
|
||||
}
|
||||
|
||||
sub _urlFormat {
|
||||
|
|
|
@ -32,7 +32,7 @@ has ott => (
|
|||
return $ott;
|
||||
}
|
||||
);
|
||||
has rule => ( is => 'rw', default => sub { 1 } );
|
||||
has rule => ( is => 'rw', default => sub { 0 } );
|
||||
has idRule => ( is => 'rw', default => sub { 1 } );
|
||||
|
||||
sub init {
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
package Lemonldap::NG::Portal::Plugins::DecryptValue;
|
||||
|
||||
use strict;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_TOKENEXPIRED
|
||||
PE_NOTOKEN
|
||||
PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.7';
|
||||
|
||||
extends qw(
|
||||
Lemonldap::NG::Portal::Main::Plugin
|
||||
Lemonldap::NG::Portal::Lib::_tokenRule
|
||||
);
|
||||
|
||||
# INITIALIZATION
|
||||
has rule => ( is => 'rw', default => sub { 0 } );
|
||||
has ott => (
|
||||
is => 'rw',
|
||||
lazy => 1,
|
||||
default => sub {
|
||||
my $ott =
|
||||
$_[0]->{p}->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken');
|
||||
$ott->timeout( $_[0]->{conf}->{formTimeout} );
|
||||
return $ott;
|
||||
}
|
||||
);
|
||||
|
||||
sub init {
|
||||
my ($self) = @_;
|
||||
my $hd = $self->p->HANDLER;
|
||||
$self->addAuthRoute( decryptvalue => 'run', ['POST'] )
|
||||
->addAuthRouteWithRedirect( decryptvalue => 'display', ['GET'] );
|
||||
|
||||
# Parse activation rule
|
||||
$self->logger->debug(
|
||||
'DecryptValue rule -> ' . $self->conf->{decryptValueRule} );
|
||||
my $rule =
|
||||
$hd->buildSub( $hd->substitute( $self->conf->{decryptValueRule} ) );
|
||||
unless ($rule) {
|
||||
$self->error( 'Bad decryptValue rule -> ' . $hd->tsv->{jail}->error );
|
||||
return 0;
|
||||
}
|
||||
$self->rule($rule);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
# RUNNING METHOD
|
||||
sub display {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
# Check access rules
|
||||
unless ( $self->rule->( $req, $req->userData ) ) {
|
||||
$self->userLogger->warn('decryptValue service NOT authorized');
|
||||
return $self->p->do( $req,
|
||||
[ sub { PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED } ] );
|
||||
}
|
||||
|
||||
# Display form
|
||||
my $params = {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
SKIN => $self->p->getSkin($req),
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => 'decryptCipheredValue',
|
||||
ALERTE => 'alert-warning',
|
||||
TOKEN => (
|
||||
$self->ottRule->( $req, {} )
|
||||
? $self->ott->createToken()
|
||||
: ''
|
||||
)
|
||||
};
|
||||
return $self->sendJSONresponse( $req, $params ) if ( $req->wantJSON );
|
||||
|
||||
# Display form
|
||||
return $self->p->sendHtml( $req, 'decryptvalue', params => $params );
|
||||
}
|
||||
|
||||
sub run {
|
||||
my ( $self, $req ) = @_;
|
||||
my $msg = '';
|
||||
|
||||
# Check access rules
|
||||
unless ( $self->rule->( $req, $req->userData ) ) {
|
||||
$self->userLogger->warn('decryptValue service NOT authorized');
|
||||
return $self->p->do( $req,
|
||||
[ sub { PE_DECRYPTVALUE_SERVICE_NOT_ALLOWED } ] );
|
||||
}
|
||||
|
||||
# Check token
|
||||
if ( $self->ottRule->( $req, {} ) ) {
|
||||
my $token = $req->param('token');
|
||||
unless ($token) {
|
||||
$self->userLogger->warn('decryptValue try without token');
|
||||
$msg = PE_NOTOKEN;
|
||||
$token = $self->ott->createToken();
|
||||
}
|
||||
|
||||
unless ( $self->ott->getToken($token) ) {
|
||||
$self->userLogger->warn('decryptValue try with expired/bad token');
|
||||
$msg = PE_TOKENEXPIRED;
|
||||
$token = $self->ott->createToken();
|
||||
}
|
||||
|
||||
my $params = {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
SKIN => $self->p->getSkin($req),
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => "PE$msg",
|
||||
ALERTE => 'alert-warning',
|
||||
TOKEN => $token,
|
||||
};
|
||||
return $self->p->sendJSONresponse( $req, $params )
|
||||
if ( $req->wantJSON );
|
||||
return $self->p->sendHtml( $req, 'decryptvalue', params => $params )
|
||||
if $msg;
|
||||
}
|
||||
|
||||
my $cipheredValue = $req->param('cipheredValue') || '';
|
||||
my $decryptedValue =
|
||||
$self->p->HANDLER->tsv->{cipher}->decrypt($cipheredValue)
|
||||
if $cipheredValue;
|
||||
|
||||
$self->logger->debug("decryptValue try with : $cipheredValue");
|
||||
$self->logger->debug("Decrypted value = $decryptedValue") if $decryptedValue;
|
||||
|
||||
# Display form
|
||||
my $params = {
|
||||
PORTAL => $self->conf->{portal},
|
||||
MAIN_LOGO => $self->conf->{portalMainLogo},
|
||||
SKIN => $self->p->getSkin($req),
|
||||
LANGS => $self->conf->{showLanguages},
|
||||
MSG => 'decryptCipheredValue',
|
||||
DECRYPTED => (
|
||||
$decryptedValue ? $decryptedValue
|
||||
: 'notAnEncryptedValue'
|
||||
),
|
||||
DALERTE => (
|
||||
$decryptedValue ? 'alert-info'
|
||||
: 'alert-danger'
|
||||
),
|
||||
ALERTE => 'alert-warning',
|
||||
TOKEN => (
|
||||
$self->ottRule->( $req, {} ) ? $self->ott->createToken()
|
||||
: ''
|
||||
)
|
||||
};
|
||||
return $self->p->sendJSONresponse( $req, $params ) if ( $req->wantJSON );
|
||||
|
||||
# Display form
|
||||
return $self->p->sendHtml( $req, 'decryptvalue', params => $params );
|
||||
}
|
||||
|
||||
1;
|
|
@ -85,10 +85,10 @@
|
|||
"PE92":"Access not granted on GET service",
|
||||
"PE93":"Access not granted on IMPERSONATION service",
|
||||
"PE94":"A required attribute is not available",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"قبول",
|
||||
"accessDenied":"ليس لديك إذن بالدخول لهذا التطبيق",
|
||||
|
@ -118,6 +118,7 @@
|
|||
"checkUserComputeSession":"Computed session data!",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"اختر أحد التطبيقات المسموح لك بالدخول إليها",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"الرجاء الضغط هنا",
|
||||
"clickOnYubikey":"Click on your Yubikey",
|
||||
"closeSSO":"أغلق جلسة الدخول الموحد (سسو)",
|
||||
|
@ -131,6 +132,7 @@
|
|||
"createAccount":"انشئ حساب",
|
||||
"currentPwd":"كلمة المرور الحالية",
|
||||
"date":"تاريخ",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"الرجاء إدخال بيانات الاعتماد الخاصة بك",
|
||||
"enterExt2fCode":"تم إرسال رمز إليك. الرجاء إدخاله",
|
||||
"enterMail2fCode":"A code has been sent to your email address. Please enter it",
|
||||
|
@ -181,6 +183,7 @@
|
|||
"newPassword":"كلمة مرور جديدة",
|
||||
"newPwdSentTo":"تم إرسال تأكيد إلى عنوان بريدك الإلكتروني.",
|
||||
"noHistory":"هذا هو أول اتصال، مرحبا بك!",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"You're not authorized to do this",
|
||||
"notFound":"لم يتم العثور: محاولة الدخول إلى صفحة غير متوفرة",
|
||||
"noTOTPFound":"No TOTP found",
|
||||
|
|
|
@ -84,10 +84,10 @@
|
|||
"PE92":"Zugang zum GET-Service nicht genehmigt",
|
||||
"PE93":"Access not granted on IMPERSONATION service",
|
||||
"PE94":"A required attribute is not available",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"Dieser Dienst benötigt Zwei-Faktor-Authentifizierung. Bitte legen Sie ein Gerät an und gehen dann zum Portal zurück.",
|
||||
"accept":"Akzeptieren",
|
||||
"accessDenied":"Sie haben keine Zugriffsberechtigung für diese Anwendung",
|
||||
|
@ -117,6 +117,7 @@
|
|||
"checkUserComputeSession":"Computed session data!",
|
||||
"choose2f":"Wählen deinen Ihren zweiten Faktor",
|
||||
"chooseApp":"Wählen Sie eine Anwendung aus, auf die du zugreifen darfst",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"Bitte hier klicken",
|
||||
"clickOnYubikey":"Klicke auf deinen Yubikey",
|
||||
"closeSSO":"Schließe deine SSO-Sitzung",
|
||||
|
@ -130,6 +131,7 @@
|
|||
"createAccount":"Konto erstellen",
|
||||
"currentPwd":"Aktuelles Passwort",
|
||||
"date":"Datum",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"Bitte geben deine Zugangsdaten ein",
|
||||
"enterExt2fCode":"Ein Code wurde an dich gesendet. Bitte gebe diesen ein",
|
||||
"enterMail2fCode":"A code has been sent to your email address. Please enter it",
|
||||
|
@ -180,6 +182,7 @@
|
|||
"newPassword":"Neues Passwort",
|
||||
"newPwdSentTo":"Eine Bestätigung wurde an deine E-Mail Adresse gesendet.",
|
||||
"noHistory":"Das ist deine erste Verbindung, willkommen!",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"Du bist nicht dazu berechtigt",
|
||||
"notFound":"Nicht gefunden: Du versuchst, auf eine nicht verfügbare Seite zuzugreifen",
|
||||
"noTOTPFound":"Kein TOTP gefunden",
|
||||
|
|
|
@ -84,9 +84,10 @@
|
|||
"PE92":"Access not granted on GET service",
|
||||
"PE93":"Access not granted on IMPERSONATION service",
|
||||
"PE94":"A required attribute is not available",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept",
|
||||
"accessDenied":"You have no access authorization for this application",
|
||||
|
@ -117,6 +118,7 @@
|
|||
"certificateReset":"Reset my certificate",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"Please click here",
|
||||
"clickOnYubikey":"Click on your Yubikey",
|
||||
"closeSSO":"Close your SSO session",
|
||||
|
@ -130,6 +132,7 @@
|
|||
"createAccount":"Create an account",
|
||||
"currentPwd":"Current password",
|
||||
"date":"Date",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"Please enter your credentials",
|
||||
"enterExt2fCode":"A code has been sent to you. Please enter it",
|
||||
"enterMail2fCode":"A code has been sent to your email address. Please enter it",
|
||||
|
@ -181,6 +184,7 @@
|
|||
"newPassword":"New password",
|
||||
"newPwdSentTo":"A confirmation has been sent to your mail address.",
|
||||
"noHistory":"This is your first connection, welcome!",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"You're not authorized to do this",
|
||||
"notFound": "Not found: you try to access to an unavailable page",
|
||||
"noTOTPFound":"No TOTP found",
|
||||
|
|
|
@ -84,9 +84,10 @@
|
|||
"PE92":"Acceso no autorizado al servicio GET",
|
||||
"PE93":"Acceso no concedido al servicio de SUPLANTACIÓN",
|
||||
"PE94":"Un atributo obligatorio no está presente",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"Este servicio necesita la autenticación de dos factores. Registre un dispositivo ahora, luego reingrese al portal.",
|
||||
"accept":"Aceptar",
|
||||
"accessDenied":"No está autorizado a acceder a esta aplicación",
|
||||
|
@ -116,6 +117,7 @@
|
|||
"checkUserComputeSession":"¡Datos de sesión calculados!",
|
||||
"choose2f":"Seleccione su segundo factor",
|
||||
"chooseApp":"Elija una aplicación a la cual se le está permitido acceder",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"Por favor haga clic aquí",
|
||||
"clickOnYubikey":"Haga clic en su Yubikey",
|
||||
"closeSSO":"Cierre su sesión SSO",
|
||||
|
@ -129,6 +131,7 @@
|
|||
"createAccount":"Crear una cuenta",
|
||||
"currentPwd":"Contraseña actual",
|
||||
"date":"Fecha",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"Por favor ingrese sus credenciales",
|
||||
"enterExt2fCode":"Un código le ha sido enviado. Por favor ingréselo ",
|
||||
"enterMail2fCode":"Un código le ha sido enviado a dirección de e-mail. Por favor ingréselo",
|
||||
|
@ -179,6 +182,7 @@
|
|||
"newPassword":"Contraseña nueva",
|
||||
"newPwdSentTo":"Una confirmación ha sido enviada a su dirección de e-mail.",
|
||||
"noHistory":"Esta es su primera conexión, bienvenido.",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"Usted no está autorizado a hacer esto",
|
||||
"notFound":"No encontrado: página no disponible",
|
||||
"noTOTPFound":"TOTP no encontrado",
|
||||
|
|
|
@ -84,9 +84,10 @@
|
|||
"PE92":"Access not granted on GET service",
|
||||
"PE93":"Access not granted on IMPERSONATION service",
|
||||
"PE94":"A required attribute is not available",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Hyväksy",
|
||||
"accessDenied":"Sinulla ei ole käyttöoikeutta tähän sovellukseen",
|
||||
|
@ -116,6 +117,7 @@
|
|||
"checkUserComputeSession":"Computed session data!",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"Please click here",
|
||||
"clickOnYubikey":"Click on your Yubikey",
|
||||
"closeSSO":"Sulje SSO istuntosi",
|
||||
|
@ -129,6 +131,7 @@
|
|||
"createAccount":"Rekisteröidy",
|
||||
"currentPwd":"Nykyinen salasana",
|
||||
"date":"Päivämäärä",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"Syötä käyttäjätietosi",
|
||||
"enterExt2fCode":"A code has been sent to you. Please enter it",
|
||||
"enterMail2fCode":"A code has been sent to your email address. Please enter it",
|
||||
|
@ -179,6 +182,7 @@
|
|||
"newPassword":"Uusi salasana",
|
||||
"newPwdSentTo":"A confirmation has been sent to your mail address.",
|
||||
"noHistory":"This is your first connection, welcome!",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"You're not authorized to do this",
|
||||
"notFound":"Not found: you try to access to an unavailable page",
|
||||
"noTOTPFound":"No TOTP found",
|
||||
|
|
|
@ -84,9 +84,10 @@
|
|||
"PE92":"Accès non autorisé au service GET",
|
||||
"PE93":"Accès non autorisé au service d'Usurpation d'Identité",
|
||||
"PE94":"Un attribut exigé n'est pas disponible",
|
||||
"PE95":"votre certificat est invalid ou expire bientot.Veuillez contacter votre administrateur",
|
||||
"PE96":"Veuillez selectionner votre nouveau certificat",
|
||||
"PE95":"Accès non autorisé au service de déchiffrement",
|
||||
"PE96":"votre certificat est invalid ou expire bientot.Veuillez contacter votre administrateur",
|
||||
"PE97":"Veuillez selectionner votre nouveau certificat",
|
||||
"PE98":"Veuillez selectionner votre nouveau certificat",
|
||||
"2fRegRequired":"Ce service requiert une authentification à deux facteurs. Enregistrez un équipement ici et retournez au portail.",
|
||||
"accept":"Accepter",
|
||||
"accessDenied":"Vous n'avez pas les droits d'accès à cette application",
|
||||
|
@ -116,6 +117,7 @@
|
|||
"checkUserComputeSession":"Données de session issues d'une évaluation !",
|
||||
"choose2f":"Choisissez votre second facteur",
|
||||
"chooseApp":"Choisissez une application à laquelle vous êtes autorisé à accéder",
|
||||
"cipheredValue":"Valeur cryptée",
|
||||
"clickHere":"Cliquez ici",
|
||||
"clickOnYubikey":"Cliquez sur votre Yubikey",
|
||||
"closeSSO":"Fermer votre Session SSO",
|
||||
|
@ -129,6 +131,7 @@
|
|||
"createAccount":"Créer un compte",
|
||||
"currentPwd":"Mot de passe actuel",
|
||||
"date":"Date",
|
||||
"decryptCipheredValue":"Déchiffrer une valeur cryptée",
|
||||
"enterCred":"Merci de vous authentifier",
|
||||
"enterExt2fCode":"Un code vous a été envoyé, entrez-le ici",
|
||||
"enterMail2fCode":"Un code vous a été envoyé par mail, entrez-le ici",
|
||||
|
@ -179,6 +182,7 @@
|
|||
"newPassword":"Nouveau mot de passe",
|
||||
"newPwdSentTo":"Une confirmation a été envoyée à votre adresse mail.",
|
||||
"noHistory":"Ceci est votre première connexion. Bienvenue !",
|
||||
"notAnEncryptedValue":"Ce n'est pas une valeur cryptée",
|
||||
"notAuthorized":"Vous n'êtes pas autorisé à faire cette requête",
|
||||
"notFound": "Non trouvé : vous tentez d'accéder à une page non disponible",
|
||||
"noTOTPFound":"Aucun secret TOTP trouvé",
|
||||
|
|
|
@ -84,9 +84,10 @@
|
|||
"PE92":"Accesso non concesso sul servizio GET",
|
||||
"PE93":"Accesso non concesso sul servizio IMPERSONATION",
|
||||
"PE94":"A required attribute is not available",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"Questo servizio richiede un'autenticazione a doppio fattore. Registrare un dispositivo ora, quindi tornare al portale.",
|
||||
"accept":"Accetta",
|
||||
"accessDenied":"Non hai un'autorizzazione di accesso per questa applicazione",
|
||||
|
@ -116,6 +117,7 @@
|
|||
"checkUserComputeSession":"Computed session data!",
|
||||
"choose2f":"Scegli il tuo secondo fattore",
|
||||
"chooseApp":"Scegli un'applicazione alla quale ti è consentito l'accesso",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"Per favore clicka qui",
|
||||
"clickOnYubikey":"Clicca sulla tua Yubikey",
|
||||
"closeSSO":"Chiudi la sessione SSO",
|
||||
|
@ -129,6 +131,7 @@
|
|||
"createAccount":"Crea un account",
|
||||
"currentPwd":"Password attuale",
|
||||
"date":"Data",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"Inserisci le tue credenziali",
|
||||
"enterExt2fCode":"Un codice vi é stato inviato. Inseritelo",
|
||||
"enterMail2fCode":"A code has been sent to your email address. Please enter it",
|
||||
|
@ -179,6 +182,7 @@
|
|||
"newPassword":"Nuova password",
|
||||
"newPwdSentTo":"Una conferma è stata inviata all'indirizzo di posta elettronica.",
|
||||
"noHistory":"Questa è la tua prima connessione, benvenuto!",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"Non sei autorizzato a farlo",
|
||||
"notFound":"Non trovato: si tenta di accedere ad una pagina non disponibile",
|
||||
"noTOTPFound":"Nessun TOTP trovato",
|
||||
|
|
|
@ -84,9 +84,10 @@
|
|||
"PE92":"Onbevoegde toegang tot de GET-service",
|
||||
"PE93":"Access not granted on IMPERSONATION service",
|
||||
"PE94":"A required attribute is not available",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept",
|
||||
"accessDenied":"You have no access authorization for this application",
|
||||
|
@ -116,6 +117,7 @@
|
|||
"checkUserComputeSession":"Computed session data!",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"Please click here",
|
||||
"clickOnYubikey":"Click on your Yubikey",
|
||||
"closeSSO":"Close your SSO session",
|
||||
|
@ -129,6 +131,7 @@
|
|||
"createAccount":"Create an account",
|
||||
"currentPwd":"Current password",
|
||||
"date":"Date",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"Please enter your credentials",
|
||||
"enterExt2fCode":"A code has been sent to you. Please enter it",
|
||||
"enterMail2fCode":"A code has been sent to your email address. Please enter it",
|
||||
|
@ -179,6 +182,7 @@
|
|||
"newPassword":"New password",
|
||||
"newPwdSentTo":"A confirmation has been sent to your mail address.",
|
||||
"noHistory":"This is your first connection, welcome!",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"You're not authorized to do this",
|
||||
"notFound":"Not found: you try to access to an unavailable page",
|
||||
"noTOTPFound":"No TOTP found",
|
||||
|
|
|
@ -84,9 +84,10 @@
|
|||
"PE92":"Acesso não autorizado ao serviço GET",
|
||||
"PE93":"Access not granted on IMPERSONATION service",
|
||||
"PE94":"Um atributo exigido não está disponível",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept",
|
||||
"accessDenied":"You have no access authorization for this application",
|
||||
|
@ -116,6 +117,7 @@
|
|||
"checkUserComputeSession":"Computed session data!",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"Please click here",
|
||||
"clickOnYubikey":"Click on your Yubikey",
|
||||
"closeSSO":"Close your SSO session",
|
||||
|
@ -129,6 +131,7 @@
|
|||
"createAccount":"Create an account",
|
||||
"currentPwd":"Current password",
|
||||
"date":"Date",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"Please enter your credentials",
|
||||
"enterExt2fCode":"A code has been sent to you. Please enter it",
|
||||
"enterMail2fCode":"A code has been sent to your email address. Please enter it",
|
||||
|
@ -179,6 +182,7 @@
|
|||
"newPassword":"New password",
|
||||
"newPwdSentTo":"A confirmation has been sent to your mail address.",
|
||||
"noHistory":"This is your first connection, welcome!",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"You're not authorized to do this",
|
||||
"notFound":"Not found: you try to access to an unavailable page",
|
||||
"noTOTPFound":"No TOTP found",
|
||||
|
|
|
@ -84,9 +84,10 @@
|
|||
"PE92":"Access not granted on GET service",
|
||||
"PE93":"Access not granted on IMPERSONATION service",
|
||||
"PE94":"A required attribute is not available",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept",
|
||||
"accessDenied":"You have no access authorization for this application",
|
||||
|
@ -116,6 +117,7 @@
|
|||
"checkUserComputeSession":"Computed session data!",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"Please click here",
|
||||
"clickOnYubikey":"Click on your Yubikey",
|
||||
"closeSSO":"Close your SSO session",
|
||||
|
@ -129,6 +131,7 @@
|
|||
"createAccount":"Create an account",
|
||||
"currentPwd":"Current password",
|
||||
"date":"Date",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"Please enter your credentials",
|
||||
"enterExt2fCode":"A code has been sent to you. Please enter it",
|
||||
"enterMail2fCode":"A code has been sent to your email address. Please enter it",
|
||||
|
@ -179,6 +182,7 @@
|
|||
"newPassword":"New password",
|
||||
"newPwdSentTo":"A confirmation has been sent to your mail address.",
|
||||
"noHistory":"This is your first connection, welcome!",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"You're not authorized to do this",
|
||||
"notFound":"Not found: you try to access to an unavailable page",
|
||||
"noTOTPFound":"No TOTP found",
|
||||
|
|
|
@ -84,9 +84,10 @@
|
|||
"PE92":"Truy cập không được cấp trên dịch vụ GET",
|
||||
"PE93":"Access not granted on IMPERSONATION service",
|
||||
"PE94":"Một thuộc tính bắt buộc không có sẵn",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Chấp nhận",
|
||||
"accessDenied":"Bạn không có quyền truy cập vào ứng dụng này",
|
||||
|
@ -116,6 +117,7 @@
|
|||
"checkUserComputeSession":"Computed session data!",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Chọn một ứng dụng bạn được phép truy cập vào",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"Vui lòng nhấp vào đây",
|
||||
"clickOnYubikey":"Click on your Yubikey",
|
||||
"closeSSO":"Đóng phiên SSO của bạn",
|
||||
|
@ -129,6 +131,7 @@
|
|||
"createAccount":"Tạo một tài khoản",
|
||||
"currentPwd":"Mật khẩu hiện tại",
|
||||
"date":"Ngày",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"Vui lòng nhập thông tin đăng nhập của bạn",
|
||||
"enterExt2fCode":"Một mã đã được gửi cho bạn. Hãy nhập nó",
|
||||
"enterMail2fCode":"A code has been sent to your email address. Please enter it",
|
||||
|
@ -179,6 +182,7 @@
|
|||
"newPassword":"Mật khẩu mới",
|
||||
"newPwdSentTo":"Một xác nhận đã được gửi đến địa chỉ thư của bạn.",
|
||||
"noHistory":"Đây là kết nối đầu tiên của bạn, chào mừng!",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"You're not authorized to do this",
|
||||
"notFound":"Không tìm thấy: bạn cố gắng truy cập vào một trang không có sẵn",
|
||||
"noTOTPFound":"Đăng xuất khỏi các ứng dụng khác",
|
||||
|
|
|
@ -84,9 +84,10 @@
|
|||
"PE92":"Access not granted on GET service",
|
||||
"PE93":"Access not granted on IMPERSONATION service",
|
||||
"PE94":"A required attribute is not available",
|
||||
"PE95":"Your certificate is invalid or expires soon",
|
||||
"PE96":"Please select your new certificate",
|
||||
"PE95":"Access not granted on DECRYPT service",
|
||||
"PE96":"Your certificate is invalid or expires soon",
|
||||
"PE97":"Please select your new certificate",
|
||||
"PE98":"Please select your new certificate",
|
||||
"2fRegRequired":"This service requires a double factor authentication. Register a device now, then go back to the portal.",
|
||||
"accept":"Accept 方法",
|
||||
"accessDenied":"您无权访问此应用",
|
||||
|
@ -116,6 +117,7 @@
|
|||
"checkUserComputeSession":"Computed session data!",
|
||||
"choose2f":"Choose your second factor",
|
||||
"chooseApp":"Choose an application your are allowed to access to",
|
||||
"cipheredValue":"Ciphered value",
|
||||
"clickHere":"请点击这里",
|
||||
"clickOnYubikey":"Click on your Yubikey",
|
||||
"closeSSO":"Close your SSO session",
|
||||
|
@ -129,6 +131,7 @@
|
|||
"createAccount":"创建账户",
|
||||
"currentPwd":"当前密码",
|
||||
"date":"日期",
|
||||
"decryptCipheredValue":"Decrypt a ciphered value",
|
||||
"enterCred":"请输入您的认证信息",
|
||||
"enterExt2fCode":"验证法已发送,请输入",
|
||||
"enterMail2fCode":"A code has been sent to your email address. Please enter it",
|
||||
|
@ -179,6 +182,7 @@
|
|||
"newPassword":"新密码",
|
||||
"newPwdSentTo":"确认邮件已发送至您的邮箱",
|
||||
"noHistory":"欢迎,这是您的首次登陆",
|
||||
"notAnEncryptedValue":"It is not an encrypted value",
|
||||
"notAuthorized":"您没有权限进行该项操作",
|
||||
"notFound":"无法找到:您请求的网页不存在。",
|
||||
"noTOTPFound":"No TOTP found",
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
<TMPL_INCLUDE NAME="header.tpl">
|
||||
|
||||
<div id="errorcontent" class="container">
|
||||
<!--
|
||||
<div class="message message-positive alert"><span trspan="<TMPL_VAR NAME="MSG">"></span></div>
|
||||
-->
|
||||
<div class="alert <TMPL_VAR NAME="ALERTE"> alert"><div class="text-center"><span trspan="<TMPL_VAR NAME="MSG">"></span></div></div>
|
||||
<form id="contextSwitching" action="/switchcontext" method="post" class="password" role="form">
|
||||
<div class="buttons">
|
||||
|
@ -11,7 +8,7 @@
|
|||
<input type="hidden" name="token" value="<TMPL_VAR NAME="TOKEN">" />
|
||||
</TMPL_IF>
|
||||
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl">
|
||||
<TMPL_INCLUDE NAME="impersonation.tpl">
|
||||
|
||||
<button type="submit" class="btn btn-success">
|
||||
<span class="fa fa-random"></span>
|
||||
|
@ -19,14 +16,7 @@
|
|||
</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="buttons">
|
||||
<!--
|
||||
<button type="submit" class="btn btn-success">
|
||||
<span class="fa fa-sign-in"></span>
|
||||
<span trspan="search">Search</span>
|
||||
</button>
|
||||
-->
|
||||
<a href="<TMPL_VAR NAME="PORTAL_URL">" class="btn btn-primary" role="button">
|
||||
<span class="fa fa-home"></span>
|
||||
<span trspan="goToPortal">Go to portal</span>
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<TMPL_INCLUDE NAME="header.tpl">
|
||||
|
||||
<div id="errorcontent" class="container">
|
||||
<div class="alert <TMPL_VAR NAME="ALERTE"> alert"><div class="text-center"><span trspan="<TMPL_VAR NAME="MSG">"></span></div></div>
|
||||
|
||||
<TMPL_IF NAME="DECRYPTED">
|
||||
<div class="alert <TMPL_VAR NAME="DALERTE"> alert"><div class="text-center"><span trspan="<TMPL_VAR NAME="DECRYPTED">"></span></div></div>
|
||||
</TMPL_IF>
|
||||
|
||||
<form id="findUser" action="/decryptvalue" method="post" class="password" role="form">
|
||||
<div class="buttons">
|
||||
<TMPL_IF NAME="TOKEN">
|
||||
<input type="hidden" name="token" value="<TMPL_VAR NAME="TOKEN">" />
|
||||
</TMPL_IF>
|
||||
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-random icon-blue"></i> </span>
|
||||
</div>
|
||||
<input name="cipheredValue" type="text" class="form-control" trplaceholder="cipheredValue" autocomplete="off" aria-required="false"/>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-success">
|
||||
<span class="fa fa-search"></span>
|
||||
<span trspan="search">Search</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="buttons">
|
||||
<a href="<TMPL_VAR NAME="PORTAL_URL">" class="btn btn-primary" role="button">
|
||||
<span class="fa fa-home"></span>
|
||||
<span trspan="goToPortal">Go to portal</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<TMPL_INCLUDE NAME="footer.tpl">
|
|
@ -1,8 +1,8 @@
|
|||
<TMPL_IF NAME="SPOOFID">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text"><i class="fa fa-user icon-blue"></i> </span>
|
||||
</div>
|
||||
<input name="spoofId" type="text" class="form-control" trplaceholder="spoofId" aria-required="false"/>
|
||||
</div>
|
||||
<input name="spoofId" type="text" class="form-control" trplaceholder="spoofId" aria-required="false"/>
|
||||
</div>
|
||||
</TMPL_IF>
|
|
@ -134,7 +134,8 @@ SKIP: {
|
|||
|
||||
# Expect pdata to be cleared
|
||||
$pdata = expectCookie( $res, 'lemonldappdata' );
|
||||
ok( $pdata !~ 'issuerRequestsaml', 'SAML request cleared from pdata' );
|
||||
ok( $pdata !~ 'issuerRequestsaml', 'SAML request cleared from pdata' )
|
||||
or explain( $pdata, 'not issuerRequestsaml' );
|
||||
|
||||
( $host, $url, $s ) =
|
||||
expectAutoPost( $res, 'auth.sp.com', '/saml/proxySingleSignOnPost',
|
||||
|
|
Loading…
Reference in New Issue