Remove XML::Simple dep in CAS issuer (#1491)

This commit is contained in:
Maxime Besson 2019-09-04 15:44:09 +02:00
parent 986a3974b0
commit 3c6c5423c1
1 changed files with 59 additions and 24 deletions

View File

@ -3,7 +3,8 @@ package Lemonldap::NG::Portal::Lib::CAS;
use strict;
use Mouse;
use Lemonldap::NG::Common::FormEncode;
use XML::Simple;
use Hash::MultiValue;
use XML::LibXML;
use Lemonldap::NG::Common::UserAgent;
our $VERSION = '2.1.0';
@ -28,6 +29,14 @@ has casAppList => ( is => 'rw', default => sub { {} }, );
has spRules => ( is => 'rw', default => sub { {} }, );
has spMacros => ( is => 'rw', default => sub { {} }, );
# XML parser
has parser => (
is => 'rw',
builder => sub {
return XML::LibXML->new( load_ext_dtd => 0, expand_entities => 0 );
}
);
# RUNNING METHODS
# Load CAS server list
@ -389,20 +398,30 @@ sub validateST {
return 0 if $response->is_error;
my $xml = $response->decoded_content( default_charset => 'UTF-8' );
utf8::encode($xml);
$xml = XMLin($xml);
my $xml = $response->decoded_content( default_charset => 'UTF-8' );
my $casResponse = $self->parser->parse_string($xml)->documentElement;
if ( defined $xml->{'cas:authenticationFailure'} ) {
unless ( $casResponse->nodeName eq "cas:serviceResponse" ) {
$self->logger->error( "Failed to validate Service Ticket $ticket: "
. $xml->{'cas:authenticationFailure'} );
. "unexpected top-level XML element: "
. $casResponse->nodeName );
return 0;
}
if ( my $failure =
$casResponse->getElementsByTagName('cas:authenticationFailure') )
{
$self->logger->error( "Failed to validate Service Ticket $ticket: "
. $failure->string_value =~ s/\R//r );
return 0;
}
# Get proxy data and store pgtId
if ($proxy_url) {
my $pgtIou =
$xml->{'cas:authenticationSuccess'}->{'cas:proxyGrantingTicket'};
$casResponse->find(
'//cas:authenticationSuccess/cas:proxyGrantingTicket')
->string_value;
if ($pgtIou) {
my $moduleOptions;
@ -435,24 +454,37 @@ sub validateST {
}
}
my $user = $xml->{'cas:authenticationSuccess'}->{'cas:user'};
my $attrs = {};
if ( my $casAttr = $xml->{'cas:authenticationSuccess'}->{'cas:attributes'} )
my $user =
$casResponse->find('//cas:authenticationSuccess/cas:user')->string_value;
unless ($user) {
$self->logger->error(
"Could not extract cas:user field from XML response");
return 0;
}
my $attrs = Hash::MultiValue->new;
if ( my $casAttr =
$casResponse->find('//cas:authenticationSuccess/cas:attributes/cas:*') )
{
foreach my $k ( keys %$casAttr ) {
my $v = $casAttr->{$k};
if ( ref($v) eq "ARRAY" ) {
$v = join( $self->conf->{multiValuesSeparator}, @$v );
$casAttr->foreach(
sub {
my $k = $_[0]->localname;
my $v = $_[0]->textContent;
utf8::encode($v);
$attrs->add( $k => $v );
}
utf8::encode($v);
$k =~ s/^cas://;
$attrs->{$k} = $v;
}
);
}
# Flatten each list of attribute values
my $result = {};
for ( $attrs->keys ) {
$result->{$_} = join $self->conf->{multiValuesSeparator},
$attrs->get_all($_);
}
# TODO store attributes for UserDBCAS
return ( $user, $attrs );
return ( $user, $result );
}
# Store PGT IOU and PGT ID
@ -484,15 +516,18 @@ sub retrievePT {
return 0 if $response->is_error;
my $xml = XMLin( $response->decoded_content );
my $casResponse = $self->parser->parse_string( $response->decoded_content )
->documentElement;
if ( defined $xml->{'cas:proxyFailure'} ) {
if ( my $failure = $casResponse->getElementsByTagName('cas:proxyFailure') )
{
$self->logger->error(
"Failed to get PT: " . $xml->{'cas:proxyFailure'} );
"Failed to get PT: " . $failure->string_value =~ s/\R//r );
return 0;
}
my $pt = $xml->{'cas:proxySuccess'}->{'cas:proxyTicket'};
my $pt =
$casResponse->find('//cas:proxySuccess/cas:proxyTicket')->string_value;
return $pt;
}