2017-01-10 13:25:30 +01:00
|
|
|
package Lemonldap::NG::Portal::Lib::RESTProxy;
|
2017-01-10 07:04:40 +01:00
|
|
|
|
|
|
|
use strict;
|
|
|
|
use JSON;
|
|
|
|
use Mouse;
|
2017-02-15 16:08:23 +01:00
|
|
|
use Lemonldap::NG::Common::UserAgent;
|
2021-09-06 17:10:55 +02:00
|
|
|
use Lemonldap::NG::Portal::Main::Constants qw(
|
2021-09-08 22:10:45 +02:00
|
|
|
URIRE
|
2021-09-06 17:10:55 +02:00
|
|
|
PE_OK
|
|
|
|
PE_ERROR
|
|
|
|
PE_BADCREDENTIALS
|
|
|
|
);
|
2017-01-10 07:04:40 +01:00
|
|
|
use Lemonldap::NG::Common::FormEncode;
|
|
|
|
|
2021-09-06 17:10:55 +02:00
|
|
|
our $VERSION = '2.0.14';
|
2017-01-10 07:04:40 +01:00
|
|
|
|
2021-09-06 17:10:55 +02:00
|
|
|
has ua => ( is => 'rw' );
|
2021-09-09 14:28:06 +02:00
|
|
|
has cookieName => ( is => 'rw' );
|
2021-09-06 17:10:55 +02:00
|
|
|
has sessionService => ( is => 'rw' );
|
2017-01-10 07:04:40 +01:00
|
|
|
|
|
|
|
# INITIALIZATION
|
|
|
|
|
|
|
|
sub init {
|
|
|
|
my ($self) = @_;
|
|
|
|
|
2021-09-08 22:10:45 +02:00
|
|
|
unless ( defined $self->conf->{proxyAuthService}
|
|
|
|
&& $self->conf->{proxyAuthService} =~ URIRE )
|
|
|
|
{
|
|
|
|
$self->error("Bad or missing proxyAuthService parameter");
|
2017-01-10 07:04:40 +01:00
|
|
|
return 0;
|
|
|
|
}
|
2021-09-06 17:10:55 +02:00
|
|
|
|
|
|
|
my $sessionService = $self->conf->{proxySessionService}
|
|
|
|
|| $self->conf->{proxyAuthService} . '/session/my';
|
|
|
|
$sessionService =~ s#/*$##;
|
2021-09-08 22:10:45 +02:00
|
|
|
unless ( $sessionService =~ URIRE ) {
|
|
|
|
$self->error("Malformed proxySessionService parameter");
|
|
|
|
return 0;
|
|
|
|
}
|
2021-09-06 17:10:55 +02:00
|
|
|
$self->sessionService($sessionService);
|
|
|
|
$self->ua( Lemonldap::NG::Common::UserAgent->new( $self->conf ) );
|
|
|
|
$self->ua->default_header( Accept => 'application/json' );
|
2021-09-10 22:13:51 +02:00
|
|
|
$self->cookieName( $self->conf->{proxyCookieName}
|
2021-09-09 14:28:06 +02:00
|
|
|
|| $self->conf->{cookieName} );
|
2021-09-06 17:10:55 +02:00
|
|
|
|
2017-01-10 07:04:40 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-01-10 13:25:30 +01:00
|
|
|
no warnings 'once';
|
|
|
|
*authenticate = \&getUser;
|
2017-01-10 07:04:40 +01:00
|
|
|
|
|
|
|
sub getUser {
|
|
|
|
my ( $self, $req ) = @_;
|
2018-07-05 22:56:16 +02:00
|
|
|
return PE_OK if ( $req->data->{_proxyQueryDone} );
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug(
|
|
|
|
'Proxy push auth to ' . $self->conf->{proxyAuthService} );
|
2021-09-06 10:47:06 +02:00
|
|
|
my $resp = $self->ua->post(
|
|
|
|
$self->conf->{proxyAuthService},
|
|
|
|
{
|
|
|
|
user => $req->{user},
|
|
|
|
password => $req->data->{password},
|
|
|
|
(
|
|
|
|
$self->conf->{proxyAuthServiceChoiceParam}
|
|
|
|
&& $self->conf->{proxyAuthServiceChoiceValue}
|
|
|
|
? ( $self->conf->{proxyAuthServiceChoiceParam} =>
|
|
|
|
$self->conf->{proxyAuthServiceChoiceValue} )
|
|
|
|
: ()
|
|
|
|
),
|
2021-09-06 14:18:10 +02:00
|
|
|
(
|
2021-09-08 22:10:45 +02:00
|
|
|
$self->conf->{proxyAuthServiceImpersonation}
|
|
|
|
&& $req->param('spoofId')
|
2021-09-06 14:18:10 +02:00
|
|
|
? ( spoofId => $req->param('spoofId') )
|
|
|
|
: ()
|
|
|
|
)
|
2021-09-06 10:47:06 +02:00
|
|
|
}
|
|
|
|
);
|
2017-01-10 07:04:40 +01:00
|
|
|
unless ( $resp->is_success ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error(
|
|
|
|
'Unable to query authentication service: ' . $resp->status_line );
|
2017-01-10 07:04:40 +01:00
|
|
|
return PE_ERROR;
|
|
|
|
}
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug('Proxy gets a response');
|
2017-09-28 14:52:14 +02:00
|
|
|
my $res = eval { JSON::from_json( $resp->content, { allow_nonref => 1 } ) };
|
2017-01-10 07:04:40 +01:00
|
|
|
if ($@) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error("Bad content: $@");
|
2017-01-10 07:04:40 +01:00
|
|
|
return PE_ERROR;
|
|
|
|
}
|
2017-01-10 13:25:30 +01:00
|
|
|
unless ( $res->{result} ) {
|
2021-09-09 14:28:06 +02:00
|
|
|
$self->userLogger->warn("Authentication failed for $req->{user}");
|
2017-03-14 17:52:11 +01:00
|
|
|
$self->setSecurity($req);
|
2017-01-10 13:25:30 +01:00
|
|
|
return PE_BADCREDENTIALS;
|
|
|
|
}
|
2021-09-09 14:28:06 +02:00
|
|
|
my $name = $self->cookieName;
|
2021-09-09 14:54:40 +02:00
|
|
|
unless ( grep /\b$name=/, $resp->header('Set-Cookie') ) {
|
2021-09-09 14:28:06 +02:00
|
|
|
$self->logger->error("No cookie named '$name'");
|
|
|
|
return PE_ERROR;
|
|
|
|
}
|
|
|
|
|
2017-01-10 13:25:30 +01:00
|
|
|
$req->sessionInfo->{_proxyCookies} = join '; ',
|
2017-01-10 17:09:28 +01:00
|
|
|
map { s/;.*$//; $_ } $resp->header('Set-Cookie');
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug( 'Store remote cookies in session ('
|
|
|
|
. $req->sessionInfo->{_proxyCookies}
|
|
|
|
. ')' );
|
2021-09-09 14:28:06 +02:00
|
|
|
$req->data->{_proxyQueryDone}++;
|
2021-04-01 23:07:58 +02:00
|
|
|
|
|
|
|
return PE_OK;
|
2017-01-10 07:04:40 +01:00
|
|
|
}
|
|
|
|
|
2021-01-02 18:58:40 +01:00
|
|
|
sub findUser {
|
|
|
|
|
|
|
|
# Nothing to do here
|
2021-04-01 23:07:58 +02:00
|
|
|
return PE_OK;
|
2021-01-02 18:58:40 +01:00
|
|
|
}
|
|
|
|
|
2017-01-10 07:04:40 +01:00
|
|
|
sub setSessionInfo {
|
|
|
|
my ( $self, $req ) = @_;
|
2018-07-05 22:56:16 +02:00
|
|
|
return PE_OK if ( $req->data->{_setSessionInfoDone} );
|
2021-09-09 14:28:06 +02:00
|
|
|
$self->logger->debug(
|
|
|
|
'Proxy requests sessionInfo to ' . $self->sessionService . '/global' );
|
2017-01-10 13:25:30 +01:00
|
|
|
my $q = HTTP::Request->new(
|
2021-09-09 14:28:06 +02:00
|
|
|
GET => $self->sessionService . '/global',
|
2017-01-10 17:09:28 +01:00
|
|
|
[
|
|
|
|
Cookie => $req->sessionInfo->{_proxyCookies},
|
|
|
|
Accept => 'application/json'
|
|
|
|
]
|
2017-01-10 13:25:30 +01:00
|
|
|
);
|
2017-01-10 17:09:28 +01:00
|
|
|
my $resp = $self->ua->request($q);
|
2017-01-10 13:25:30 +01:00
|
|
|
unless ( $resp->is_success ) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error(
|
|
|
|
'Unable to query session service: ' . $resp->status_line );
|
2017-01-10 13:25:30 +01:00
|
|
|
return PE_ERROR;
|
2017-01-10 07:04:40 +01:00
|
|
|
}
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug('Proxy gets a response');
|
2017-09-28 14:52:14 +02:00
|
|
|
my $res = eval { JSON::from_json( $resp->content, { allow_nonref => 1 } ) };
|
2017-01-10 13:25:30 +01:00
|
|
|
if ($@) {
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->error("Bad content: $@");
|
2017-01-10 07:04:40 +01:00
|
|
|
return PE_ERROR;
|
|
|
|
}
|
2017-01-10 13:25:30 +01:00
|
|
|
foreach ( keys %$res ) {
|
|
|
|
$req->{sessionInfo}->{$_} ||= $res->{$_} unless (/^_/);
|
2017-01-10 07:04:40 +01:00
|
|
|
}
|
2018-07-05 22:56:16 +02:00
|
|
|
$req->data->{_setSessionInfoDone}++;
|
2021-09-06 10:47:06 +02:00
|
|
|
|
2021-04-01 23:07:58 +02:00
|
|
|
return PE_OK;
|
2017-01-10 07:04:40 +01:00
|
|
|
}
|
|
|
|
|
2017-01-10 17:09:28 +01:00
|
|
|
sub authLogout {
|
|
|
|
my ( $self, $req ) = @_;
|
2017-02-15 07:41:50 +01:00
|
|
|
$self->logger->debug(
|
|
|
|
'Proxy ask logout to ' . $self->conf->{proxyAuthService} );
|
2017-01-10 17:09:28 +01:00
|
|
|
my $q = HTTP::Request->new(
|
|
|
|
GET => $self->conf->{proxyAuthService} . '?logout=1',
|
|
|
|
[
|
|
|
|
Cookie => $req->sessionInfo->{_proxyCookies},
|
|
|
|
Accept => 'application/json'
|
|
|
|
]
|
|
|
|
);
|
|
|
|
my $resp = $self->ua->request($q);
|
2021-09-09 14:54:40 +02:00
|
|
|
unless ( $resp->is_success ) {
|
|
|
|
$self->logger->error(
|
|
|
|
'Unable to query authentication service: ' . $resp->status_line );
|
|
|
|
return PE_OK;
|
|
|
|
}
|
|
|
|
$self->logger->debug('Proxy gets a response');
|
|
|
|
my $res = eval { JSON::from_json( $resp->content, { allow_nonref => 1 } ) };
|
|
|
|
if ($@) {
|
|
|
|
$self->logger->error("Bad content: $@");
|
|
|
|
return PE_OK;
|
|
|
|
}
|
|
|
|
my $user = $req->{sessionInfo}->{ $self->conf->{whatToTrace} };
|
|
|
|
unless ( $res->{result} ) {
|
|
|
|
$self->userLogger->warn("Internal Portal logout failed for $user")
|
|
|
|
if $user;
|
|
|
|
return PE_OK;
|
|
|
|
}
|
|
|
|
$self->userLogger->notice(
|
|
|
|
"User $user has been disconnected from internal Portal")
|
|
|
|
if $user;
|
2021-09-10 22:13:51 +02:00
|
|
|
|
2017-01-10 17:09:28 +01:00
|
|
|
return PE_OK;
|
|
|
|
}
|
|
|
|
|
2017-01-10 07:04:40 +01:00
|
|
|
1;
|
|
|
|
|