SOAP server (#970)
This commit is contained in:
parent
b24343bd10
commit
1983842f79
|
@ -1,3 +1,4 @@
|
|||
* updateStatus( Main, SOAP server )
|
||||
* replace SOAP calls in Handler/Lib/AuthBasic and Auth/Proxy
|
||||
* replace SOAP by REST for notification creation
|
||||
* "mail" in UserDB/*
|
||||
|
|
|
@ -126,7 +126,7 @@ sub _connect {
|
|||
if ( $self->{proxyOptions} ) {
|
||||
push @args, %{ $self->{proxyOptions} };
|
||||
}
|
||||
$self->{ns} ||= 'urn:Lemonldap/NG/Common/CGI/SOAPService';
|
||||
$self->{ns} ||= 'urn:Lemonldap/NG/Common/PSGI/SOAPService';
|
||||
return $self->{service} = SOAP::Lite->ns( $self->{ns} )->proxy(@args);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ use bytes;
|
|||
use strict;
|
||||
use SOAP::Transport::HTTP;
|
||||
|
||||
our @ISA = ('SOAP::Transport::HTTP');
|
||||
our @ISA = ('SOAP::Transport::HTTP::Server');
|
||||
|
||||
our $VERSION = '2.0.0';
|
||||
|
||||
|
@ -17,7 +17,8 @@ sub new {
|
|||
my $self = shift;
|
||||
return $self if ref $self;
|
||||
|
||||
$self = $self->SUPER::new(@_);
|
||||
my $class = ref($self) || $self;
|
||||
$self = $class->SUPER::new(@_);
|
||||
SOAP::Trace::objects('()');
|
||||
|
||||
return $self;
|
||||
|
|
|
@ -15,9 +15,9 @@ our $VERSION = '2.0.0';
|
|||
# @param @func authorizated methods
|
||||
# @return Lemonldap::NG::Common::PSGI::SOAPService object
|
||||
sub new {
|
||||
my ( $class, $obj, @func ) = @_;
|
||||
my ( $class, $obj, $req, @func ) = @_;
|
||||
s/.*::// foreach (@func);
|
||||
return bless { obj => $obj, func => \@func }, $class;
|
||||
return bless { obj => $obj, func => \@func, req => $req }, $class;
|
||||
}
|
||||
|
||||
## @method datas AUTOLOAD()
|
||||
|
@ -30,7 +30,7 @@ sub AUTOLOAD {
|
|||
my $self = shift;
|
||||
$AUTOLOAD =~ s/.*:://;
|
||||
if ( grep { $_ eq $AUTOLOAD } @{ $self->{func} } ) {
|
||||
my $tmp = $self->{obj}->$AUTOLOAD(@_);
|
||||
my $tmp = $self->{obj}->$AUTOLOAD( $self->{req}, @_ );
|
||||
unless ( ref($tmp) and ref($tmp) eq 'SOAP::Data' ) {
|
||||
$tmp = SOAP::Data->name( result => $tmp );
|
||||
}
|
||||
|
|
|
@ -67,7 +67,7 @@ sub createSession {
|
|||
|
||||
my $soapClient = SOAP::Lite->proxy( $class->tsv->{portal}->(),
|
||||
default_headers => $soapHeaders )
|
||||
->uri('urn:Lemonldap::NG::Common::CGI::SOAPService');
|
||||
->uri('urn:Lemonldap/NG/Common/PSGI/SOAPService');
|
||||
|
||||
my $creds = $class->header_in('Authorization');
|
||||
$creds =~ s/^Basic\s+//;
|
||||
|
|
|
@ -956,7 +956,11 @@ sub attributes {
|
|||
type => 'bool',
|
||||
documentation => 'Enable SOAP services',
|
||||
},
|
||||
exportedAttr => { type => 'text', },
|
||||
exportedAttr => {
|
||||
type => 'text',
|
||||
documentation =>
|
||||
'List of attributes to export by SOAP or REST servers',
|
||||
},
|
||||
|
||||
## Virtualhosts
|
||||
|
||||
|
|
|
@ -372,6 +372,7 @@ t/32-Auth-and-issuer-OIDC-authorization_code.t
|
|||
t/32-Auth-and-issuer-OIDC-hybrid.t
|
||||
t/32-Auth-and-issuer-OIDC-implicit.t
|
||||
t/33-Auth-and-issuer-OpenID2.t
|
||||
t/34-Auth-Proxy-and-SOAP-Server.t
|
||||
t/40-Notifications-DBI.t
|
||||
t/50-IssuerGet.t
|
||||
t/90-translations.t
|
||||
|
|
|
@ -13,12 +13,12 @@ our $VERSION = '2.0.0';
|
|||
sub init {
|
||||
my ($self) = @_;
|
||||
$self->conf->{soapSessionService} ||=
|
||||
$self->conf->{soapAuthService} . 'index.pl/sessions';
|
||||
$self->conf->{soapAuthService} . '/sessions';
|
||||
$self->conf->{soapSessionService} =~ s/\.plindex.pl/\.pl/;
|
||||
$self->conf->{remoteCookieName} ||= $self->conf->{cookieName};
|
||||
|
||||
unless ( defined $self->conf->{soapAuthService} ) {
|
||||
$self->error("Missing soapAuthService parameter");
|
||||
unless ( defined $self->conf->{soapSessionService} ) {
|
||||
$self->error("Missing soapSessionService parameter");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
@ -32,7 +32,7 @@ sub getUser {
|
|||
my ( $self, $req ) = @_;
|
||||
return PE_OK if ( $req->datas->{_proxyQueryDone} );
|
||||
my $soap = SOAP::Lite->proxy( $self->conf->{soapSessionService} )
|
||||
->uri('urn:Lemonldap::NG::Common::CGI::SOAPService');
|
||||
->uri('urn:Lemonldap/NG/Common/PSGI/SOAPService');
|
||||
my $r = $soap->getCookies( $req->{user}, $req->datas->{password} );
|
||||
if ( $r->fault ) {
|
||||
$self->lmLog(
|
||||
|
@ -65,7 +65,7 @@ sub setSessionInfo {
|
|||
return PE_OK if ( $req->datas->{_setSessionInfoDone} );
|
||||
my $soap =
|
||||
SOAP::Lite->proxy( $self->conf->{soapSessionService} )
|
||||
->uri('urn:Lemonldap::NG::Common::CGI::SOAPService');
|
||||
->uri('urn:Lemonldap/NG/Common/PSGI/SOAPService');
|
||||
my $r = $soap->getAttributes( $req->datas->{_remoteId} );
|
||||
if ( $r->fault ) {
|
||||
$self->lmLog(
|
||||
|
|
|
@ -36,8 +36,10 @@ sub enabledPlugins {
|
|||
#}
|
||||
|
||||
# Check if SOAP is enabled
|
||||
# TODO: REST
|
||||
push @res, 'SOAP' if ( $self->conf->{Soap} );
|
||||
push @res, '::Plugins::SOAPServer' if ( $self->conf->{Soap} );
|
||||
|
||||
# Check if REST is enabled
|
||||
push @res, '::Plugins::RESTServer' if ( $self->conf->{rest} );
|
||||
|
||||
# Check if notification is enabled
|
||||
push @res, '::Plugins::Notifications' if ( $self->conf->{notifications} );
|
||||
|
|
|
@ -129,6 +129,7 @@ sub do {
|
|||
return $req->response;
|
||||
}
|
||||
if ( !$self->conf->{noAjaxHook} and $req->wantJSON ) {
|
||||
$self->lmLog('Processing to JSON response','debug');
|
||||
if ( $err > 0 and !%{ $req->sessionInfo } ) {
|
||||
return [
|
||||
401,
|
||||
|
@ -170,9 +171,11 @@ sub do {
|
|||
)
|
||||
{
|
||||
my ( $tpl, $prms ) = $self->display($req);
|
||||
$self->lmLog("Calling sendHtml with template $tpl",'debug');
|
||||
return $self->sendHtml( $req, $tpl, params => $prms );
|
||||
}
|
||||
else {
|
||||
$self->lmLog('Calling autoredirect','debug');
|
||||
return $self->autoRedirect($req);
|
||||
}
|
||||
}
|
||||
|
@ -227,6 +230,7 @@ sub autoRedirect {
|
|||
}
|
||||
}
|
||||
my ( $tpl, $prms ) = $self->display($req);
|
||||
$self->lmLog("Calling sendHtml with template $tpl",'debug');
|
||||
return $self->sendHtml( $req, $tpl, params => $prms );
|
||||
}
|
||||
|
||||
|
|
|
@ -148,8 +148,7 @@ sub getCookies {
|
|||
|
||||
# Launch process
|
||||
else {
|
||||
$req->{error} = $self->p->process(
|
||||
$req,
|
||||
$req->steps(
|
||||
[
|
||||
qw(getUser setAuthSessionInfo),
|
||||
@{ $self->p->betweenAuthAndDatas },
|
||||
|
@ -157,6 +156,7 @@ sub getCookies {
|
|||
@{ $self->p->afterDatas },
|
||||
]
|
||||
);
|
||||
$req->{error} = $self->p->process($req);
|
||||
$self->lmLog(
|
||||
"SOAP authentication result for $user: code $req->{error}",
|
||||
'debug' );
|
||||
|
@ -176,7 +176,9 @@ sub getCookies {
|
|||
}
|
||||
push @tmp, SOAP::Data->name( cookies => \SOAP::Data->value(@cookies) );
|
||||
my $res = SOAP::Data->name( session => \SOAP::Data->value(@tmp) );
|
||||
$self->p->updateStatus($req);
|
||||
|
||||
#TODO: updateStatus
|
||||
#$self->p->updateStatus($req);
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
@ -209,7 +211,7 @@ sub getAttributes {
|
|||
push @tmp, SOAP::Data->name( error => 0 )->type('int');
|
||||
push @tmp,
|
||||
SOAP::Data->name( attributes =>
|
||||
_buildSoapHash( $session->data, @{ $self->exportedAttr($req) } )
|
||||
_buildSoapHash( $session->data, @{ $self->exportedAttr } )
|
||||
);
|
||||
}
|
||||
my $res = SOAP::Data->name( session => \SOAP::Data->value(@tmp) );
|
||||
|
|
|
@ -50,7 +50,7 @@ sub proxyQuery {
|
|||
return PE_OK if ( $self->{_proxyQueryDone} );
|
||||
my $soap =
|
||||
SOAP::Lite->proxy( $self->{soapAuthService} )
|
||||
->uri('urn:Lemonldap::NG::Common::CGI::SOAPService');
|
||||
->uri('urn:Lemonldap/NG/Common/CGI/SOAPService');
|
||||
my $r = $soap->getCookies( $self->{user}, $self->{password} );
|
||||
if ( $r->fault ) {
|
||||
$self->abort( "Unable to query authentication service",
|
||||
|
@ -79,7 +79,7 @@ sub setSessionInfo {
|
|||
return PE_OK if ( $self->{_setSessionInfoDone} );
|
||||
my $soap =
|
||||
SOAP::Lite->proxy( $self->{soapSessionService} )
|
||||
->uri('urn:Lemonldap::NG::Common::CGI::SOAPService');
|
||||
->uri('urn:Lemonldap/NG/Common/CGI/SOAPService');
|
||||
my $r = $soap->getAttributes( $self->{_remoteId} );
|
||||
if ( $r->fault ) {
|
||||
$self->abort( "Unable to query authentication service",
|
||||
|
|
127
lemonldap-ng-portal/t/34-Auth-Proxy-and-SOAP-Server.t
Normal file
127
lemonldap-ng-portal/t/34-Auth-Proxy-and-SOAP-Server.t
Normal file
|
@ -0,0 +1,127 @@
|
|||
use Test::More;
|
||||
use strict;
|
||||
use IO::String;
|
||||
|
||||
BEGIN {
|
||||
require 't/test-lib.pm';
|
||||
}
|
||||
|
||||
my $maintests = 4;
|
||||
my $debug = 'error';
|
||||
my ( $issuer, $sp, $res );
|
||||
my %handlerOR = ( issuer => [], sp => [] );
|
||||
|
||||
SKIP: {
|
||||
eval 'use SOAP::Lite';
|
||||
if ($@) {
|
||||
skip 'SOAP::Lite not found', $maintests;
|
||||
}
|
||||
|
||||
ok( $issuer = issuer(), 'Issuer portal' );
|
||||
$handlerOR{issuer} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
||||
switch ('sp');
|
||||
|
||||
ok( $sp = sp(), 'SP portal' );
|
||||
$handlerOR{sp} = \@Lemonldap::NG::Handler::Main::Reload::_onReload;
|
||||
|
||||
# Simple SP access
|
||||
my $res;
|
||||
ok(
|
||||
$res = $sp->_get(
|
||||
'/', accept => 'text/html',
|
||||
),
|
||||
'Unauth SP request'
|
||||
);
|
||||
expectOK($res);
|
||||
|
||||
# Try to auth
|
||||
ok(
|
||||
$res = $sp->_post(
|
||||
'/', IO::String->new('user=dwho&password=dwho'),
|
||||
length => 23,
|
||||
accept => 'text/html'
|
||||
),
|
||||
'Post user/password'
|
||||
);
|
||||
expectRedirection( $res, 'http://auth.sp.com' );
|
||||
expectCookie($res);
|
||||
}
|
||||
|
||||
count($maintests);
|
||||
clean_sessions();
|
||||
done_testing( count() );
|
||||
|
||||
# Redefine LWP methods for tests
|
||||
no warnings 'redefine';
|
||||
|
||||
sub LWP::UserAgent::request {
|
||||
my ( $self, $req ) = @_;
|
||||
ok( $req->uri =~ m#http://auth.((?:id|s)p).com(.*)#, 'SOAP request' );
|
||||
my $host = $1;
|
||||
my $url = $2;
|
||||
my $res;
|
||||
my $s = $req->content;
|
||||
my $client = ( $host eq 'idp' ? $issuer : $sp );
|
||||
ok(
|
||||
$res = $client->_post(
|
||||
$url,
|
||||
IO::String->new($s),
|
||||
length => length($s),
|
||||
type => $req->header('Content-Type'),
|
||||
custom => {
|
||||
HTTP_SOAPACTION => $req->header('Soapaction'),
|
||||
},
|
||||
),
|
||||
'Execute request'
|
||||
);
|
||||
expectOK($res);
|
||||
ok( getHeader( $res, 'Content-Type' ) =~ m#^(?:text|application)/xml#,
|
||||
'Content is XML' )
|
||||
or explain( $res->[1], 'Content-Type => application/xml' );
|
||||
my $httpResp = HTTP::Response->new( $res->[0], 'OK' );
|
||||
|
||||
while ( my $name = shift @{ $res->[1] } ) {
|
||||
$httpResp->header( $name, shift( @{ $res->[1] } ) );
|
||||
}
|
||||
$httpResp->content( join( '', @{ $res->[2] } ) );
|
||||
count(3);
|
||||
return $httpResp;
|
||||
}
|
||||
|
||||
sub switch {
|
||||
my $type = shift;
|
||||
@Lemonldap::NG::Handler::Main::Reload::_onReload = @{
|
||||
$handlerOR{$type};
|
||||
};
|
||||
}
|
||||
|
||||
sub issuer {
|
||||
return LLNG::Manager::Test->new(
|
||||
{
|
||||
ini => {
|
||||
logLevel => $debug,
|
||||
templatesDir => 'site/htdocs/static',
|
||||
domain => 'idp.com',
|
||||
portal => 'http://auth.idp.com',
|
||||
authentication => 'Demo',
|
||||
userDB => 'Demo',
|
||||
Soap => 1,
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub sp {
|
||||
return LLNG::Manager::Test->new(
|
||||
{
|
||||
ini => {
|
||||
logLevel => $debug,
|
||||
domain => 'sp.com',
|
||||
portal => 'http://auth.sp.com',
|
||||
authentication => 'Proxy',
|
||||
userDB => 'Proxy',
|
||||
soapSessionService => 'http://auth.idp.com/sessions',
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
|
@ -332,7 +332,7 @@ sub _post {
|
|||
'SERVER_PORT' => '80',
|
||||
'SERVER_PROTOCOL' => 'HTTP/1.1',
|
||||
( $args{custom} ? %{ $args{custom} } : () ),
|
||||
'psgix.input.buffered' => 1,
|
||||
'psgix.input.buffered' => 0,
|
||||
'psgi.input' => $body,
|
||||
'CONTENT_LENGTH' => $args{length} // scalar( ( stat $body )[7] ),
|
||||
'CONTENT_TYPE' => $args{type}
|
||||
|
|
Loading…
Reference in New Issue
Block a user