Commit 17e351df authored by Xavier Guimard's avatar Xavier Guimard

Merge branch 'v2.0'

parents 7703b993 c77317fe
......@@ -61,10 +61,10 @@ server {
# Set manually your headers
#auth_request_set $authuser $upstream_http_auth_user;
#proxy_set_header Auth-User $authuser;
# OR in the correspondinc block
# OR in the corresponding block
#fastcgi_param HTTP_AUTH_USER $authuser;
# Then (if LUA not supported), change cookie header to hide LLNG cookie
# Then (if LUA is not supported), change cookie header to hide LLNG cookie
#auth_request_set $lmcookie $upstream_http_cookie;
#proxy_set_header Cookie: $lmcookie;
# OR in the corresponding block
......
......@@ -14,6 +14,7 @@ Build-Depends-Indep: libapache-session-perl,
libconvert-pem-perl,
libcrypt-openssl-rsa-perl,
libcrypt-openssl-x509-perl,
libcrypt-urandom-perl,
libcrypt-rijndael-perl,
libdbd-sqlite3-perl,
libdbi-perl,
......@@ -195,6 +196,7 @@ Depends: ${misc:Depends},
libconfig-inifiles-perl,
libcrypt-openssl-rsa-perl,
libcrypt-openssl-x509-perl,
libcrypt-urandom-perl,
libcrypt-rijndael-perl,
libhtml-template-perl,
libjson-perl,
......
......@@ -2,15 +2,21 @@
/* http://docs.angularjs.org/guide/dev_guide.e2e-testing */
describe('02 Lemonldap::NG Manager', function() {
describe('translation', function() {
describe('02 Lemonldap::NG Manger', function() {
describe('Menu', function() {
it('should translate in english and french', function() {
var tests = {
"en": "General Parameters",
"fr": "Paramètres généraux"
};
// // Login attempt
// browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
// browser.driver.findElement(by.xpath("//input[@name='user']")).sendKeys('dwho');
// browser.driver.findElement(by.xpath("//input[@name='password']")).sendKeys('dwho');
// browser.driver.findElement(by.xpath("//button[@type='submit']")).click();
// browser.get('/');
var els = element.all(by.css('[ng-click="getLanguage(lang)"]'));
expect(els.count()).toEqual(14);
els.each(function(el) {
......@@ -26,5 +32,14 @@ describe('02 Lemonldap::NG Manager', function() {
});
});
});
it('Should display Menu -> Links', function() {
element(by.id("mainlangmenu")).click();
browser.sleep(500);
var links = element.all(by.repeater('menulink in menulinks'));
expect(links.count()).toEqual(4);
expect(links.get(0).getText()).toEqual('Retour au portail');
expect(links.get(1).getText()).toEqual('Déconnexion');
});
});
});
......@@ -11,12 +11,13 @@ describe('40 Lemonldap::NG Manager', function() {
});
describe('40 Lemonldap::NG Session explorer', function() {
describe('40 Lemonldap::NG Sessions explorer', function() {
var session, ip;
it('Should display at least my session', function() {
browser.get('/sessions.html');
expect(element.all(by.xpath("//a[@href='sessions.html']")).first().getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
var t = element.all(by.repeater('node in data track by node.id'));
expect(t.count()).toBeGreaterThan(0);
element(by.id("a-d")).click();
......
'use strict';
describe('50 Lemonldap::NG Manager', function() {
it('should display 2FA Sessions explorer', function() {
//// Login attempt
// browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
// browser.driver.findElement(by.xpath("//input[@name='user']")).sendKeys('dwho');
// browser.driver.findElement(by.xpath("//input[@name='password']")).sendKeys('dwho');
// browser.driver.findElement(by.xpath("//button[@type='submit']")).click();
browser.get('/');
var links = element.all(by.repeater('l in links'));
expect(links.count()).toEqual(4);
expect(element.all(by.xpath("//a[@href='2ndfa.html']")).first().getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
element.all(by.xpath("//a[@href='2ndfa.html']")).first().click();
});
});
describe('50 Lemonldap::NG 2FA Sessions explorer', function() {
it('Should display at least my persistent session', function() {
browser.get('/2ndfa.html');
expect(element(by.id('a-persistent')).getText()).toEqual('Explorateur sessions 2ndFA ');
expect(element.all(by.css("input[type=checkbox]")).count()).toEqual(3);
expect(element.all(by.css("input[type=text]")).count()).toEqual(1);
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
element(by.id("a-d")).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
element(by.id("s-5efe8af397fc3577e05b483aca964f1b")).click();
browser.sleep(500);
});
it('Should display Dwho session', function() {
expect(element(by.tagName('h1')).getText()).toEqual('Contenu de la session 5efe8af397fc3577e05b483aca964f1b');
var titles = element.all(by.tagName('h2'));
expect(titles.get(0).getText()).toEqual('Dates');
expect(titles.get(1).getText()).toEqual("Seconds Facteurs d'Authentification");
var nodes = element.all(by.className('glyphicon-minus-sign'));
expect(nodes.count()).toEqual(3);
nodes.get(0).click();
expect(element.all(by.className('glyphicon-minus-sign')).count()).toEqual(2);
});
it('Should filter persistent sessions', function() {
element(by.css('input[ng-model="U2FCheck"]')).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
element(by.css('input[ng-model="UBKCheck"]')).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
element(by.css('input[ng-model="TOTPCheck"]')).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(0);
expect(element.all(by.className('label-warning')).get(0).getText()).toEqual('Aucune donnée à afficher');
element(by.css('input[ng-model="TOTPCheck"]')).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
element(by.css('input[ng-model="searchString"]')).clear().sendKeys('dw');
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
expect(element(by.id("a-dw")));
browser.sleep(500);
element(by.css('input[ng-model="searchString"]')).clear().sendKeys('dwho');
expect(element(by.id("a-dwho")));
browser.sleep(500);
element(by.css('input[ng-model="searchString"]')).clear().sendKeys('a');
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(0);
expect(element.all(by.className('label-warning')).get(0).getText()).toEqual('Aucune donnée à afficher');
browser.sleep(500);
element(by.className('glyphicon-search')).click();
expect(element.all(by.repeater('node in data track by node.id')).count()).toEqual(1);
browser.sleep(500);
});
});
......@@ -99,21 +99,25 @@ describe('0 Lemonldap::NG', function() {
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="WebSSO Manager"]')).click();
expect(element.all(by.xpath("//a[@href='manager.html']")).first().getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
browser.sleep(1000);
expect(browser.driver.findElement(by.css('[trspan="currentConfiguration"]')).getText()).toEqual('Configuration actuelle');
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="Sessions explorer"]')).click();
expect(element.all(by.xpath("//a[@href='sessions.html']")).first().getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
browser.sleep(1000);
expect(browser.driver.findElement(by.css('[trspan="session_s"]')).getText()).toEqual('session(s)');
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="Notifications explorer"]')).click();
expect(element(by.xpath("//a[@href='notifications.html']")).getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
browser.sleep(1000);
expect(browser.driver.findElement(by.css('[trspan="noDatas"]')).getText()).toEqual('Aucune donnée à afficher');
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="2FA Sessions explorer"]')).click();
expect(element.all(by.xpath("//a[@href='2ndfa.html']")).first().getCssValue("color")).toEqual('rgba(157, 157, 157, 1)');
browser.sleep(1000);
expect(browser.driver.findElement(by.id('a-persistent')).getText()).toEqual('Explorateur sessions 2ndFA ');
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
......
......@@ -33,6 +33,7 @@ WriteMakefile(
'Apache::Session::Browseable' => 0,
'Convert::Base32' => 0,
'Cookie::Baker::XS' => 0,
'Crypt::URandom' => 0,
'DBI' => 0,
'Net::LDAP' => 0,
'SOAP::Lite' => 0,
......
......@@ -9,9 +9,10 @@
package Lemonldap::NG::Common::Apache::Session::Generate::SHA256;
use strict;
use Crypt::URandom;
use Digest::SHA qw(sha256 sha256_hex sha256_base64);
our $VERSION = '2.0.0';
our $VERSION = '2.0.2';
sub generate {
my $session = shift;
......@@ -23,7 +24,9 @@ sub generate {
$session->{data}->{_session_id} = substr(
Digest::SHA::sha256_hex(
Digest::SHA::sha256_hex( time() . {} . rand() . $$ )
Digest::SHA::sha256_hex(
time() . {} . Crypt::URandom::urandom($length) . $$
)
),
0, $length
);
......
......@@ -5,10 +5,11 @@ package Lemonldap::NG::Common::TOTP;
use strict;
use Mouse;
use Convert::Base32 'decode_base32';
use Convert::Base32 qw(decode_base32 encode_base32);
use Crypt::URandom;
use Digest::HMAC_SHA1 'hmac_sha1_hex';
our $VERSION = '2.0.0';
our $VERSION = '2.0.2';
# Verify that TOTP $code matches with $secret
sub verifyCode {
......@@ -47,8 +48,7 @@ sub _code {
# Simply generate new base32 secret
sub newSecret {
my ($self) = @_;
my @chars = ( 'a' .. 'z', 2 .. 7 );
return join( '', @chars[ map { int( rand(32) ) } 1 .. 32 ] );
return encode_base32( Crypt::URandom::urandom(20) );
}
1;
......@@ -66,7 +66,7 @@ sub logLevelInit {
# adapt server signature
sub serverSignatureInit {
my $class = shift;
require Lemonldap::NG::Handler;
require Lemonldap::NG::Handler::Main;
my $version = $Lemonldap::NG::Handler::VERSION;
$class->setServerSignature("Lemonldap::NG/$version");
}
......
......@@ -44,20 +44,20 @@ sub getStatus {
if ( $ENV{LLNGSTATUSHOST} ) {
require IO::Socket::INET;
foreach ( 64322 .. 64331 ) {
if ( $statusOut =
IO::Socket::INET->new( Proto => 'udp', LocalPort => $_ ) )
if ( $statusOut
= IO::Socket::INET->new( Proto => 'udp', LocalPort => $_ ) )
{
$args =
' host=' . ( $ENV{LLNGSTATUSCLIENT} || 'localhost' ) . ":$_";
$args = ' host='
. ( $ENV{LLNGSTATUSCLIENT} || 'localhost' ) . ":$_";
last;
}
}
return $class->abort( $req,
"$class: status page can not be displayed, unable to open socket" )
unless ($statusOut);
"$class: status page can not be displayed, unable to open socket"
) unless ($statusOut);
}
return $class->abort( $req, "$class: status page can not be displayed" )
unless ( $statusPipe and $statusOut );
unless ( $statusPipe and $statusOut );
my $q = $req->{env}->{QUERY_STRING} || '';
if ( $q =~ /\s/ ) {
$class->logger->error("Bad characters in query");
......@@ -84,12 +84,12 @@ sub checkType {
if ( time() - $class->lastCheck > $class->checkTime ) {
die("$class: No configuration found")
unless ( $class->checkConf );
unless ( $class->checkConf );
}
my $vhost = $class->resolveAlias($req);
return ( defined $class->tsv->{type}->{$vhost} )
? $class->tsv->{type}->{$vhost}
: 'Main';
? $class->tsv->{type}->{$vhost}
: 'Main';
}
## @rmethod int run
......@@ -125,7 +125,7 @@ sub run {
my ($cond);
( $cond, $protection ) = $class->conditionSub($rule) if ($rule);
$protection = $class->isUnprotected( $req, $uri ) || 0
unless ( defined $protection );
unless ( defined $protection );
if ( $protection == $class->SKIP ) {
$class->logger->debug("Access control skipped");
......@@ -150,7 +150,7 @@ sub run {
# AUTHORIZATION
return ( $class->forbidden( $req, $session ), $session )
unless ( $class->grant( $req, $session, $uri, $cond ) );
unless ( $class->grant( $req, $session, $uri, $cond ) );
$class->updateStatus( $req, 'OK',
$session->{ $class->tsv->{whatToTrace} } );
......@@ -168,8 +168,8 @@ sub run {
# Log access granted
$class->logger->debug( "User "
. $session->{ $class->tsv->{whatToTrace} }
. " was granted to access to $uri" );
. $session->{ $class->tsv->{whatToTrace} }
. " was granted to access to $uri" );
# Catch POST rules
$class->postOutputFilter( $req, $session, $uri );
......@@ -192,7 +192,7 @@ sub run {
# Redirect user to the portal
$class->logger->info("No cookie found")
unless ($id);
unless ($id);
# if the cookie was fetched, a log is sent by retrieveSession()
$class->updateStatus( $req, $id ? 'EXPIRED' : 'REDIRECT' );
......@@ -243,10 +243,10 @@ sub lmLog {
sub checkMaintenanceMode {
my ( $class, $req ) = @_;
my $vhost = $class->resolveAlias($req);
my $_maintenance =
( defined $class->tsv->{maintenance}->{$vhost} )
? $class->tsv->{maintenance}->{$vhost}
: $class->tsv->{maintenance}->{_};
my $_maintenance
= ( defined $class->tsv->{maintenance}->{$vhost} )
? $class->tsv->{maintenance}->{$vhost}
: $class->tsv->{maintenance}->{_};
if ($_maintenance) {
$class->logger->debug("Maintenance mode enabled");
......@@ -272,17 +272,17 @@ sub grant {
}
}
for (
my $i = 0 ;
$i < ( $class->tsv->{locationCount}->{$vhost} || 0 ) ;
my $i = 0;
$i < ( $class->tsv->{locationCount}->{$vhost} || 0 );
$i++
)
)
{
if ( $uri =~ $class->tsv->{locationRegexp}->{$vhost}->[$i] ) {
$class->logger->debug( 'Regexp "'
. $class->tsv->{locationConditionText}->{$vhost}->[$i]
. '" match' );
. $class->tsv->{locationConditionText}->{$vhost}->[$i]
. '" match' );
return $class->tsv->{locationCondition}->{$vhost}->[$i]
->( $req, $session );
->( $req, $session );
}
}
unless ( $class->tsv->{defaultCondition}->{$vhost} ) {
......@@ -319,8 +319,8 @@ sub forbidden {
# Log forbidding
$class->userLogger->notice( "User "
. $session->{ $class->tsv->{whatToTrace} }
. " was forbidden to access to $vhost$uri" );
. $session->{ $class->tsv->{whatToTrace} }
. " was forbidden to access to $vhost$uri" );
$class->updateStatus( $req, 'REJECT',
$session->{ $class->tsv->{whatToTrace} } );
......@@ -341,8 +341,12 @@ sub hideCookie {
my ( $class, $req ) = @_;
$class->logger->debug("removing cookie");
my $cookie = $req->env->{HTTP_COOKIE};
my $cn = $class->tsv->{cookieName};
$cookie =~ s/$cn(http)?=[^,;]*[,;\s]*//og;
$class->logger->debug("Cookies -> $cookie");
my $cn = $class->tsv->{cookieName};
$class->logger->debug("CookieName -> $cn");
$cookie =~ s/\b$cn(http)?=[^,;]*[,;\s]*//og;
$class->logger->debug("newCookies -> $cookie");
if ($cookie) {
$class->set_header_in( $req, 'Cookie' => $cookie );
}
......@@ -373,9 +377,9 @@ sub goToPortal {
$class->logger->debug(
"Redirect $req->{env}->{REMOTE_ADDR} to portal (url was $url)");
$class->set_header_out( $req,
'Location' => $class->tsv->{portal}->()
. "$path?url=$urlc_init"
. ( $arg ? "&$arg" : "" ) );
'Location' => $class->tsv->{portal}->()
. "$path?url=$urlc_init"
. ( $arg ? "&$arg" : "" ) );
return $class->REDIRECT;
}
......@@ -385,9 +389,9 @@ sub goToError {
$class->logger->debug(
"Redirect $req->{env}->{REMOTE_ADDR} to lmError (url was $url)");
$class->set_header_out( $req,
'Location' => $class->tsv->{portal}->()
. "/lmerror/$code"
. "?url=$urlc_init" );
'Location' => $class->tsv->{portal}->()
. "/lmerror/$code"
. "?url=$urlc_init" );
return $class->REDIRECT;
}
......@@ -400,15 +404,15 @@ sub fetchId {
my $vhost = $class->resolveAlias($req);
my $lookForHttpCookie = (
$class->tsv->{securedCookie} =~ /^(2|3)$/
and !( defined( $class->tsv->{https}->{$vhost} ) )
and !( defined( $class->tsv->{https}->{$vhost} ) )
? $class->tsv->{https}->{$vhost}
: $class->tsv->{https}->{_}
);
my $cn = $class->tsv->{cookieName};
my $value =
$lookForHttpCookie
? ( $t =~ /${cn}http=([^,; ]+)/o ? $1 : 0 )
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
my $value
= $lookForHttpCookie
? ( $t =~ /${cn}http=([^,; ]+)/o ? $1 : 0 )
: ( $t =~ /$cn=([^,; ]+)/o ? $1 : 0 );
if ( $value && $lookForHttpCookie && $class->tsv->{securedCookie} == 3 ) {
$value = $class->tsv->{cipher}->decryptHex( $value, "http" );
......@@ -437,8 +441,8 @@ sub retrieveSession {
# (15 seconds)
if ( defined $class->data->{_session_id}
and $id eq $class->data->{_session_id}
and ( $now - $class->dataUpdate < $class->tsv->{handlerInternalCache} )
)
and
( $now - $class->dataUpdate < $class->tsv->{handlerInternalCache} ) )
{
$class->logger->debug("Get session $id from Handler internal cache");
return $class->data;
......@@ -447,8 +451,7 @@ sub retrieveSession {
# 2. Get the session from cache or backend
my $session = $req->data->{session} = (
Lemonldap::NG::Common::Session->new(
{
storageModule => $class->tsv->{sessionStorageModule},
{ storageModule => $class->tsv->{sessionStorageModule},
storageModuleOptions => $class->tsv->{sessionStorageOptions},
cacheModule => $class->tsv->{sessionCacheModule},
cacheModuleOptions => $class->tsv->{sessionCacheOptions},
......@@ -465,36 +468,36 @@ sub retrieveSession {
# Verify that session is valid
$class->logger->error(
"_utime is not defined. This should not happen. Check if it is well transmitted to handler"
"_utime is not defined. This should not happen. Check if it is well transmitted to handler"
) unless $session->data->{_utime};
$class->logger->debug("Check session validity from Handler");
$class->logger->debug( "Session timeout -> " . $class->tsv->{timeout} );
$class->logger->debug(
"Session timeout -> " . $class->tsv->{timeout} );
$class->logger->debug( "Session timeoutActivity -> "
. $class->tsv->{timeoutActivity}
. "s" )
if ( $class->tsv->{timeoutActivity} );
. $class->tsv->{timeoutActivity}
. "s" )
if ( $class->tsv->{timeoutActivity} );
$class->logger->debug(
"Session _utime -> " . $session->data->{_utime} );
$class->logger->debug( "now -> " . $now );
$class->logger->debug( "_lastSeen -> " . $session->data->{_lastSeen} )
if ( $session->data->{_lastSeen} );
if ( $session->data->{_lastSeen} );
my $delta = $now - $session->data->{_lastSeen}
if ( $session->data->{_lastSeen} );
if ( $session->data->{_lastSeen} );
$class->logger->debug( "now - _lastSeen = " . $delta )
if ( $session->data->{_lastSeen} );
if ( $session->data->{_lastSeen} );
$class->logger->debug( "Session timeoutActivityInterval -> "
. $class->tsv->{timeoutActivityInterval} )
if ( $class->tsv->{timeoutActivityInterval} );
. $class->tsv->{timeoutActivityInterval} )
if ( $class->tsv->{timeoutActivityInterval} );
my $ttl = $class->tsv->{timeout} - $now + $session->data->{_utime};
$class->logger->debug( "Session TTL = " . $ttl );
if (
$now - $session->data->{_utime} > $class->tsv->{timeout}
if ($now - $session->data->{_utime} > $class->tsv->{timeout}
or ( $class->tsv->{timeoutActivity}
and $session->data->{_lastSeen}
and $delta > $class->tsv->{timeoutActivity} )
)
)
{
$class->logger->info("Session $id expired");
......@@ -504,11 +507,10 @@ sub retrieveSession {
}
# Update the session to notify activity, if necessary
if (
$class->tsv->{timeoutActivity}
and ( $now - $session->data->{_lastSeen} >
$class->tsv->{timeoutActivityInterval} )
)
if ($class->tsv->{timeoutActivity}
and ( $now - $session->data->{_lastSeen}
> $class->tsv->{timeoutActivityInterval} )
)
{
$req->data->{session}->update( { '_lastSeen' => $now } );
$class->data( $session->data );
......@@ -546,14 +548,14 @@ sub _buildUrl {
? $class->tsv->{https}->{$vhost}
: $class->tsv->{https}->{_}
);
my $portString =
$class->tsv->{port}->{$vhost}
|| $class->tsv->{port}->{_}
|| $req->{env}->{SERVER_PORT};
my $portString
= $class->tsv->{port}->{$vhost}
|| $class->tsv->{port}->{_}
|| $req->{env}->{SERVER_PORT};
$portString = (
( $realvhost =~ /:\d+/ )
or ( $_https && $portString == 443 )
or ( !$_https && $portString == 80 )
( $realvhost =~ /:\d+/ )
or ( $_https && $portString == 443 )
or ( !$_https && $portString == 80 )
) ? '' : ":$portString";
my $url = "http" . ( $_https ? "s" : "" ) . "://$realvhost$portString$s";
$class->logger->debug("Build URL $url");
......@@ -569,10 +571,10 @@ sub isUnprotected {
my ( $class, $req, $uri ) = @_;
my $vhost = $class->resolveAlias($req);
for (
my $i = 0 ;
$i < ( $class->tsv->{locationCount}->{$vhost} || 0 ) ;
my $i = 0;
$i < ( $class->tsv->{locationCount}->{$vhost} || 0 );
$i++
)
)
{
if ( $uri =~ $class->tsv->{locationRegexp}->{$vhost}->[$i] ) {
return $class->tsv->{locationProtection}->{$vhost}->[$i];
......@@ -589,8 +591,8 @@ sub sendHeaders {
if ( defined $class->tsv->{forgeHeaders}->{$vhost} ) {
# Log headers in debug mode
my %headers =
$class->tsv->{forgeHeaders}->{$vhost}->( $req, $session );
my %headers
= $class->tsv->{forgeHeaders}->{$vhost}->( $req, $session );
foreach my $h ( sort keys %headers ) {
if ( defined( my $v = $headers{$h} ) ) {
$class->logger->debug("Send header $h with value $v");
......@@ -622,7 +624,7 @@ sub resolveAlias {
$vhost =~ s/:\d+//;
return $class->tsv->{vhostAlias}->{$vhost}
if ( $class->tsv->{vhostAlias}->{$vhost} );
if ( $class->tsv->{vhostAlias}->{$vhost} );
return $vhost if ( $class->tsv->{defaultCondition}->{$vhost} );
my $v = $vhost;
while ( $v =~ s/[\w\-]+/\*/ ) {
......@@ -695,8 +697,8 @@ sub postOutputFilter {
$class->logger->debug("Filling a html form with fake data");
$class->unset_header_in( $req, "Accept-Encoding" );
my %postdata =
$class->tsv->{outputPostData}->{$vhost}->{$uri}->( $req, $session );
my %postdata = $class->tsv->{outputPostData}->{$vhost}->{$uri}
->( $req, $session );
my $formParams = $class->tsv->{postFormParams}->{$vhost}->{$uri};
my $js = $class->postJavascript( $req, \%postdata, $formParams );
$class->addToHtmlHead( $req, $js );
......@@ -713,8 +715,8 @@ sub postInputFilter {
if ( defined( $class->tsv->{inputPostData}->{$vhost}->{$uri} ) ) {
$class->logger->debug("Replacing fake data with real form data");
my %data =
$class->tsv->{inputPostData}->{$vhost}->{$uri}->( $req, $session );
my %data = $class->tsv->{inputPostData}->{$vhost}->{$uri}
->( $req, $session );
foreach ( keys %data ) {
$data{$_} = uri_escape( $data{$_} );
}
......@@ -734,32 +736,33 @@ sub postJavascript {
foreach my $name ( keys %$data ) {
use bytes;
my $value = "x" x bytes::length( $data->{$name} );
$filler .=
"form.find('input[name=\"$name\"], select[name=\"$name\"], textarea[name=\"$name\"]').val('$value')\n";
$filler
.= "form.find('input[name=\"$name\"], select[name=\"$name\"], textarea[name=\"$name\"]').val('$value')\n";
}
my $submitter =
$formParams->{buttonSelector} eq "none" ? ""
: $formParams->{buttonSelector}
? "form.find('$formParams->{buttonSelector}').click();\n"
: "form.submit();\n";
my $submitter
= $formParams->{buttonSelector} eq "none" ? ""
: $formParams->{buttonSelector}
? "form.find('$formParams->{buttonSelector}').click();\n"
: "form.submit();\n";
my $jqueryUrl = $formParams->{jqueryUrl} || "";
$jqueryUrl = &{ $class->tsv->{portal} } . "skins/common/js/jquery-1.10.2.js"
if ( $jqueryUrl eq "default" );
$jqueryUrl
= &{ $class->tsv->{portal} } . "skins/common/js/jquery-1.10.2.js"
if ( $jqueryUrl eq "default" );
$jqueryUrl = "<script type='text/javascript' src='$jqueryUrl'></script>\n"
if ($jqueryUrl);
if ($jqueryUrl);
return
$jqueryUrl
. "<script type='text/javascript'>\n"
. "/* script added by Lemonldap::NG */\n"
. "jQuery(window).on('load', function() {\n"
. "var form = jQuery('$form');\n"
. "form.attr('autocomplete', 'off');\n"
. $filler
. $submitter . "})\n"
. "</script>\n";
$jqueryUrl
. "<script type='text/javascript'>\n"
. "/* script added by Lemonldap::NG */\n"
. "jQuery(window).on('load', function() {\n"
. "var form = jQuery('$form');\n"
. "form.attr('autocomplete', 'off');\n"
. $filler
. $submitter . "})\n"
. "</script>\n";
}
1;
......@@ -67,8 +67,11 @@ sub handler {
my ( $self, $req ) = @_;
my $hdrs = $req->{respHeaders};
$req->{respHeaders} = [];
my $cookie = $req->env->{HTTP_COOKIE};
my $cn = $self->Lemonldap::NG::Handler::Main::tsv->{cookieName};
$cookie =~ s/\b$cn(http)?=[^,;]*[,;\s]*//og;
my @convertedHdrs =
( 'Content-Length' => 0, Cookie => ( $req->env->{HTTP_COOKIE} // '' ) );
( 'Content-Length' => 0, Cookie => ( $cookie // '' ) );
my $i = 0;
while ( my $k = shift @$hdrs ) {
my $v = shift @$hdrs;
......
package Lemonldap::NG::Manager::Cli;
use strict;
use Crypt::URandom;
use Mouse;
use