diff --git a/bin/Makefile.am b/bin/Makefile.am index 18bf5d1e57ab52e3367ef5b2d35fcf307a2d74f7..87cbb5bc8398b1f34f0e09aaa86e5f584ee26f56 100644 --- a/bin/Makefile.am +++ b/bin/Makefile.am @@ -1,4 +1,4 @@ -bin_SCRIPTS = access-check-manager.pl +bin_SCRIPTS = access-check-manager.pl update-metadata www_SCRIPTS = access-check-manager.cgi @@ -13,6 +13,13 @@ access-check-manager.pl: Makefile access-check-manager.pl.in < $(srcdir)/$@.in > $@ chmod +x $@ +update-metadata: Makefile update-metadata.in + sed \ + -e 's|[@]modulesdir[@]|$(modulesdir)|' \ + -e 's|[@]confdir[@]|$(confdir)|' \ + < $(srcdir)/$@.in > $@ + chmod +x $@ + access-check-manager.cgi: Makefile access-check-manager.cgi.in sed \ -e 's|[@]modulesdir[@]|$(modulesdir)|' \ diff --git a/bin/update-metadata.in b/bin/update-metadata.in new file mode 100755 index 0000000000000000000000000000000000000000..1e3832b55b92be744d03431e053004e74bc98e05 --- /dev/null +++ b/bin/update-metadata.in @@ -0,0 +1,120 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use lib qw(@modulesdir@); + +use Config::Tiny; +use English qw(-no_match_vars); +use File::Temp; +use Getopt::Long qw(:config auto_help); +use List::MoreUtils qw(uniq); +use LWP::UserAgent; +use Pod::Usage; + +use AccountManager::DB; +use AccountManager::Metadata; +use AccountManager::ServiceProvider; + +my %options; +GetOptions( + \%options, + 'configuration=s', + 'verbose', +) or pod2usage( + -message => "unknown option, aborting\n", + -verbose => 0 +); + +my $configuration_file = + $options{configuration} || '@confdir@/manager.conf'; +my $configuration = Config::Tiny->read($configuration_file); +if (!$configuration) { + die Config::Tiny->errstr() . "\n"; +} + +AccountManager::DB->register_db( + driver => $configuration->{database}->{type}, + database => $configuration->{database}->{name}, + host => $configuration->{database}->{host}, + password => $configuration->{database}->{password}, + username => $configuration->{database}->{username}, + options => [ split(/, */, $configuration->{database}->{options}) ] +); + +my $db = AccountManager::DB->new(); + +my $ua = LWP::UserAgent->new(); + +$db->begin_work(); + +AccountManager::ServiceProvider->delete_service_providers(all => 1); + +my %seen; +foreach my $id (split(/, */, $configuration->{groups}->{list})) { + my $spec = $configuration->{$id}; + next unless $spec->{type} eq 'metadata'; + print "processing federation $id\n" if $options{verbose}; + my $file = File::Temp->new(); + + print "downloading metadata from url $spec->{url}\n" if $options{verbose}; + my $response = $ua->get($spec->{url}, ':content_file' => $file->filename()); + if (!$response->is_success()) { + $db->rollback(); + die "failed to download federation metadata: " . $response->status_line(); + } + + my $metadata; + eval { + $metadata = AccountManager::Metadata->new( + file => $file + ); + }; + if ($EVAL_ERROR) { + $db->rollback(); + die "failed to load federation metadata: $EVAL_ERROR"; + } + + print "parsing metadata from file $file\n" if $options{verbose}; + my $entities; + eval { + $entities = $metadata->parse(type => 'sp'); + }; + if ($EVAL_ERROR) { + $db->rollback(); + die "failed to parse federation metadata: $EVAL_ERROR"; + } + + foreach my $entry (@$entities) { + # avoid duplicates + next if $seen{$entry->{entityid}}++; + + my $entity = AccountManager::ServiceProvider->new( + db => $db, + entityid => $entry->{entityid}, + displayname => $entry->{display_name}, + url => $entry->{url}, + ); + + $entity->contacts(uniq map { $_->{EmailAddress} } @{$entry->{contacts}}) + if $entry->{contacts}; + + $entity->save(); + } +} + +$db->commit(); + +__END__ + +=head1 NAME + +update-metadata - Out-of-band metadata processing + +=head1 SYNOPSIS + +update-metadata [options] + + Options: + --configuration <file> + --verbose