Filter 2FA sessions

environments/ppa-mbqj77/deployments/1
Christophe Maudoux 7 years ago
parent 4b0c012579
commit eded3b65a7
  1. 96
      lemonldap-ng-manager/lib/Lemonldap/NG/Manager/2ndFA.pm
  2. 19
      lemonldap-ng-manager/site/coffee/sfa.coffee
  3. 6
      lemonldap-ng-manager/site/htdocs/static/js/sessions.js
  4. 2
      lemonldap-ng-manager/site/htdocs/static/js/sessions.min.js
  5. 17
      lemonldap-ng-manager/site/htdocs/static/js/sfa.js
  6. 2
      lemonldap-ng-manager/site/htdocs/static/js/sfa.min.js
  7. 6
      lemonldap-ng-manager/site/templates/sfa.tpl

@ -31,7 +31,6 @@ sub addRoutes {
# HTML template
$self->addRoute( 'sfa.html', undef, ['GET'] )
# READ
->addRoute(
sfa => { ':sessionType' => 'sfa' },
['GET']
@ -48,7 +47,7 @@ sub addRoutes {
sfa => { ':sessionType' => { ':sessionId' => 'add2FAKey' } },
['PUT']
)
# VERIFY 2FA KEY
->addRoute(
sfa => { ':sessionType' => { ':sessionId' => 'verify2FAKey' } },
@ -68,43 +67,43 @@ sub addRoutes {
sub delete2FAKey {
my ( $self, $req, $session, $skey ) = @_;
my $mod = $self->getMod($req)
my ( $self, $req, $session, $skey ) = @_;
my $mod = $self->getMod($req)
or return $self->sendError( $req, undef, 400 );
my $params = $req->parameters();
my $Key = $params->{Key};
if ( $Key =~ /\bU2F\b/ ) {
return $self->deleteU2FKey( $req, $session, $skey );
}
elsif ( $Key =~ /\bTOTP\b/ ) {
return $self->deleteTOTPKey( $req, $session, $skey );
}
else {
return $self->sendError( $req, undef, 400 );
}
my $Key = $params->{Key};
if ( $Key =~ /\bU2F\b/ ) {
return $self->deleteU2FKey( $req, $session, $skey );
}
elsif ( $Key =~ /\bTOTP\b/ ) {
return $self->deleteTOTPKey( $req, $session, $skey );
}
else {
return $self->sendError( $req, undef, 400 );
}
}
sub add2FAKey {
my ( $self, $req, $session, $skey ) = @_;
eval 'use Crypt::U2F::Server::Simple';
if ($@) {
$self->error("Can't load U2F library: $@");
return 0;
}
return $self->addU2FKey( $req, $session, $skey );
eval 'use Crypt::U2F::Server::Simple';
if ($@) {
$self->error("Can't load U2F library: $@");
return 0;
}
return $self->addU2FKey( $req, $session, $skey );
}
sub verify2FAKey {
my ( $self, $req, $session, $skey ) = @_;
return $self->addU2FKey( $req, $session, $skey );
my ( $self, $req, $session, $skey ) = @_;
return $self->addU2FKey( $req, $session, $skey );
}
########################
@ -115,17 +114,16 @@ sub sfa {
my ( $self, $req, $session, $skey ) = @_;
# Case 1: only one session is required
if ($session) {;
if ($session) {
return $self->session( $req, $session, $skey );
}
my $mod = $self->getMod($req)
or return $self->sendError( $req, undef, 400 );
my $params = $req->parameters();
my $type = delete $params->{sessionType};
$type = ucfirst($type);
my $Key = $params->{sessionType};
my $res;
# Case 2: list of sessions
@ -133,7 +131,11 @@ sub sfa {
my $whatToTrace = Lemonldap::NG::Handler::PSGI::Main->tsv->{whatToTrace};
# 2.1 Get fields to require
my @fields = ( '_httpSessionType', $self->{ipField}, $whatToTrace, '_u2fKeyHandle', '_totp2fSecret' );
my @fields = (
'_httpSessionType', $self->{ipField},
$whatToTrace, '_u2fKeyHandle',
'_totp2fSecret'
);
if ( my $groupBy = $params->{groupBy} ) {
$groupBy =~ s/^substr\((\w+)(?:,\d+(?:,\d+)?)?\)$/$1/;
$groupBy =~ s/^_whatToTrace$/$whatToTrace/o
@ -147,6 +149,13 @@ sub sfa {
# not a keyword)
my $moduleOptions = $mod->{options};
$moduleOptions->{backend} = $mod->{module};
# Select 2FA sessions to display
if ( defined $params->{TOTPCheck} ) {
$self->{TOTPCheck} = delete $params->{TOTPCheck};
$self->{U2FCheck} = delete $params->{U2FCheck};
}
my %filters = map {
my $s = $_;
$s =~ s/\b_whatToTrace\b/$whatToTrace/o;
@ -219,13 +228,22 @@ sub sfa {
}
}
# Display sessions with registered U2F key only
foreach my $session ( keys %$res ) {
delete $res->{$session}
unless ( ( defined $res->{$session}->{_u2fKeyHandle} and length $res->{$session}->{_u2fKeyHandle} )
or ( defined $res->{$session}->{_totp2fSecret} and length $res->{$session}->{_totp2fSecret} ) )
}
# Filter 2FA sessions if needed
if ( $self->{U2FCheck} eq '2' ) {
foreach my $session ( keys %$res ) {
delete $res->{$session}
unless ( defined $res->{$session}->{_u2fKeyHandle}
and length $res->{$session}->{_u2fKeyHandle} );
}
}
if ( $self->{TOTPCheck} eq '2' ) {
foreach my $session ( keys %$res ) {
delete $res->{$session}
unless ( defined $res->{$session}->{_totp2fSecret}
and length $res->{$session}->{_totp2fSecret} );
}
}
my $total = ( keys %$res );
if ( my $group = $req->params('groupBy') ) {

@ -109,10 +109,23 @@ menu =
home: []
###
# AngularJS application
# AngularJS applications
###
llapp = angular.module 'llngSessionsExplorer', ['ui.tree', 'ui.bootstrap', 'llApp']
# Filter 2FA sessions controller
llapp.controller 'SessionsExplorerFilter', ['$scope', '$location', '$q', '$http', ($scope, $location, $q, $http) ->
$scope.filter2FA = ->
$http.get("#{scriptname}sfa/persistent?groupBy=substr(_session_uid,1)&U2FCheck=#{$scope.U2FCheck}&TOTPCheck=#{$scope.TOTPCheck}").then (response) ->
$scope.waiting = true
, (resp) ->
$scope.waiting = false
$scope.updateTree '', $scope.data, 0, 0
]
# Main controller
llapp.controller 'SessionsExplorerCtrl', ['$scope', '$translator', '$location', '$q', '$http', ($scope, $translator, $location, $q, $http) ->
$scope.links = links
@ -151,11 +164,11 @@ llapp.controller 'SessionsExplorerCtrl', ['$scope', '$translator', '$location',
console.log typeof button.action
$scope.showM = false
# SESSION MANAGEMENT
# SESSIONS MANAGEMENT
# Delete U2F key
$scope.deleteU2FKey = ->
$scope.waiting = true
$http['delete']("#{scriptname}sfa/#{sessionType}/#{$scope.currentSession.id}?Key=U2F").then (response) ->
$http['delete']("#{scriptname}sfa/#{$scope.currentSession.id}?Key=U2F").then (response) ->
$scope.currentSession = null
$scope.currentScope.remove()
$scope.waiting = false

@ -1,4 +1,4 @@
// Generated by CoffeeScript 1.12.7
// Generated by CoffeeScript 1.9.3
/*
* Session explorer
@ -227,8 +227,8 @@
session[key] = $scope.localeDate(value);
} else if (key.match(/^(_startTime|_updateTime)$/)) {
session[key] = _stToStr(value);
} else if (key.match(/^(_u2fKeyHandle|_u2fUserKey)$/)) {
session[key] = '########';
} else if (key.match(/^(_u2fKeyHandle|_u2fUserKey|_totp2fSecret)$/)) {
session[key] = '##########';
}
}
}

File diff suppressed because one or more lines are too long

@ -133,11 +133,24 @@
/*
* AngularJS application
* AngularJS applications
*/
llapp = angular.module('llngSessionsExplorer', ['ui.tree', 'ui.bootstrap', 'llApp']);
llapp.controller('SessionsExplorerFilter', [
'$scope', '$location', '$q', '$http', function($scope, $location, $q, $http) {
return $scope.filter2FA = function() {
$http.get(scriptname + "sfa/persistent?groupBy=substr(_session_uid,1)&U2FCheck=" + $scope.U2FCheck + "&TOTPCheck=" + $scope.TOTPCheck).then(function(response) {
return $scope.waiting = true;
}, function(resp) {
return $scope.waiting = false;
});
return $scope.updateTree('', $scope.data, 0, 0);
};
}
]);
llapp.controller('SessionsExplorerCtrl', [
'$scope', '$translator', '$location', '$q', '$http', function($scope, $translator, $location, $q, $http) {
var autoId, c, pathEvent, sessionType;
@ -182,7 +195,7 @@
};
$scope.deleteU2FKey = function() {
$scope.waiting = true;
$http['delete'](scriptname + "sfa/" + sessionType + "/" + $scope.currentSession.id + "?Key=U2F").then(function(response) {
$http['delete'](scriptname + "sfa/" + $scope.currentSession.id + "?Key=U2F").then(function(response) {
$scope.currentSession = null;
$scope.currentScope.remove();
return $scope.waiting = false;

File diff suppressed because one or more lines are too long

@ -17,12 +17,14 @@
<div class="navbar-collapse">
<ul class="nav navbar-nav" role="grid">
<li><a id="a-persistent" role="row"><i class="glyphicon glyphicon-exclamation-sign"></i> {{translate('2faSessions')}}</a></li>
<form name="filterForm" ng-controller="SessionsExplorerFilter">
<div class="form-check ">&nbsp;&nbsp;&nbsp;
<input type="checkbox" class="form-check-input" id="U2FCheck" value="1">
<input type="checkbox" ng-model="U2FCheck" class="form-check-input" ng-true-value="'2'" ng-false-value="'1'" ng-change="filter2FA()"/>
<label class="form-check-label" for="U2FCheck">U2F</label>&nbsp;&nbsp;
<input type="checkbox" class="form-check-input" id="TOTPCheck" value="1">
<input type="checkbox" ng-model="TOTPCheck" class="form-check-input" ng-true-value="'2'" ng-false-value="'1'" ng-change="filter2FA()"/>
<label class="form-check-label" for="TOTPCheck">TOTP</label>
</div>
</form>
</ul>
</div>
</div>

Loading…
Cancel
Save