Skip to content
Snippets Groups Projects
Metadata.pm 9.59 KiB
package AccessCheck::Metadata;

use Mojo::Base -base;

use English qw(-no_match_vars);
use Syntax::Keyword::Try;
use XML::LibXML qw(:libxml);

sub new {
    my ($pkg, %args) = @_;

    die "missing argument 'file'" unless defined $args{file};
    die "non-existing file $args{file}" unless -f $args{file};
    die "non-readable file $args{file}" unless -r $args{file};

    my $doc;
    try {
        $doc = XML::LibXML->load_xml(location => $args{file});
    } catch($error) {
        die "Failed to parse file: $error";
    }

    my $root = $doc->documentElement();
    my $type = $root->nodeName();

    die "incorrect root element type '$type' for file $args{file}, should be
        'EntitiesDescriptor'" unless $type =~ /EntitiesDescriptor$/;

    my $self = {
        file => $args{file},
        doc  => $doc
    };

    bless $self, $pkg;

    return $self;
}

## Parse XML structure of metadata to fill a hashref
sub parse {
    my ($self, %args) = @_;

    my @array;
    ENTITY: foreach my $EntityDescriptor (
        @{ $self->{doc}->getElementsByLocalName('EntityDescriptor') })
    {

        my $id = $EntityDescriptor->getAttribute('entityID');
        next ENTITY if $args{id} && $args{id} ne $id;

        my $data = {
            entityid => $id
        };

        foreach my $child ($EntityDescriptor->childNodes()) {

            ## Ignoring nodes of type XML::LibXML::Text or XML::LibXML::Comment
            next unless $child->nodeType() == XML_ELEMENT_NODE;

            if ($child->localname() eq 'IDPSSODescriptor') {
                # skip immediatly if requested type differs
                next ENTITY if $args{type} && $args{type} ne 'idp';

                $data->{type} = 'idp';

                foreach my $sso (
                    $child->getChildrenByLocalName('SingleSignOnService'))
                {

                    ## On ne prend en compte que les endpoints prévus