StayConnected plugin (#1131)
TODO: - check fingerprint back - insert "stayconnected" param in login.tpl
This commit is contained in:
parent
4cf3762f38
commit
57189c1fb6
|
@ -2827,6 +2827,9 @@ qr/^(?:(?:(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-
|
|||
'staticPrefix' => {
|
||||
'type' => 'text'
|
||||
},
|
||||
'stayConnected' => {
|
||||
'type' => 'bool'
|
||||
},
|
||||
'storePassword' => {
|
||||
'default' => 0,
|
||||
'type' => 'bool'
|
||||
|
|
|
@ -333,6 +333,10 @@ sub attributes {
|
|||
default => '; ',
|
||||
documentation => 'Separator for multiple values',
|
||||
},
|
||||
stayConnected => {
|
||||
type => 'bool',
|
||||
documentation => 'Enable StayConnected plugin',
|
||||
},
|
||||
|
||||
# Manager
|
||||
protection => {
|
||||
|
|
|
@ -510,6 +510,7 @@ sub tree {
|
|||
{
|
||||
title => 'plugins',
|
||||
nodes => [
|
||||
'stayConnected',
|
||||
'portalStatus',
|
||||
{
|
||||
title => 'portalServers',
|
||||
|
|
|
@ -628,6 +628,7 @@
|
|||
"SSLVar": "Extracted certificate field",
|
||||
"SSLVarIf": "Conditional extracted certificate field",
|
||||
"startTime": "Creation date",
|
||||
"stayConnected": "Persistent connections",
|
||||
"successfullySaved": "Successfully saved",
|
||||
"storePassword": "Store user password in session datas",
|
||||
"successLoginNumber": "Number of registered logins",
|
||||
|
|
|
@ -628,6 +628,7 @@
|
|||
"SSLVar": "Champ extrait du certificat",
|
||||
"SSLVarIf": "Champ conditionnel extrait du certificat",
|
||||
"startTime": "Date de création",
|
||||
"stayConnected": "Connexions persistantes",
|
||||
"successfullySaved": "Sauvegarde effectuée",
|
||||
"storePassword": "Stocke le mot de passe de l'utilisateur en session",
|
||||
"successLoginNumber": "Nombre de connexions mémorisées",
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -22,7 +22,7 @@ our @pList = (
|
|||
u2fSelfRegistration => '::Register::U2F',
|
||||
notification => '::Plugins::Notifications',
|
||||
portalCheckLogins => '::Plugins::History',
|
||||
sTokenService => '::Plugins::ServiceTokenServer',
|
||||
stayConnected => '::Plugins::StayConnected',
|
||||
);
|
||||
|
||||
##@method list enabledPlugins
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
# Plugin to enable "stay connected on this device" feature
|
||||
|
||||
package Lemonldap::NG::Portal::Plugins::StayConnected;
|
||||
|
||||
use 5.16.0;
|
||||
use strict;
|
||||
use Mouse;
|
||||
use Lemonldap::NG::Portal::Main::Constants qw(
|
||||
PE_OK
|
||||
PE_SENDRESPONSE
|
||||
);
|
||||
|
||||
our $VERSION = '2.0.0';
|
||||
|
||||
extends 'Lemonldap::NG::Portal::Main::Plugin';
|
||||
|
||||
# INTERFACE
|
||||
|
||||
use constant afterDatas => 'newDevice';
|
||||
|
||||
use constant beforeAuth => 'check';
|
||||
|
||||
# INITIALIZATION
|
||||
|
||||
has ott => (
|
||||
is => 'rw',
|
||||
default => sub {
|
||||
my $ott =
|
||||
$_[0]->{p}->loadModule('Lemonldap::NG::Portal::Lib::OneTimeToken');
|
||||
$ott->timeout( $_[0]->conf->{formTimeout} );
|
||||
return $ott;
|
||||
}
|
||||
);
|
||||
|
||||
sub init {
|
||||
my ($self) = @_;
|
||||
$self->addAuthRoute( registerbrowser => 'storeBrowser', ['POST'] );
|
||||
|
||||
}
|
||||
|
||||
# RUNNING METHODS
|
||||
|
||||
sub newDevice {
|
||||
my ( $self, $req ) = @_;
|
||||
|
||||
if ( $req->param('stayconnected') ) {
|
||||
my $token = $self->ott->createToken(
|
||||
{
|
||||
name => $req->sessionInfo->{ $self->conf->{whatToTrace} }
|
||||
}
|
||||
);
|
||||
print STDERR Data::Dumper::Dumper($token);
|
||||
use Data::Dumper;
|
||||
$req->response(
|
||||
$self->p->sendHtml(
|
||||
$req,
|
||||
'../common/registerBrowser',
|
||||
params => {
|
||||
URL => $req->urldc,
|
||||
TOKEN => $token,
|
||||
}
|
||||
)
|
||||
);
|
||||
return PE_SENDRESPONSE;
|
||||
}
|
||||
return PE_OK;
|
||||
}
|
||||
|
||||
sub storeBrowser {
|
||||
my ( $self, $req ) = @_;
|
||||
$req->urldc( $req->param('url') );
|
||||
$req->mustRedirect(1);
|
||||
if ( my $token = $req->param('token') ) {
|
||||
if ( my $tmp = $self->ott->getToken($token) ) {
|
||||
my $uid = $req->userData->{ $self->conf->{whatToTrace} };
|
||||
if ( $tmp->{name} eq $uid ) {
|
||||
if ( my $fg = $req->param('fg') ) {
|
||||
my $ps = Lemonldap::NG::Common::Session->new(
|
||||
storageModule => $self->conf->{persistentStorage},
|
||||
storageModuleOptions =>
|
||||
$self->conf->{persistentStorageOptions},
|
||||
kind => "Persistent",
|
||||
info => {
|
||||
_session_uid => $uid,
|
||||
_connectedSince => time,
|
||||
dataKeep => $req->datas->{dataToKeep},
|
||||
},
|
||||
);
|
||||
$req->addCookie(
|
||||
$self->p->cookie(
|
||||
name => 'llngconnexion',
|
||||
value => $ps->id,
|
||||
expires => '+1M',
|
||||
)
|
||||
);
|
||||
}
|
||||
else {
|
||||
$self->logger->warn("Browser hasn't return fingerprint");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$self->userLogger->error(
|
||||
"StayConnected: mismatch UID: $tmp->{name} / $uid");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$self->userLogger->error("StayConnected call with expired token");
|
||||
}
|
||||
}
|
||||
else {
|
||||
$self->userLogger->error('StayConnected call without token');
|
||||
}
|
||||
|
||||
# Deliver cookie llngbrowser
|
||||
return $self->p->do( $req, [ sub { PE_OK } ] );
|
||||
}
|
||||
|
||||
sub check {
|
||||
my ( $self, $req ) = @_;
|
||||
if ( my $cid = $req->cookies->{llngconnexion} ) {
|
||||
my $ps = Lemonldap::NG::Common::Session->new(
|
||||
storageModule => $self->conf->{persistentStorage},
|
||||
storageModuleOptions => $self->conf->{persistentStorageOptions},
|
||||
kind => "Persistent",
|
||||
id => $cid,
|
||||
);
|
||||
# TODO: verify fingerprint
|
||||
if ( $ps and my $uid = $ps->data->{uid} ) {
|
||||
$req->user($uid);
|
||||
if ( $ps->data->{dataKeep} ) {
|
||||
$req->data( $ps->data->{dataKeep} ) :;
|
||||
}
|
||||
my @steps =
|
||||
grep { !ref $_ or $_ !~ /^(?:extractFormInfo|authenticate)$/ }
|
||||
@{ $req->steps };
|
||||
$req->steps( \@steps );
|
||||
$self->userLogger->notice("$uid connected by StayConnected cookie");
|
||||
return PE_OK;
|
||||
}
|
||||
}
|
||||
return PE_OK;
|
||||
}
|
||||
|
||||
1;
|
4
lemonldap-ng-portal/site/coffee/registerbrowser.coffee
Normal file
4
lemonldap-ng-portal/site/coffee/registerbrowser.coffee
Normal file
|
@ -0,0 +1,4 @@
|
|||
$(document).ready ->
|
||||
new Fingerprint2().get (result, components) ->
|
||||
$('#fg').attr "value", result
|
||||
$('#form').submit()
|
|
@ -0,0 +1,10 @@
|
|||
// Generated by CoffeeScript 1.10.0
|
||||
(function() {
|
||||
$(document).ready(function() {
|
||||
return new Fingerprint2().get(function(result, components) {
|
||||
$('#fg').attr("value", result);
|
||||
return $('#form').submit();
|
||||
});
|
||||
});
|
||||
|
||||
}).call(this);
|
1
lemonldap-ng-portal/site/htdocs/static/common/js/registerbrowser.min.js
vendored
Normal file
1
lemonldap-ng-portal/site/htdocs/static/common/js/registerbrowser.min.js
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
(function(){$(document).ready(function(){return new Fingerprint2().get(function(a,b){$("#fg").attr("value",a);return $("#form").submit()})})}).call(this);
|
|
@ -0,0 +1,31 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>Register browser</title>
|
||||
</head>
|
||||
<body>
|
||||
<p>Please wait...</p>
|
||||
<form id="form" method="post" action="/registerbrowser">
|
||||
<input type="hidden" name="token" value="<TMPL_VAR NAME="TOKEN">" />
|
||||
<input type="hidden" name="url" value="<TMPL_VAR NAME="URL">" />
|
||||
<input type="hidden" name="fg" id="fg" value="" />
|
||||
</form>
|
||||
<!-- //if:usedebianlibs
|
||||
<script type="text/javascript" src="/javascript/jquery/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">bwr/fingerprintjs2/fingerprint2.min.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/registerbrowser.min.js"></script>
|
||||
//elsif:useexternallibs
|
||||
<script type="text/javascript" src="http://code.jquery.com/jquery-2.2.0.min.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">bwr/fingerprintjs2/fingerprint2.min.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/registerbrowser.min.js"></script>
|
||||
//elsif:jsminified
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">bwr/jquery/dist/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">bwr/fingerprintjs2/fingerprint2.min.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/registerbrowser.min.js"></script>
|
||||
//else -->
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">bwr/jquery/dist/jquery.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">bwr/fingerprintjs2/fingerprint2.js"></script>
|
||||
<script type="text/javascript" src="<TMPL_VAR NAME="STATIC_PREFIX">common/js/registerbrowser.js"></script>
|
||||
<!-- //endif -->
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user