improve Metadata script import

This commit is contained in:
Gallavardin Antoine 2021-06-28 21:45:11 +02:00 committed by Maxime Besson
parent 4141a8e620
commit 17be15e88a

188
lemonldap-ng-common/scripts/importMetadata Executable file → Normal file
View File

@ -6,6 +6,19 @@ use Lemonldap::NG::Common::Conf;
use LWP::UserAgent; use LWP::UserAgent;
use MIME::Base64; use MIME::Base64;
use XML::LibXML; use XML::LibXML;
use Data::Dumper qw(Dumper);
sub toEntityIDkey {
my ($prefix, $entityID) = @_;
my $entityIDKey = $entityID;
$entityIDKey =~ s/^https?:\/\///;
$entityIDKey =~ s/[^a-zA-Z0-9]/-/g;
$entityIDKey =~ s/-+$//g;
return($prefix . $entityIDKey);
}
#============================================================================== #==============================================================================
# Get command line options # Get command line options
@ -16,7 +29,8 @@ my $result = GetOptions(
'certificate|c=s', 'verbose|v', 'certificate|c=s', 'verbose|v',
'help|h', 'spconfprefix|s=s', 'help|h', 'spconfprefix|s=s',
'idpconfprefix|i=s', 'warning|w', 'idpconfprefix|i=s', 'warning|w',
'remove|r' 'remove|r', 'nagios|n',
'blocklistsp|bs=s', 'blocklistidp|bi=s', 'dryrun|d'
); );
#============================================================================== #==============================================================================
@ -27,15 +41,18 @@ if ( $opts{help} or !$opts{metadata} ) {
"\nScript to import SAML metadata bundle file into LL::NG configuration\n\n"; "\nScript to import SAML metadata bundle file into LL::NG configuration\n\n";
print STDERR "Usage: $0 -m <metadata file URL>\n\n"; print STDERR "Usage: $0 -m <metadata file URL>\n\n";
print STDERR "Options:\n"; print STDERR "Options:\n";
print STDERR print STDERR "\t-c (--certificate): URL of certificate, to check metadata document signature\n";
"\t-c (--certificate): URL of certificate, to check metadata document signature\n"; print STDERR "\t-i (--idpconfprefix): Prefix used to set IDP configuration key\n";
print STDERR
"\t-i (--idpconfprefix): Prefix used to set IDP configuration key\n";
print STDERR "\t-h (--help): print this message\n"; print STDERR "\t-h (--help): print this message\n";
print STDERR "\t-m (--metadata): URL of metadata document\n"; print STDERR "\t-m (--metadata): URL of metadata document\n";
print STDERR print STDERR "\t-s (--spconfprefix): Prefix used to set SP configuration key\n";
"\t-s (--spconfprefix): Prefix used to set SP configuration key\n";
print STDERR "\t-w (--warning): print debug messages\n"; print STDERR "\t-w (--warning): print debug messages\n";
print STDERR "\t-bs (--blocklistsp): list of SP entityID to avoid to modify/import\n";
print STDERR "\t-bi (--blocklistip): list of IdP entityID to avoid to modify/import\n";
print STDERR "\t-n (--nagios) : output only metrics nagios compatible\n";
print STDERR "\t-d (--dryrun): do nothing\n";
print STDERR "\t-v (--verbose): display all actions\n";
print STDERR "\t-r (--remove): remove entityID inside LemonLDAP if was remove inside remote metadata\n";
exit 1; exit 1;
} }
@ -43,11 +60,15 @@ if ( $opts{help} or !$opts{metadata} ) {
# Default values # Default values
#============================================================================== #==============================================================================
my $spConfKeyPrefix = $opts{spconfprefix} || "sp-"; my $spConfKeyPrefix = $opts{spconfprefix} || "sp-";
my $idpConfKeyPrefix = $opts{idpconfprefix} || "idp-"; my $idpConfKeyPrefix = $opts{idpconfprefix} || "idp-";
# Set here attributes that are declared for your SP in the federation # Set here attributes that are declared for your SP in the federation
# They will be set as exported attributes for all IDP # They will be set as exported attributes for all IDP
#
my $exportedAttributes = { my $exportedAttributes = {
'cn' => '0;cn', 'cn' => '0;cn',
'eduPersonPrincipalName' => '0;eduPersonAffiliation', 'eduPersonPrincipalName' => '0;eduPersonAffiliation',
@ -101,16 +122,46 @@ my $idpCounter = {
'updated' => 0, 'updated' => 0,
'created' => 0, 'created' => 0,
'rejected' => 0, 'rejected' => 0,
'removed' => 0 'removed' => 0,
'ignored' => 0
}; };
my $spCounter = { my $spCounter = {
'found' => 0, 'found' => 0,
'updated' => 0, 'updated' => 0,
'created' => 0, 'created' => 0,
'rejected' => 0, 'rejected' => 0,
'removed' => 0 'removed' => 0,
'ignored' => 0,
}; };
############# Block List manipulation
my $blocklistsp = $opts{blocklistsp} || "";
my $blocklistidp = $opts{blocklistidp} || "";
# BlockList initialisation
my @spBlocklist = ();
my @spBlocklistKey = ();
if ( $blocklistsp ) {
@spBlocklist = split(/,/,$opts{blocklistsp});
}
my @idpBlocklist = ();
my @idpBlocklistKey = ();
if ( $blocklistidp ) {
@idpBlocklist = split(/,/,$opts{blocklistidp})
}
foreach my $s (@spBlocklist) {
push(@spBlocklistKey,toEntityIDkey($spConfKeyPrefix, $s));
}
foreach my $s (@idpBlocklist) {
push(@idpBlocklistKey,toEntityIDkey($idpConfKeyPrefix, $s));
}
#============================================================================== #==============================================================================
# Main # Main
#============================================================================== #==============================================================================
@ -232,6 +283,14 @@ foreach
my $partner_metadata = $partner->toString; my $partner_metadata = $partner->toString;
$partner_metadata =~ s/\n//g; $partner_metadata =~ s/\n//g;
# test if IDP entityID is inside the block list
if ( $entityID ~~ @idpBlocklist){
if ( $opts{verbose} ) {
print "IDP $entityID won't be update/added \n";
}
$idpCounter->{ignored}++;
}else{
# Check if entityID already in configuration # Check if entityID already in configuration
if ( defined $idpList->{$entityID} ) { if ( defined $idpList->{$entityID} ) {
@ -254,11 +313,7 @@ foreach
} }
else { else {
# Create a new partner # Create a new partner
my $entityIDKey = $entityID; my $confKey = toEntityIDkey($idpConfKeyPrefix, $entityID);
$entityIDKey =~ s/^https?:\/\///;
$entityIDKey =~ s/[^a-zA-Z0-9]/-/g;
$entityIDKey =~ s/-+$//g;
my $confKey = $idpConfKeyPrefix . $entityIDKey;
# Metadata # Metadata
$lastConf->{samlIDPMetaDataXML}->{$confKey} $lastConf->{samlIDPMetaDataXML}->{$confKey}
@ -277,6 +332,7 @@ foreach
} }
$idpCounter->{created}++; $idpCounter->{created}++;
} }
}
} }
else { else {
@ -346,9 +402,17 @@ foreach
my $partner_metadata = $partner->toString; my $partner_metadata = $partner->toString;
$partner_metadata =~ s/\n//g; $partner_metadata =~ s/\n//g;
# test if IDP entityID is inside the block list
if ( $entityID ~~ @spBlocklist){
if ( $opts{verbose} ) {
print "SP $entityID won't be update/added \n";
}
$spCounter->{ignored}++;
}else{
# Check if entityID already in configuration # Check if entityID already in configuration
if ( defined $spList->{$entityID} ) { if ( defined $spList->{$entityID} ) {
# Update metadata # Update metadata
$lastConf->{samlSPMetaDataXML}->{ $spList->{$entityID} } $lastConf->{samlSPMetaDataXML}->{ $spList->{$entityID} }
->{samlSPMetaDataXML} = $partner_metadata; ->{samlSPMetaDataXML} = $partner_metadata;
@ -358,8 +422,11 @@ foreach
->{ $spList->{$entityID} } = $requestedAttributes; ->{ $spList->{$entityID} } = $requestedAttributes;
# Update options # Update options
# $lastConf->{samlSPMetaDataOptions}->{ $spList->{$entityID} } =
# $spOptions;
# FIX AGA
$lastConf->{samlSPMetaDataOptions}->{ $spList->{$entityID} } = $lastConf->{samlSPMetaDataOptions}->{ $spList->{$entityID} } =
$spOptions; { %{$spOptions } };
if ( $opts{verbose} ) { if ( $opts{verbose} ) {
print "Update SP $entityID in configuration\n"; print "Update SP $entityID in configuration\n";
@ -368,11 +435,7 @@ foreach
} }
else { else {
# Create a new partner # Create a new partner
my $entityIDKey = $entityID; my $confKey = toEntityIDkey($spConfKeyPrefix, $entityID);
$entityIDKey =~ s/^https?:\/\///;
$entityIDKey =~ s/[^a-zA-Z0-9]/-/g;
$entityIDKey =~ s/-+$//g;
my $confKey = $spConfKeyPrefix . $entityIDKey;
# Metadata # Metadata
$lastConf->{samlSPMetaDataXML}->{$confKey}->{samlSPMetaDataXML} $lastConf->{samlSPMetaDataXML}->{$confKey}->{samlSPMetaDataXML}
@ -383,7 +446,10 @@ foreach
$requestedAttributes; $requestedAttributes;
# Options # Options
$lastConf->{samlSPMetaDataOptions}->{$confKey} = $spOptions; # $lastConf->{samlSPMetaDataOptions}->{$confKey} = $spOptions;
# FIX AGA
$lastConf->{samlSPMetaDataOptions}->{$confKey} = { %{$spOptions } };
if ( $opts{verbose} ) { if ( $opts{verbose} ) {
print print
@ -391,6 +457,13 @@ foreach
} }
$spCounter->{created}++; $spCounter->{created}++;
} }
# handle eduPersonTargetedID
if ( $requestedAttributes->{eduPersonTargetedID} ) {
delete $requestedAttributes->{eduPersonTargetedID};
$lastConf->{samlSPMetaDataOptions}->{ $spList->{$entityID} }->{samlSPMetaDataOptionsNameIDFormat} = 'persistent';
}
}
} }
else { else {
@ -408,6 +481,11 @@ foreach
if ( $opts{remove} ) { if ( $opts{remove} ) {
foreach ( keys %$idpList ) { foreach ( keys %$idpList ) {
my $idpConfKey = $idpList->{$_}; my $idpConfKey = $idpList->{$_};
if ( $idpConfKey ~~ @idpBlocklistKey){
if ( $opts{verbose} ) {
print "IDP $idpConfKey won't be deleted \n";
}
}else{
unless ( defined $mdIdpList->{$_} ) { unless ( defined $mdIdpList->{$_} ) {
delete $lastConf->{samlIDPMetaDataXML}->{$idpConfKey}; delete $lastConf->{samlIDPMetaDataXML}->{$idpConfKey};
delete $lastConf->{samlIDPMetaDataExportedAttributes} delete $lastConf->{samlIDPMetaDataExportedAttributes}
@ -419,9 +497,15 @@ if ( $opts{remove} ) {
} }
} }
} }
}
foreach ( keys %$spList ) { foreach ( keys %$spList ) {
my $spConfKey = $spList->{$_}; my $spConfKey = $spList->{$_};
if ( $spConfKey ~~ @spBlocklistKey){
if ( $opts{verbose} ) {
print "SP $spConfKey won't be deleted \n";
}
}else{
unless ( defined $mdSpList->{$_} ) { unless ( defined $mdSpList->{$_} ) {
delete $lastConf->{samlSPMetaDataXML}->{$spConfKey}; delete $lastConf->{samlSPMetaDataXML}->{$spConfKey};
delete $lastConf->{samlSPMetaDataExportedAttributes}->{$spConfKey}; delete $lastConf->{samlSPMetaDataExportedAttributes}->{$spConfKey};
@ -433,15 +517,46 @@ if ( $opts{remove} ) {
} }
} }
} }
# Register configuration
my $numConf = $conf->saveConf( $lastConf, ( cfgNumFixed => 1 ) );
unless ($numConf) {
print "[ERROR] Unable to save configuration\n";
exit 1;
} }
my $numConf = "DRY-RUN";
my $exitCode = 0;
if ( ! $opts{dryrun} ) {
# Register configuration
if ( $opts{verbose} ) {
print "[INFO] run mod EntityID will be inserted\n";
}
$numConf = $conf->saveConf( $lastConf, ( cfgNumFixed => 1 ) );
if ( $opts{verbose} ) {
print "[OK] Configuration $numConf saved\n";
$exitCode = 0;
}
unless ($numConf) {
print "[ERROR] Unable to save configuration\n";
$exitCode = 1;
}
}else{
if ( $opts{verbose} ) {
print "[INFO] Dry-run mod no EntityID inserted\n";
}
}
if ( $opts{nagios} ) {
print "Metadata loaded inside Conf: [".$numConf."]|idp_found=".$idpCounter->{found}
.", idp_updated=".$idpCounter->{updated}
.", idp_created=".$idpCounter->{created}
.", idp_removed=".$idpCounter->{removed}
.", idp_rejected=".$idpCounter->{rejected}
.", idp_ignored=".$idpCounter->{ignored}
.", sp_found=".$spCounter->{found}
.", sp_updated=".$spCounter->{updated}
.", sp_created=".$spCounter->{created}
.", sp_removed=".$spCounter->{removed}
.", sp_rejected=".$spCounter->{rejected}
.", sp_ignored=".$spCounter->{ignored}."\n";
}else{
print "[IDP]\tFound: " print "[IDP]\tFound: "
. $idpCounter->{found} . $idpCounter->{found}
. "\tUpdated: " . "\tUpdated: "
@ -451,7 +566,9 @@ print "[IDP]\tFound: "
. "\tRemoved: " . "\tRemoved: "
. $idpCounter->{removed} . $idpCounter->{removed}
. "\tRejected: " . "\tRejected: "
. $idpCounter->{rejected} . "\n"; . $idpCounter->{rejected}
. "\tIgnored: "
. $idpCounter->{ignored} . "\n";
print "[SP]\tFound: " print "[SP]\tFound: "
. $spCounter->{found} . $spCounter->{found}
. "\tUpdated: " . "\tUpdated: "
@ -461,6 +578,11 @@ print "[SP]\tFound: "
. "\tRemoved: " . "\tRemoved: "
. $spCounter->{removed} . $spCounter->{removed}
. "\tRejected: " . "\tRejected: "
. $spCounter->{rejected} . "\n"; . $spCounter->{rejected}
print "[OK] Configuration $numConf saved\n"; . "\tIgnored: "
exit 0; . $spCounter->{ignored} . "\n";
}
exit $exitCode;