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

Merge branch 'v2.0'

parents 7703b993 c77317fe
...@@ -61,10 +61,10 @@ server { ...@@ -61,10 +61,10 @@ server {
# Set manually your headers # Set manually your headers
#auth_request_set $authuser $upstream_http_auth_user; #auth_request_set $authuser $upstream_http_auth_user;
#proxy_set_header Auth-User $authuser; #proxy_set_header Auth-User $authuser;
# OR in the correspondinc block # OR in the corresponding block
#fastcgi_param HTTP_AUTH_USER $authuser; #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; #auth_request_set $lmcookie $upstream_http_cookie;
#proxy_set_header Cookie: $lmcookie; #proxy_set_header Cookie: $lmcookie;
# OR in the corresponding block # OR in the corresponding block
......
...@@ -14,6 +14,7 @@ Build-Depends-Indep: libapache-session-perl, ...@@ -14,6 +14,7 @@ Build-Depends-Indep: libapache-session-perl,
libconvert-pem-perl, libconvert-pem-perl,
libcrypt-openssl-rsa-perl, libcrypt-openssl-rsa-perl,
libcrypt-openssl-x509-perl, libcrypt-openssl-x509-perl,
libcrypt-urandom-perl,
libcrypt-rijndael-perl, libcrypt-rijndael-perl,
libdbd-sqlite3-perl, libdbd-sqlite3-perl,
libdbi-perl, libdbi-perl,
...@@ -195,6 +196,7 @@ Depends: ${misc:Depends}, ...@@ -195,6 +196,7 @@ Depends: ${misc:Depends},
libconfig-inifiles-perl, libconfig-inifiles-perl,
libcrypt-openssl-rsa-perl, libcrypt-openssl-rsa-perl,
libcrypt-openssl-x509-perl, libcrypt-openssl-x509-perl,
libcrypt-urandom-perl,
libcrypt-rijndael-perl, libcrypt-rijndael-perl,
libhtml-template-perl, libhtml-template-perl,
libjson-perl, libjson-perl,
......
...@@ -2,15 +2,21 @@ ...@@ -2,15 +2,21 @@
/* http://docs.angularjs.org/guide/dev_guide.e2e-testing */ /* http://docs.angularjs.org/guide/dev_guide.e2e-testing */
describe('02 Lemonldap::NG Manager', function() { describe('02 Lemonldap::NG Manger', function() {
describe('Menu', function() {
describe('translation', function() {
it('should translate in english and french', function() { it('should translate in english and french', function() {
var tests = { var tests = {
"en": "General Parameters", "en": "General Parameters",
"fr": "Paramètres généraux" "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)"]')); var els = element.all(by.css('[ng-click="getLanguage(lang)"]'));
expect(els.count()).toEqual(14); expect(els.count()).toEqual(14);
els.each(function(el) { els.each(function(el) {
...@@ -26,5 +32,14 @@ describe('02 Lemonldap::NG Manager', function() { ...@@ -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() { ...@@ -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; var session, ip;
it('Should display at least my session', function() { it('Should display at least my session', function() {
browser.get('/sessions.html'); 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')); var t = element.all(by.repeater('node in data track by node.id'));
expect(t.count()).toBeGreaterThan(0); expect(t.count()).toBeGreaterThan(0);
element(by.id("a-d")).click(); 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() { ...@@ -99,21 +99,25 @@ describe('0 Lemonldap::NG', function() {
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/'); browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="WebSSO Manager"]')).click(); 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); browser.sleep(1000);
expect(browser.driver.findElement(by.css('[trspan="currentConfiguration"]')).getText()).toEqual('Configuration actuelle'); expect(browser.driver.findElement(by.css('[trspan="currentConfiguration"]')).getText()).toEqual('Configuration actuelle');
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/'); browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="Sessions explorer"]')).click(); 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); browser.sleep(1000);
expect(browser.driver.findElement(by.css('[trspan="session_s"]')).getText()).toEqual('session(s)'); 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.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="Notifications explorer"]')).click(); 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); browser.sleep(1000);
expect(browser.driver.findElement(by.css('[trspan="noDatas"]')).getText()).toEqual('Aucune donnée à afficher'); 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.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
browser.driver.findElement(by.css('[alt="2FA Sessions explorer"]')).click(); 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); browser.sleep(1000);
expect(browser.driver.findElement(by.id('a-persistent')).getText()).toEqual('Explorateur sessions 2ndFA '); expect(browser.driver.findElement(by.id('a-persistent')).getText()).toEqual('Explorateur sessions 2ndFA ');
browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/'); browser.driver.get('http://auth.example.com:' + process.env.TESTWEBSERVERPORT + '/');
......
...@@ -33,6 +33,7 @@ WriteMakefile( ...@@ -33,6 +33,7 @@ WriteMakefile(
'Apache::Session::Browseable' => 0, 'Apache::Session::Browseable' => 0,
'Convert::Base32' => 0, 'Convert::Base32' => 0,
'Cookie::Baker::XS' => 0, 'Cookie::Baker::XS' => 0,
'Crypt::URandom' => 0,
'DBI' => 0, 'DBI' => 0,
'Net::LDAP' => 0, 'Net::LDAP' => 0,
'SOAP::Lite' => 0, 'SOAP::Lite' => 0,
......
...@@ -9,9 +9,10 @@ ...@@ -9,9 +9,10 @@
package Lemonldap::NG::Common::Apache::Session::Generate::SHA256; package Lemonldap::NG::Common::Apache::Session::Generate::SHA256;
use strict; use strict;
use Crypt::URandom;
use Digest::SHA qw(sha256 sha256_hex sha256_base64); use Digest::SHA qw(sha256 sha256_hex sha256_base64);
our $VERSION = '2.0.0'; our $VERSION = '2.0.2';
sub generate { sub generate {
my $session = shift; my $session = shift;
...@@ -23,7 +24,9 @@ sub generate { ...@@ -23,7 +24,9 @@ sub generate {
$session->{data}->{_session_id} = substr( $session->{data}->{_session_id} = substr(
Digest::SHA::sha256_hex( Digest::SHA::sha256_hex(
Digest::SHA::sha256_hex( time() . {} . rand() . $$ ) Digest::SHA::sha256_hex(
time() . {} . Crypt::URandom::urandom($length) . $$
)
), ),
0, $length 0, $length
); );
......
...@@ -5,10 +5,11 @@ package Lemonldap::NG::Common::TOTP; ...@@ -5,10 +5,11 @@ package Lemonldap::NG::Common::TOTP;
use strict; use strict;
use Mouse; 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'; use Digest::HMAC_SHA1 'hmac_sha1_hex';
our $VERSION = '2.0.0'; our $VERSION = '2.0.2';
# Verify that TOTP $code matches with $secret # Verify that TOTP $code matches with $secret
sub verifyCode { sub verifyCode {
...@@ -47,8 +48,7 @@ sub _code { ...@@ -47,8 +48,7 @@ sub _code {
# Simply generate new base32 secret # Simply generate new base32 secret
sub newSecret { sub newSecret {
my ($self) = @_; my ($self) = @_;
my @chars = ( 'a' .. 'z', 2 .. 7 ); return encode_base32( Crypt::URandom::urandom(20) );
return join( '', @chars[ map { int( rand(32) ) } 1 .. 32 ] );
} }
1; 1;
...@@ -66,7 +66,7 @@ sub logLevelInit { ...@@ -66,7 +66,7 @@ sub logLevelInit {
# adapt server signature # adapt server signature
sub serverSignatureInit { sub serverSignatureInit {
my $class = shift; my $class = shift;
require Lemonldap::NG::Handler; require Lemonldap::NG::Handler::Main;
my $version = $Lemonldap::NG::Handler::VERSION; my $version = $Lemonldap::NG::Handler::VERSION;
$class->setServerSignature("Lemonldap::NG/$version"); $class->setServerSignature("Lemonldap::NG/$version");
} }
......
...@@ -67,8 +67,11 @@ sub handler { ...@@ -67,8 +67,11 @@ sub handler {
my ( $self, $req ) = @_; my ( $self, $req ) = @_;
my $hdrs = $req->{respHeaders}; my $hdrs = $req->{respHeaders};
$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 = my @convertedHdrs =
( 'Content-Length' => 0, Cookie => ( $req->env->{HTTP_COOKIE} // '' ) ); ( 'Content-Length' => 0, Cookie => ( $cookie // '' ) );
my $i = 0; my $i = 0;
while ( my $k = shift @$hdrs ) { while ( my $k = shift @$hdrs ) {
my $v = shift @$hdrs; my $v = shift @$hdrs;
......
package Lemonldap::NG::Manager::Cli; package Lemonldap::NG::Manager::Cli;
use strict; use strict;
use Crypt::URandom;
use Mouse; use Mouse;
use Data::Dumper; use Data::Dumper;
use Lemonldap::NG::Common::Conf::ReConstants; use Lemonldap::NG::Common::Conf::ReConstants;
...@@ -254,8 +255,9 @@ sub _save { ...@@ -254,8 +255,9 @@ sub _save {
$new->{cfgDate} = time; $new->{cfgDate} = time;
$new->{cfgVersion} = $VERSION; $new->{cfgVersion} = $VERSION;
$new->{cfgLog} = ''; $new->{cfgLog} = '';
$new->{key} ||= $new->{key} ||= join( '',
join( '', map { chr( int( rand(94) ) + 33 ) } ( 1 .. 16 ) ); map { chr( int( ord( Crypt::URandom::urandom(1) ) * 94 / 256 ) + 33 ) }
( 1 .. 16 ) );
my $s = $self->mgr->confAcc->saveConf( $new, %$saveParams ); my $s = $self->mgr->confAcc->saveConf( $new, %$saveParams );
if ( $s > 0 ) { if ( $s > 0 ) {
......
...@@ -20,6 +20,7 @@ package Lemonldap::NG::Manager::Conf::Parser; ...@@ -20,6 +20,7 @@ package Lemonldap::NG::Manager::Conf::Parser;
use strict; use strict;
use utf8; use utf8;
use Crypt::URandom;
use Mouse; use Mouse;
use JSON 'to_json'; use JSON 'to_json';
use Lemonldap::NG::Common::Conf::ReConstants; use Lemonldap::NG::Common::Conf::ReConstants;
...@@ -130,8 +131,9 @@ sub scanTree { ...@@ -130,8 +131,9 @@ sub scanTree {
$self->newConf->{cfgAuthorIP} = $self->req->address; $self->newConf->{cfgAuthorIP} = $self->req->address;
$self->newConf->{cfgDate} = time; $self->newConf->{cfgDate} = time;
$self->newConf->{cfgVersion} = $VERSION; $self->newConf->{cfgVersion} = $VERSION;
$self->newConf->{key} ||= $self->newConf->{key} ||= join( '',
join( '', map { chr( int( rand(94) ) + 33 ) } ( 1 .. 16 ) ); map { chr( int( ord( Crypt::URandom::urandom(1) ) * 94 / 256 ) + 33 ) }
( 1 .. 16 ) );
return 1; return 1;
} }
......
...@@ -342,7 +342,7 @@ llapp.controller 'TreeCtrl', [ ...@@ -342,7 +342,7 @@ llapp.controller 'TreeCtrl', [
id: "#{node.id}/n#{id++}" id: "#{node.id}/n#{id++}"
title: 'new' title: 'new'
type: 'samlAttribute' type: 'samlAttribute'
data: [0, 'New', '', ''] data: ['0', 'New', '', '']
# Nodes with template # Nodes with template
$scope.addVhost = -> $scope.addVhost = ->
...@@ -678,9 +678,9 @@ llapp.controller 'TreeCtrl', [ ...@@ -678,9 +678,9 @@ llapp.controller 'TreeCtrl', [
else else
node.data = data.value node.data = data.value
# Cast int as int (remember that booleans are int for Perl) # Cast int as int (remember that booleans are int for Perl)
if node.type and node.type.match /^(bool|trool|boolOrExpr)$/ #if node.type and node.type.match /^(bool|trool|boolOrExpr)$/
node.data = node.data.toString() #node.data = node.data.toString()
else if node.type and node.type.match /^int$/ if node.type and node.type.match /^int$/
node.data = parseInt(node.data, 10) node.data = parseInt(node.data, 10)
# Split SAML types # Split SAML types
else if node.type and node.type.match(/^(saml(Service|Assertion)|blackWhiteList)$/) and not (typeof node.data == 'object') else if node.type and node.type.match(/^(saml(Service|Assertion)|blackWhiteList)$/) and not (typeof node.data == 'object')
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
<div class="panel-body"> <div class="panel-body">
<div class="input-group-solid" role="radiogroup"> <div class="input-group-solid" role="radiogroup">
<label class="radio-inline"> <label class="radio-inline">
<input id="bopeOn" type="radio" value="1" name="bope" ng-model="currentNode.data" aria-labelledby="onl" role="radio"/> <input id="bopeOn" type="radio" ng-value="1" name="bope" ng-model="currentNode.data" ng-checked="currentNode.data==1 || currentNode.data=='1'" aria-labelledby="onl" role="radio"/>
<label id="onl" for="bopeOn" trspan="on"></label> <label id="onl" for="bopeOn" trspan="on"></label>
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input id="bopeOff" type="radio" value="0" name="bope" ng-model="currentNode.data" ng-checked="currentNode.data!==1&&currentNode.data!=='1'" aria-labelledby="offl" role="radio"/> <input id="bopeOff" type="radio" ng-value="0" name="bope" ng-model="currentNode.data" ng-checked="currentNode.data!==1&&currentNode.data!=='1'" aria-labelledby="offl" role="radio"/>
<label id="offl" for="bopeOff" trspan="off"></label> <label id="offl" for="bopeOff" trspan="off"></label>
</label> </label>
</div> </div>
......
...@@ -5,15 +5,15 @@ ...@@ -5,15 +5,15 @@
<div class="panel-body"> <div class="panel-body">
<div class="input-group-solid" role="radiogroup"> <div class="input-group-solid" role="radiogroup">
<label class="radio-inline"> <label class="radio-inline">
<input id="bopeOn" type="radio" value="1" name="bope" ng-model="currentNode.data" aria-labelledby="onl" role="radio"/> <input id="bopeOn" type="radio" ng-value="1" name="bope" ng-model="currentNode.data" aria-labelledby="onl" role="radio"/>
<label id="onl" for="bopeOn" trspan="on"></label> <label id="onl" for="bopeOn" trspan="on"></label>
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input id="bopeOff" type="radio" value="0" name="bope" ng-model="currentNode.data" aria-labelledby="offl" role="radio"/> <input id="bopeOff" type="radio" ng-value="0" name="bope" ng-model="currentNode.data" aria-labelledby="offl" role="radio"/>
<label id="offl" for="bopeOff" trspan="off"></label> <label id="offl" for="bopeOff" trspan="off"></label>
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input id="bopeExpr" type="radio" value="-1" name="bope" ng-click="currentNode.data=''" ng-checked="currentNode.data!==0&&currentNode.data!=='0'&&currentNode.data!==1&&currentNode.data!=='1'" aria-labelledby="rulel" role="radio"/> <input id="bopeExpr" type="radio" ng-value="-1" name="bope" ng-click="currentNode.data=''" ng-checked="currentNode.data!==0&&currentNode.data!=='0'&&currentNode.data!=1&&currentNode.data!=='1'" aria-labelledby="rulel" role="radio"/>
<label id="rulel" for="bopeExpr" trspan="specialRule"></label> <label id="rulel" for="bopeExpr" trspan="specialRule"></label>
</label> </label>
</div> </div>
......
...@@ -28,11 +28,11 @@ ...@@ -28,11 +28,11 @@
<td ng-if="n.type=='bool'"> <td ng-if="n.type=='bool'">
<div class="input-group-solid" role="radiogroup"> <div class="input-group-solid" role="radiogroup">
<label class="radio-inline"> <label class="radio-inline">
<input id="bopeOn/{{n.title}}" type="radio" value="1" ng-model="n.data" role="radio" aria-labelledby="lbopeOn{{n.title}}"/> <input id="bopeOn/{{n.title}}" type="radio" ng-value="1" ng-model="n.data" role="radio" aria-labelledby="lbopeOn{{n.title}}"/>
<span id="lbopeOn{{n.title}}" for="bopeOn/{{n.title}}" trspan="on"></span> <span id="lbopeOn{{n.title}}" for="bopeOn/{{n.title}}" trspan="on"></span>
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input id="bopeOff/{{n.title}}" type="radio" value="0" ng-model="n.data" ng-checked="n.data!==1&&n.data!=='1'" role="radio" aria-labelledby="lbopeOff{{n.title}}"/> <input id="bopeOff/{{n.title}}" type="radio" ng-value="0" ng-model="n.data" ng-checked="n.data!==1&&n.data!=='1'" role="radio" aria-labelledby="lbopeOff{{n.title}}"/>
<span id="lbopeOff{{n.title}}" for="bopeOff/{{n.title}}" trspan="off"></span> <span id="lbopeOff{{n.title}}" for="bopeOff/{{n.title}}" trspan="off"></span>
</label> </label>
</div> </div>
...@@ -41,15 +41,15 @@ ...@@ -41,15 +41,15 @@
<td ng-if="n.type=='trool'"> <td ng-if="n.type=='trool'">
<div class="input-group-solid" role="radiogroup"> <div class="input-group-solid" role="radiogroup">
<label class="radio-inline"> <label class="radio-inline">
<input id="trOn/{{n.title}}" type="radio" value="1" ng-model="n.data" role="radio" aria-labelledby="ltrOn{{n.title}}"> <input id="trOn/{{n.title}}" type="radio" ng-value="1" ng-model="n.data" role="radio" aria-labelledby="ltrOn{{n.title}}">
<span id="ltrOn{{n.title}}" for="trOn/{{n.title}}" trspan="on"></span> <span id="ltrOn{{n.title}}" for="trOn/{{n.title}}" trspan="on"></span>
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input id="trOff/{{n.title}}" type="radio" value="0" ng-model="n.data" role="radio" aria-labelledby="ltrOff{{n.title}}"> <input id="trOff/{{n.title}}" type="radio" ng-value="0" ng-model="n.data" role="radio" aria-labelledby="ltrOff{{n.title}}">
<span id="ltrOff{{n.title}}" for="trOff/{{n.title}}" trspan="off"></span> <span id="ltrOff{{n.title}}" for="trOff/{{n.title}}" trspan="off"></span>
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input id="trDefault/{{n.title}}" type="radio" value="-1" ng-model="n.data" ng-checked="n.data!==1&&n.data!=='1'&&n.data!==0&&n.data!=='0'" role="radio" aria-labelledby="ltrDefault{{n.title}}"> <input id="trDefault/{{n.title}}" type="radio" ng-value="-1" ng-model="n.data" ng-checked="n.data!==1&&n.data!=='1'&&n.data!==0&&n.data!=='0'" role="radio" aria-labelledby="ltrDefault{{n.title}}">
<span id="ltrDefault{{n.title}}" for="trDefault/{{n.title}}" trspan="default"></span> <span id="ltrDefault{{n.title}}" for="trDefault/{{n.title}}" trspan="default"></span>
</label> </label>
</div> </div>
...@@ -58,15 +58,15 @@ ...@@ -58,15 +58,15 @@
<td ng-if="n.type=='boolOrExpr'"> <td ng-if="n.type=='boolOrExpr'">
<div class="input-group-solid" role="radiogroup"> <div class="input-group-solid" role="radiogroup">
<label class="radio-inline"> <label class="radio-inline">
<input id="boeOn/{{n.title}}" type="radio" value="1" ng-model="n.data" role="radio" aria-labelledby="lboeOn{{n.title}}"> <input id="boeOn/{{n.title}}" type="radio" ng-value="1" ng-model="n.data" role="radio" aria-labelledby="lboeOn{{n.title}}">
<span id="lboeOn{{n.title}}" for="boeOn/{{n.title}}" trspan="on"></span> <span id="lboeOn{{n.title}}" for="boeOn/{{n.title}}" trspan="on"></span>
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input id="boeOff/{{n.title}}" type="radio" value="0" ng-model="n.data" role="radio" aria-labelledby="lboeOff{{n.title}}"> <input id="boeOff/{{n.title}}" type="radio" ng-value="0" ng-model="n.data" role="radio" aria-labelledby="lboeOff{{n.title}}">
<span id="lboeOff{{n.title}}" for="boeOff/{{n.title}}" trspan="off"></span> <span id="lboeOff{{n.title}}" for="boeOff/{{n.title}}" trspan="off"></span>
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input id="boeExpr/{{n.title}}" type="radio" value="-1" ng-click="n.data=''" ng-checked="n.data!==0&&n.data!=='0'&&n.data!==1&&n.data!=='1'" role="radio" aria-labelledby="lboeExpr{{n.title}}"> <input id="boeExpr/{{n.title}}" type="radio" ng-value="-1" ng-click="n.data=''" ng-checked="n.data!==0&&n.data!=='0'&&n.data!==1&&n.data!=='1'" role="radio" aria-labelledby="lboeExpr{{n.title}}">
<span id="lboeExpr{{n.title}}" for="boeExpr/{{n.title}}" trspan="specialRule"></span> <span id="lboeExpr{{n.title}}" for="boeExpr/{{n.title}}" trspan="specialRule"></span>
</label> </label>
</div> </div>
......
...@@ -5,15 +5,15 @@ ...@@ -5,15 +5,15 @@
<div class="panel-body"> <div class="panel-body">
<div class="input-group-solid" role="radiogroup"> <div class="input-group-solid" role="radiogroup">
<label class="radio-inline"> <label class="radio-inline">
<input id="trOn" type="radio" value="1" ng-model="currentNode.data" role="radio" aria-labelledby="ltrOn"> <input id="trOn" type="radio" ng-value="1" ng-model="currentNode.data" role="radio" aria-labelledby="ltrOn">
<span id="ltrOn" for="trOn" trspan="on"></span> <span id="ltrOn" for="trOn" trspan="on"></span>
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input id="trOff" type="radio" value="0" ng-model="currentNode.data" role="radio" aria-labelledby="ltrOff"> <input id="trOff" type="radio" ng-value="0" ng-model="currentNode.data" role="radio" aria-labelledby="ltrOff">
<span id="ltrOff" for="trOff" trspan="off"></span> <span id="ltrOff" for="trOff" trspan="off"></span>
</label> </label>
<label class="radio-inline"> <label class="radio-inline">
<input id="trDefault" type="radio" value="-1" ng-model="currentNode.data" ng-checked="currentNode.data!==1&&currentNode.data!=='1'&&currentNode.data!==0&&currentNode.data!=='0'" role="radio" aria-labelledby="ltrDefault"> <input id="trDefault" type="radio" ng-value="-1" ng-model="currentNode.data" ng-checked="currentNode.data!==1&&currentNode.data!=='1'&&currentNode.data!==0&&currentNode.data!=='0'" role="radio" aria-labelledby="ltrDefault">
<span id="ltrDefault" for="trDefault" trspan="default"></span> <span id="ltrDefault" for="trDefault" trspan="default"></span>
</label> </label>
</div> </div>
......
...@@ -410,7 +410,7 @@ This file contains: ...@@ -410,7 +410,7 @@ This file contains:
id: node.id + "/n" + (id++), id: node.id + "/n" + (id++),
title: 'new', title: 'new',
type: 'samlAttribute', type: 'samlAttribute',
data: [0, 'New', '', ''] data: ['0', 'New', '', '']
}); });
}; };
$scope.addVhost = function() { $scope.addVhost = function() {
...@@ -823,9 +823,7 @@ This file contains: ...@@ -823,9 +823,7 @@ This file contains:
} else { } else {
node.data = data.value; node.data = data.value;
} }
if (node.type && node.type.match(/^(bool|trool|boolOrExpr)$/)) { if (node.type && node.type.match(/^int$/)) {
node.data = node.data.toString();
} else if (node.type && node.type.match(/^int$/)) {
node.data = parseInt(node.data, 10); node.data = parseInt(node.data, 10);
} else if (node.type && node.type.match(/^(saml(Service|Assertion)|blackWhiteList)$/) && !(typeof node.data === 'object')) { } else if (node.type && node.type.match(/^(saml(Service|Assertion)|blackWhiteList)$/) && !(typeof node.data === 'object')) {
node.data = node.data.split(';'); node.data = node.data.split(';');
......
...@@ -3,8 +3,9 @@ package Lemonldap::NG::Portal::Lib::OneTimeToken; ...@@ -3,8 +3,9 @@ package Lemonldap::NG::Portal::Lib::OneTimeToken;
use strict; use strict;
use Mouse; use Mouse;
use JSON qw(from_json to_json); use JSON qw(from_json to_json);
use Crypt::URandom;
our $VERSION = '2.0.0'; our $VERSION = '2.0.2';
extends 'Lemonldap::NG::Common::Module'; extends 'Lemonldap::NG::Common::Module';
...@@ -63,7 +64,8 @@ sub createToken { ...@@ -63,7 +64,8 @@ sub createToken {
$infos->{_type} ||= "token"; $infos->{_type} ||= "token";
if ( $self->cache ) { if ( $self->cache ) {
my $id = $infos->{_utime} . '_' . int( rand(10000) ); my $id =
$infos->{_utime} . '_' . unpack( 's', Crypt::URandom::urandom(2) );
# Dereference $infos # Dereference $infos
my %h = %$infos; my %h = %$infos;
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
# #
package Lemonldap::NG::Portal::Main::Run; package Lemonldap::NG::Portal::Main::Run;
our $VERSION = '2.0.1';