Skip to content
Snippets Groups Projects
account-manager-client.pl 13.3 KiB
Newer Older
#!/usr/bin/perl

## Copyright (c) GEANT
## This software was developed by RENATER. The research leading to these results has received funding
## from the European Community¹s Seventh Framework Programme (FP7/2007-2013) under grant agreement nº 238875 (GÉANT).

## 18/07/2014, Olivier Salaün
## Command-line client for the Test IdP Account Manager

use strict;
use utf8;
use lib qw(lib conf);
use Getopt::Long qw(:config auto_help);
use Pod::Usage;
use IdPAccountManager::TestAccount;
use IdPAccountManager::ServiceProvider;
use IdPAccountManager::AuthenticationToken;
use IdPAccountManager::Logger;

my %options;
unless (
        \%options,                  'add_test_account',
        'account_profile=s',        'sp_entityid=s',
        'list_test_accounts',       'parse_federation_metadata',
        'list_service_providers',   'list_authentication_tokens',
        'get_authentication_token', 'add_authentication_token',
        'email_address=s',          'token=s',
        'send_notice',              'filter_expired',
        'delete',                   'add_service_provider',
        'contacts=s',               'displayname=s'
    )
  )
{
    pod2usage(
        -message => "unknown option, aborting\n",
        -verbose => 0
    );
if ($options{'add_test_account'}) {
    my $logger = IdPAccountManager::Logger->new(
        file      => $Conf::global{'log_file'},
        verbosity => $Conf::global{'log_level'}
    );

    unless ($options{'account_profile'}) {
        die "Missing account_profile option";
    }

    unless ($options{'sp_entityid'}) {
        die "Missing sp_entityid option";
    }
    my $test_account = IdPAccountManager::TestAccount->new(
        account_profile => $options{'account_profile'},
        sp_entityid     => $options{'sp_entityid'}
    );
    unless (defined $test_account) {
        $logger->log(level => LOG_ERROR, message => "Failed to create test account");
        exit -1;
    unless ($test_account->save()) {
        $logger->log(level => LOG_ERROR, message => "Failed to create test account");

    printf "Account created:\n\tuserid: user%d\n\tpassword: %s\n",
      $test_account->get('id'), $test_account->get('user_password');

} elsif ($options{'list_test_accounts'}) {

    my $logger = IdPAccountManager::Logger->new(
        file      => $Conf::global{'log_file'},
        verbosity => $Conf::global{'log_level'}
    );

    my %args;
    if ($options{'sp_entityid'}) {
        push @{ $args{'query'} }, 'sp_entityid' => $options{'sp_entityid'};
    if ($options{'account_profile'}) {
        push @{ $args{'query'} },
          'account_profile' => $options{'account_profile'};
    if ($options{'filter_expired'}) {
        push @{ $args{'query'} }, 'expiration_date' => { lt => time };
    my $all = IdPAccountManager::TestAccount::list_test_accounts(%args);
        printf "No matching test account in DB\n";
    foreach my $test_account (@$all) {
        $test_account->print();
        $test_account->delete || die if ($options{'delete'});
        printf "%d accounts removed\n", $#{$all} + 1;

        ## Update simpleSamlPhp configuration file
        printf "Update simpleSamlPhp configuration file...\n";
        unless(IdPAccountManager::Tools::update_ssp_authsources()) {
            $logger->log(
                level   => LOG_ERROR,
                message => "Failed to create simpleSAMLphp configuration file"
            );
        }
} elsif ($options{'parse_federation_metadata'}) {
    my $federation_metadata = IdPAccountManager::SAMLMetadata->new();
    unless (
        $federation_metadata->load(
            federation_metadata_file_path =>
              $Conf::global{'federation_metadata_file_path'}
        )
      )
    {
    my %args;
    if ($options{'sp_entityid'}) {
        $args{'filter_entity_id'} = $options{'sp_entityid'};
    }

    unless ($federation_metadata->parse(%args)) {

    printf "Document %s parsed\n",
      $Conf::global{'federation_metadata_file_path'};

    ## List SAML entities
    printf "Hashref representing the metadata:\n";
    IdPAccountManager::Tools::dump_var(
        $federation_metadata->{'federation_metadata_as_hashref'},
        0, \*STDOUT);

} elsif ($options{'add_service_provider'}) {

    my $logger = IdPAccountManager::Logger->new(
        file      => $Conf::global{'log_file'},
        verbosity => $Conf::global{'log_level'}
    );

    unless ($options{'sp_entityid'}) {
        die "Missing sp_entityid option";
    }

    unless ($options{'contacts'}) {
        die "Missing contacts option";
    }
    ## Check if entry already exists in DB first
    my $service_provider =
      IdPAccountManager::ServiceProvider->new(
        entityid => $options{'sp_entityid'});
    if ($service_provider->load(speculative => 1)) {
        printf "Entry for %s already in DB; update it with new data\n",
          $options{'sp_entityid'};

        $service_provider->contacts($options{'contacts'});
        $service_provider->displayname($options{'displayname'})
          if ($options{'displayname'});
    } else {

        $service_provider = IdPAccountManager::ServiceProvider->new(
            entityid    => $options{'sp_entityid'},
            contacts    => $options{'contacts'},
            displayname => $options{'displayname'}
        );
        unless (defined $service_provider) {
            $logger->log(level => LOG_ERROR, message => "Failed to create service provider");
            exit -1;
    unless ($service_provider->save()) {
        $logger->log(level => LOG_ERROR, message => "Failed to create service provider");
    printf "Service Provider created:\n";

} elsif ($options{'list_service_providers'}) {

    my %args;

    my $all = IdPAccountManager::ServiceProvider::list_service_providers(%args);
    if ($#{$all} < 0) {
        printf "No service provider in DB\n";
    }
    foreach my $service_provider (@$all) {
        $service_provider->print();
    }

} elsif ($options{'list_authentication_tokens'}) {

    my %args;
    if ($options{'sp_entityid'}) {
        push @{ $args{'query'} }, 'sp_entityid' => $options{'sp_entityid'};
    }
    if ($options{'token'}) {
        push @{ $args{'query'} }, 'token' => $options{'token'};
    if ($options{'filter_expired'}) {
        push @{ $args{'query'} }, 'creation_date' =>
          { lt => time - ($Conf::global{'tokens_validity_period'} * 3600) };

    my $all =
      IdPAccountManager::AuthenticationToken::list_authentication_tokens(%args);

        printf "No corresponding token found in DB\n";
    foreach my $authentication_token (@$all) {
        $authentication_token->print();
        $authentication_token->delete || die if ($options{'delete'});
    if ($options{'delete'}) {
        printf "%d tokens removed\n", $#{$all} + 1;

    }
} elsif ($options{'get_authentication_token'}) {

    my %args;
    if ($options{'token'}) {
        $args{'token'} = $options{'token'};
    }

    my $authentication_token =
      IdPAccountManager::AuthenticationToken->new(%args);
    unless ($authentication_token->load()) {
        die "No corresponding token found in DB\n";
    }
    if ($options{'sp_entityid'}) {
        unless ($authentication_token->get('sp_entityid') eq
            $options{'sp_entityid'})
        {
            die "Authentication token cannot be used for this SP\n";
        }
    }

    $authentication_token->print();

} elsif ($options{'add_authentication_token'}) {

    my $logger = IdPAccountManager::Logger->new(
        file      => $Conf::global{'log_file'},
        verbosity => $Conf::global{'log_level'}
    );

    unless ($options{'email_address'}) {
        die "Missing email_address option";

    unless ($options{'sp_entityid'}) {
        die "Missing sp_entityid option";
    }
    my $authentication_token = IdPAccountManager::AuthenticationToken->new(
        'email_address' => $options{'email_address'},
        'sp_entityid'   => $options{'sp_entityid'}
    );
    unless (defined $authentication_token) {
        $logger->log(level => LOG_ERROR, message => "Failed to create token object");
        exit -1;

    ## First remove token if on exist for this email+SP
    if ($authentication_token->load()) {
        unless ($authentication_token->delete()) {
            $logger->log(level => LOG_ERROR, message => "Failed to delete token");
        $authentication_token = IdPAccountManager::AuthenticationToken->new(
            'email_address' => $options{'email_address'},
            'sp_entityid'   => $options{'sp_entityid'}
        );
        unless (defined $authentication_token) {
            $logger->log(level => LOG_ERROR, message => "Failed to create token object");
    unless ($authentication_token->save()) {
        $logger->log(level => LOG_ERROR, message => "Failed to create token");
    $authentication_token->print();

} elsif ($options{'send_notice'}) {
    unless ($options{'email_address'}) {
        die "Missing email_address option";
    }

    unless (
        IdPAccountManager::Tools::mail_notice(
            'template' => 'templates/mail/notification_generic_error.tt2.eml',
            'data'     => {},
            'to'       => $options{'email_address'}
            'logger'   => $logger
        die "Failed to send mail notice to $options{'email_address'}\n";
    }
    printf "Mail notice sent to $options{'email_address'}\n";
    pod2usage(
        -message => "missing argument, aborting\n",
        -verbose => 0
    );
account-manager-client.pl - Command line client to the Test Account manager
B<account-manager-client.pl> B<--add_test_account>
S<B<--account_profile> I<string>>
S<B<--sp_entityid> I<string>>

B<account-manager-client.pl> B<--list_test_accounts>
S<[B<--account_profile> I<string>]>
S<[B<--sp_entityid> I<string>]>
[B<--filter_expired>]
[B<--delete>]

B<account-manager-client.pl> B<--parse_federation_metadata>
S<[B<--sp_entityid> I<string>]>

B<account-manager-client.pl> B<--add_service_provider>
S<B<--sp_entityid> I<string>>
S<B<--contact> I<string>>
S<[B<--displayname> I<string>]>

B<account-manager-client.pl> B<--list_service_providers>

B<account-manager-client.pl> B<--list_authentication_tokens>
S<B<--sp_entityid> I<string>>
S<[B<--token> I<string>]>
[B<--filter_expired>]
[B<--delete>]

B<account-manager-client.pl> B<--get_authentication_token>
S<B<--sp_entityid> I<string>>
S<[B<--token> I<string>]>

B<account-manager-client.pl> B<--add_authentication_token>
S<B<--sp_entityid> I<string>>
S<B<--email_address> I<string>>

B<account-manager-client.pl> B<--send_notice>
S<B<--email_address> I<string>>
The Test Account manager instanciates test accounts associated to a SAML
Identity Provider.  This script provides a command-line interface for most
functions.
    $> account-manager-client.pl --add_test_account \
    --sp_entityid=https://test.federation.renater.fr/test/ressource
    --account_profile=student1 \

Adds a new test account.

    $> account-manager-client.pl --list_test_accounts \
    --sp_entityid=https://test.federation.renater.fr/test/ressource \
    --account_profile=student1

List all test accounts. Criterias can be added to filter test accounts.

    $> account-manager-client.pl --list_test_accounts --filter_expired
    $> account-manager-client.pl --list_test_accounts --filter_expired \
    --delete

Remove all expired test accounts from DB.

    $> account-manager-client.pl --parse_federation_metadata
Parses the SAML metadata file, as defined by the
C<federation_metadata_file_path> configuration parameter.
    $> account-manager-client.pl --list_authentication_tokens \
    --sp_entityid=https://test.federation.renater.fr/test/ressource \
    --token=dhj67sjJ

List all authentication tokens. Criterias can be added to filter tokens.

    $> account-manager-client.pl --list_authentication_tokens \
    --filter_expired

List all expired authentication tokens.

    $> account-manager-client.pl --list_authentication_tokens \
    --filter_expired --delete

Remove all expired authentication tokens from DB.

    $> account-manager-client.pl --get_authentication_token \
    --token=dhj67sjJ

Get informations on a token.

    $> account-manager-client.pl --add_authentication_token \
    --email_address=john@my.fqdn \
    --sp_entityid=https://test.federation.renater.fr/test/ressource

Adds a new test account.

    $> account-manager-client.pl --send_notice --email_address=john@my.fqdn

Sends a mail notice to the specified email address.

    $> account-manager-client.pl --add_service_provider \
    --sp_entityid=='https://test.federation.renater.fr/test/ressource _
    --displayname='Test SP' --contacts=email1@dom,email2@dom

Adds a new Service provider

Olivier Salaün (olivier.salaun@renater.fr)

=head1 LICENSE

Copyright (c) GEANT
This software was developed by RENATER. The research leading to these results has received funding
from the European Community¹s Seventh Framework Programme (FP7/2007-2013) under grant agreement nº 238875 (GÉANT).