URIRE
PE_OK
PE_ERROR
PE_BADCREDENTIALS
)
;
our
$VERSION
=
'2.19.0'
;
has
ua
=> (
is
=>
'rw'
);
has
cookieName
=> (
is
=>
'rw'
);
has
sessionService
=> (
is
=>
'rw'
);
sub
init {
my
(
$self
) =
@_
;
unless
(
defined
$self
->conf->{proxyAuthService}
&&
$self
->conf->{proxyAuthService} =~ URIRE )
{
$self
->error(
"Bad or missing proxyAuthService parameter"
);
return
0;
}
my
$sessionService
=
$self
->conf->{proxySessionService}
||
$self
->conf->{proxyAuthService} .
'/session/my'
;
$sessionService
=~ s
unless
(
$sessionService
=~ URIRE ) {
$self
->error(
"Malformed proxySessionService parameter"
);
return
0;
}
$self
->sessionService(
$sessionService
);
$self
->ua( Lemonldap::NG::Common::UserAgent->new(
$self
->conf ) );
$self
->ua->default_header(
Accept
=>
'application/json'
);
$self
->cookieName(
$self
->conf->{proxyCookieName}
||
$self
->conf->{cookieName} );
return
1;
}
no
warnings
'once'
;
*authenticate
= \
&getUser
;
sub
getUser {
my
(
$self
,
$req
) =
@_
;
return
PE_OK
if
(
$req
->data->{_proxyQueryDone} );
$self
->logger->debug(
'Proxy push auth to '
.
$self
->conf->{proxyAuthService} );
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} )
: ()
),
(
$self
->conf->{proxyAuthServiceImpersonation}
&&
$req
->param(
'spoofId'
)
? (
spoofId
=>
$req
->param(
'spoofId'
) )
: ()
)
}
);
unless
(
$resp
->is_success ) {
$self
->logger->error(
'Unable to query authentication service: '
.
$resp
->status_line );
return
PE_ERROR;
}
$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_ERROR;
}
unless
(
$res
->{result} ) {
$self
->userLogger->
warn
(
"Authentication failed for $req->{user}"
);
$self
->setSecurity(
$req
);
return
PE_BADCREDENTIALS;
}
my
$name
=
$self
->cookieName;
unless
(
grep
/\b
$name
=/,
$resp
->header(
'Set-Cookie'
) ) {
$self
->logger->error(
"No cookie named '$name'"
);
return
PE_ERROR;
}
$req
->sessionInfo->{_proxyCookies} =
join
'; '
,
map
{ s/;.*$//r }
$resp
->header(
'Set-Cookie'
);
$self
->logger->debug(
'Store remote cookies in session ('
.
$req
->sessionInfo->{_proxyCookies}
.
')'
);
$req
->data->{_proxyQueryDone}++;
return
PE_OK;
}
sub
findUser {
return
PE_OK;
}
sub
setSessionInfo {
my
(
$self
,
$req
) =
@_
;
return
PE_OK
if
(
$req
->data->{_setSessionInfoDone} );
$self
->logger->debug(
'Proxy requests sessionInfo to '
.
$self
->sessionService .
'/global'
);
my
$q
= HTTP::Request->new(
GET
=>
$self
->sessionService .
'/global'
,
[
Cookie
=>
$req
->sessionInfo->{_proxyCookies},
Accept
=>
'application/json'
]
);
my
$resp
=
$self
->ua->request(
$q
);
unless
(
$resp
->is_success ) {
$self
->logger->error(
'Unable to query session service: '
.
$resp
->status_line );
return
PE_ERROR;
}
$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_ERROR;
}
foreach
(
keys
%$res
) {
$req
->{sessionInfo}->{
$_
} ||=
$res
->{
$_
}
unless
(/^_/);
}
$req
->data->{_setSessionInfoDone}++;
return
PE_OK;
}
sub
authLogout {
my
(
$self
,
$req
) =
@_
;
$self
->logger->debug(
'Proxy ask logout to '
.
$self
->conf->{proxyAuthService} );
my
$q
= HTTP::Request->new(
GET
=>
$self
->conf->{proxyAuthService} .
'?logout=1'
,
[
Cookie
=>
$req
->sessionInfo->{_proxyCookies},
Accept
=>
'application/json'
]
);
my
$resp
=
$self
->ua->request(
$q
);
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
;
return
PE_OK;
}
1;