Minimize persistentSession tie/untie (#713, #LEMONLDAP-1173)
This commit is contained in:
parent
babb7f9230
commit
c0c67fd0bd
|
@ -2,10 +2,13 @@ package Lemonldap::NG::Common::Apache::Session::REST;
|
|||
|
||||
use strict;
|
||||
use Lemonldap::NG::Common::UserAgent;
|
||||
use Lemonldap::NG::Common::Apache::Session::Generate::SHA256;
|
||||
use JSON qw(from_json to_json);
|
||||
|
||||
our $VERSION = '2.0.0';
|
||||
|
||||
our @ISA = qw(Lemonldap::NG::Common::Apache::Session::Generate::SHA256);
|
||||
|
||||
# PUBLIC INTERFACE
|
||||
|
||||
# Constructor for Perl TIE mechanism. See perltie(3) for more.
|
||||
|
@ -29,6 +32,10 @@ sub TIEHASH {
|
|||
die "unexistant session $session_id"
|
||||
unless ( $self->get($session_id) );
|
||||
}
|
||||
elsif ( $args->{setId} ) {
|
||||
$self->{data}->{_session_id} = $args->{setId};
|
||||
$self->newSession;
|
||||
}
|
||||
else {
|
||||
die "unable to create session"
|
||||
unless ( $self->newSession() );
|
||||
|
@ -151,7 +158,7 @@ sub get {
|
|||
my $res = $self->getJson("$id") or return 0;
|
||||
$self->{data} = $res;
|
||||
|
||||
$self->cache->set( "soap$id", $self->{data} ) if $self->{localStorage};
|
||||
$self->cache->set( "rest$id", $self->{data} ) if $self->{localStorage};
|
||||
|
||||
return $self->{data};
|
||||
}
|
||||
|
@ -161,30 +168,33 @@ sub get {
|
|||
# @return User datas (just the session ID)
|
||||
sub newSession {
|
||||
my $self = shift;
|
||||
my $req = HTTP::Request->new( POST => $self->base );
|
||||
$req->content( to_json( { _utime => time } ) );
|
||||
$req->header( 'Content-Type' => 'application/json' );
|
||||
my $resp = $self->ua->request($req);
|
||||
if ( $resp->is_success ) {
|
||||
my $res;
|
||||
eval { $res = from_json( $resp->content ) };
|
||||
if ( $@ or !$res->{result} ) {
|
||||
die "Unable to create session: bad REST response $@";
|
||||
}
|
||||
$self->{data} = $res->{session};
|
||||
}
|
||||
else {
|
||||
die "REST server returns " . $resp->status_line;
|
||||
}
|
||||
$self->generate unless ( $self->{data}->{_session_id} );
|
||||
$self->{data}->{_utime} = time;
|
||||
|
||||
# Set cache
|
||||
if ( $self->{localStorage} ) {
|
||||
my $id = "rest" . $self->{data}->{_session_id};
|
||||
if ( $self->cache->get($id) ) {
|
||||
$self->cache->remove($id);
|
||||
}
|
||||
$self->cache->set( $id, $self->{data} );
|
||||
}
|
||||
#my $req = HTTP::Request->new( POST => $self->base );
|
||||
#$req->content( to_json( { _utime => time } ) );
|
||||
#$req->header( 'Content-Type' => 'application/json' );
|
||||
#my $resp = $self->ua->request($req);
|
||||
#if ( $resp->is_success ) {
|
||||
# my $res;
|
||||
# eval { $res = from_json( $resp->content ) };
|
||||
# if ( $@ or !$res->{result} ) {
|
||||
# die "Unable to create session: bad REST response $@";
|
||||
# }
|
||||
# $self->{data} = $res->{session};
|
||||
#}
|
||||
#else {
|
||||
# die "REST server returns " . $resp->status_line;
|
||||
#}
|
||||
|
||||
## Set cache
|
||||
#if ( $self->{localStorage} ) {
|
||||
# my $id = "rest" . $self->{data}->{_session_id};
|
||||
# if ( $self->cache->get($id) ) {
|
||||
# $self->cache->remove($id);
|
||||
# }
|
||||
# $self->cache->set( $id, $self->{data} );
|
||||
#}
|
||||
|
||||
return $self->{data};
|
||||
}
|
||||
|
@ -197,7 +207,7 @@ sub save {
|
|||
|
||||
# Update session in cache
|
||||
if ( $self->{localStorage} ) {
|
||||
my $id = "soap" . $self->{data}->{_session_id};
|
||||
my $id = "rest" . $self->{data}->{_session_id};
|
||||
if ( $self->cache->get($id) ) {
|
||||
$self->cache->remove($id);
|
||||
}
|
||||
|
@ -207,9 +217,15 @@ sub save {
|
|||
# REST
|
||||
my $req =
|
||||
HTTP::Request->new( PUT => $self->base . $self->{data}->{_session_id} );
|
||||
eval {
|
||||
$self->{data}->{__secret} =
|
||||
Lemonldap::NG::Handler::Main->tsv->{cipher}->encrypt(1);
|
||||
};
|
||||
$req->content( to_json( $self->{data} ) );
|
||||
delete $self->{data}->{__secret};
|
||||
$req->header( 'Content-Type' => 'application/json' );
|
||||
my $resp = $self->ua->request($req);
|
||||
|
||||
if ( $resp->is_success ) {
|
||||
my $res;
|
||||
eval { $res = from_json( $resp->content ) };
|
||||
|
@ -231,7 +247,7 @@ sub delete {
|
|||
|
||||
# Remove session from cache
|
||||
if ( $self->{localStorage} ) {
|
||||
my $id = "soap" . $self->{data}->{_session_id};
|
||||
my $id = "rest" . $self->{data}->{_session_id};
|
||||
if ( $self->cache->get($id) ) {
|
||||
$self->cache->remove($id);
|
||||
}
|
||||
|
|
|
@ -101,7 +101,6 @@ sub defaultValues {
|
|||
'locationRules' => {
|
||||
'default' => 'deny'
|
||||
},
|
||||
'loginHistoryEnabled' => 1,
|
||||
'logoutServices' => {},
|
||||
'macros' => {},
|
||||
'mailCharset' => 'utf-8',
|
||||
|
|
|
@ -134,7 +134,7 @@ sub _tie_session {
|
|||
my %h;
|
||||
|
||||
eval {
|
||||
# SOAP session module must be directly tied
|
||||
# SOAP/REST session module must be directly tied
|
||||
if ( $self->storageModule =~ /^Lemonldap::NG::Common::Apache::Session/ )
|
||||
{
|
||||
tie %h, $self->storageModule, $self->id,
|
||||
|
|
|
@ -1307,7 +1307,7 @@ qr/^(?:(?:(?:(?:[a-zA-Z0-9][-a-zA-Z0-9]*)?[a-zA-Z0-9])[.])*(?:[a-zA-Z][-a-zA-Z0-
|
|||
'type' => 'ruleContainer'
|
||||
},
|
||||
'loginHistoryEnabled' => {
|
||||
'default' => 1,
|
||||
'default' => 0,
|
||||
'type' => 'bool'
|
||||
},
|
||||
'logoutServices' => {
|
||||
|
|
|
@ -576,7 +576,6 @@ sub attributes {
|
|||
loginHistoryEnabled => {
|
||||
default => 0,
|
||||
type => 'bool',
|
||||
default => 1,
|
||||
documentation => 'Enable login history',
|
||||
},
|
||||
portalDisplayLoginHistory => {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -346,6 +346,8 @@ sub getPersistentSession {
|
|||
# Compute persistent identifier
|
||||
my $pid = $self->_md5hash($uid);
|
||||
|
||||
$info->{_session_uid} = $uid;
|
||||
|
||||
my $ps = Lemonldap::NG::Common::Session->new(
|
||||
{
|
||||
storageModule => $self->conf->{persistentStorage},
|
||||
|
@ -363,12 +365,12 @@ sub getPersistentSession {
|
|||
|
||||
# Set _session_uid if not already present
|
||||
unless ( defined $ps->data->{_session_uid} ) {
|
||||
$ps->update( { '_session_uid' => $uid } );
|
||||
$ps->update( { _session_uid => $uid } );
|
||||
}
|
||||
|
||||
# Set _utime if not already present
|
||||
unless ( defined $ps->data->{_utime} ) {
|
||||
$ps->update( { '_utime' => time } );
|
||||
$ps->update( { _utime => time } );
|
||||
}
|
||||
|
||||
return $ps;
|
||||
|
@ -728,7 +730,9 @@ sub tplParams {
|
|||
|
||||
sub registerLogin {
|
||||
my ( $self, $req ) = @_;
|
||||
return unless ( defined $req->authResult );
|
||||
return
|
||||
unless ( $self->conf->{loginHistoryEnabled}
|
||||
and defined $req->authResult );
|
||||
my $history = $req->sessionInfo->{loginHistory} ||= {};
|
||||
my $type = ( $req->authResult > 0 ? 'failed' : 'success' ) . 'Login';
|
||||
$history->{$type} ||= [];
|
||||
|
|
|
@ -146,7 +146,17 @@ sub newSession {
|
|||
or return $self->p->sendError( $req, undef, 400 );
|
||||
$infos->{_utime} = time();
|
||||
|
||||
my $session = $self->getApacheSession($mod, undef, $infos);
|
||||
my $force = 0;
|
||||
if ( my $s = delete $infos->{__secret} ) {
|
||||
if ( $self->conf->{cipher}->decrypt($s) == 1 ) {
|
||||
$force = 1;
|
||||
}
|
||||
else {
|
||||
$self->userLogger->error('Bad key, force denied');
|
||||
}
|
||||
}
|
||||
|
||||
my $session = $self->getApacheSession( $mod, undef, $infos, $force );
|
||||
return $self->p->sendError( $req, 'Unable to create session', 500 )
|
||||
unless ($session);
|
||||
|
||||
|
@ -168,8 +178,18 @@ sub updateSession {
|
|||
my $infos = $req->jsonBodyToObj
|
||||
or return $self->p->sendError( $req, undef, 400 );
|
||||
|
||||
# Get secret if given
|
||||
my $force = 0;
|
||||
if ( my $s = delete $infos->{__secret} ) {
|
||||
if ( $self->conf->{cipher}->decrypt($s) == 1 ) {
|
||||
$force = 1;
|
||||
}
|
||||
else {
|
||||
$self->userLogger->error('Bad key, force denied');
|
||||
}
|
||||
}
|
||||
# Get session and store info
|
||||
my $session = $self->getApacheSession( $mod, $id, $infos )
|
||||
my $session = $self->getApacheSession( $mod, $id, $infos, $force )
|
||||
or return $self->p->sendError( $req, 'Session id does not exists', 400 );
|
||||
|
||||
return $self->p->sendJSONresponse( $req, { result => 1 } );
|
||||
|
|
|
@ -40,6 +40,11 @@ count(2);
|
|||
expectRedirection( $res, 'http://auth.sp.com' );
|
||||
$spId = expectCookie($res);
|
||||
|
||||
# Test auth
|
||||
ok( $res = $sp->_get( '/', cookie => "lemonldap=$spId" ), 'Auth test' );
|
||||
count(1);
|
||||
expectOK($res);
|
||||
|
||||
# Test other REST queries
|
||||
switch ('issuer');
|
||||
|
||||
|
@ -182,10 +187,10 @@ sub sp {
|
|||
globalStorageOptions => {
|
||||
baseUrl => 'http://auth.idp.com/sessions/global/'
|
||||
},
|
||||
persistentStorage => 'Apache::Session::File',
|
||||
persistentStorage =>
|
||||
'Lemonldap::NG::Common::Apache::Session::REST',
|
||||
persistentStorageOptions => {
|
||||
Directory => 't/sessions',
|
||||
LockDirectory => 't/sessions/lock',
|
||||
baseUrl => 'http://auth.idp.com/sessions/persistent/'
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user