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

use strict;
use utf8;
use lib qw(@modulesdir@);
use feature "switch";
no warnings 'experimental::smartmatch';
use Data::Dumper;
use English qw(-no_match_vars);
use Getopt::Long qw(:config auto_help);
use Log::Any::Adapter;
use Pod::Usage;
use IdPAccountManager::AuthenticationToken;
use IdPAccountManager::AuthenticationToken::Manager;
use IdPAccountManager::ServiceProvider;
use IdPAccountManager::ServiceProvider::Manager;
use IdPAccountManager::TestAccount;
use IdPAccountManager::TestAccount::Manager;
use IdPAccountManager::Configuration;
use IdPAccountManager::SAMLMetadata;
use IdPAccountManager::Tools;

my %options;
GetOptions(
    \%options,
    'account_profile=s',
    'contacts=s',
    'delete',
    'displayname=s',
    'email_address=s',
    'filter_expired',
    'sp_entityid=s',
    'token=s',
) or pod2usage(
    -message => "unknown option, aborting\n",
    -verbose => 0
);

my $action = $ARGV[0];

pod2usage(
    -message => "no action given, aborting\n",
    -verbose => 0
) unless $action;

my $configuration = IdPAccountManager::Configuration->new(
    file => '@sysconfdir@/manager.conf'
IdPAccountManager::DB->register_db(
    driver   => $configuration->{database_type},
    database => $configuration->{database_name},
    host     => $configuration->{database_host},
    password => $configuration->{database_password},
    username => $configuration->{database_user}
);

my $db = IdPAccountManager::DB->new();
    when ('add_account')    { add_account()           }
    when ('list_accounts')  { list_accounts()         }
    when ('add_provider')   { add_provider()       }
    when ('list_providers') { list_providers()     }
    when ('add_token')      { add_token()   }
    when ('get_token')      { get_token()   }
    when ('list_tokens')    { list_tokens() }
    when ('parse_metadata') { parse_metadata()  }
    default {
        pod2usage(
            -message => "invalid action '$action', aborting\n",
            -verbose => 0
        );
    }
}
sub add_account {
    pod2usage(
        -message => "missing account_profile option, aborting\n",
        -verbose => 0
    ) unless $options{account_profile};
    pod2usage(
        -message => "missing sp_entityid option, aborting\n",
        -verbose => 0
    ) unless $options{sp_entityid};
    my $test_account = IdPAccountManager::TestAccount->new(
        account_profile => $options{account_profile},
        sp_entityid     => $options{sp_entityid}
    die "Failed to create test account\n"
        unless $test_account;

    die "Failed to save test account\n"
        unless $test_account->save(
            accounts_validity_period => $configuration->{accounts_validity_period}

    printf "Account created:\n\tuserid: user%d\n\tpassword: %s\n",
      $test_account->id(), $test_account->user_password();
sub list_accounts {
    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 };
        IdPAccountManager::TestAccount::Manager->get_testaccounts(db => $db, %args);
        printf "No matching test account in DB\n";
    foreach my $account (@$accounts) {
        $account->print();
    if ($options{delete}) {
        foreach my $account (@$accounts) {
            $account->delete() or die "failed to delete test account\n";
        }
        printf "%d accounts removed\n", scalar @$accounts;
            IdPAccountManager::TestAccount::Manager->get_testaccounts(
        eval {
            IdPAccountManager::Tools::update_ssp_authsources(
                $configuration->{templates_dir},
                $configuration->{idp_accounts_file},
                $configuration->{idp_scope},
        };
        die "failed to update simpleSAMLphp configuration file: $EVAL_ERROR"
            if $EVAL_ERROR;
        printf "Update simpleSamlPhp configuration file...\n";
    }

sub parse_metadata {
    my $federation_metadata;
        $federation_metadata = IdPAccountManager::SAMLMetadata->new(
            file => $configuration->{federation_metadata_file}
    };
    die "unable to load federation metadata: $EVAL_ERROR" if $EVAL_ERROR;
    my $data = $federation_metadata->parse(id => $options{sp_entityid});

    printf "Document %s parsed\n",
      $configuration->{federation_metadata_file};
    ## List SAML entities
    printf "Hashref representing the metadata:\n";
    print Dumper->Dump($data);
sub add_provider {
    pod2usage(
        -message => "missing sp_entityid option, aborting\n",
        -verbose => 0
    ) unless $options{sp_entityid};
    pod2usage(
        -message => "missing contacts option, aborting\n",
        -verbose => 0
    ) unless $options{contacts};
    ## Check if entry already exists in DB first
    my $provider = IdPAccountManager::ServiceProvider->new(
        entityid => $options{sp_entityid}
    if ($provider->load(speculative => 1)) {
        printf "Entry for %s already in DB; update it with new data\n",
          $options{sp_entityid};
        $provider->contacts($options{contacts});
        $provider->displayname($options{displayname}) if $options{displayname};
    } else {
        $provider = IdPAccountManager::ServiceProvider->new(
            entityid    => $options{sp_entityid},
            contacts    => $options{contacts},
            displayname => $options{displayname}
        die "failed to create service provider\n"
            unless $provider;
    $provider->save() or die "failed to save service provider";
    printf "Service Provider created\n";
sub list_providers {
    my $providers = IdPAccountManager::ServiceProvider::Manager->get_serviceproviders(db => $db, %args);
    if (! @$providers) {
        printf "No service provider in DB\n";
    }
    foreach my $provider (@$providers) {
        $provider->print();
    if ($options{delete}) {
        foreach my $provider (@$providers) {
            $provider->delete() or die "failed to delete authentication token\n";
        }
        printf "%d providers removed\n", scalar @$providers;
    }
sub list_tokens {
    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 - ($configuration->{tokens_validity_period} * 3600) };
      IdPAccountManager::AuthenticationToken::Manager->get_authenticationtokens(db => $db, %args);
        printf "No corresponding token found in DB\n";
    foreach my $token (@$tokens) {
        $token->print();
    if ($options{delete}) {
        foreach my $token (@$tokens) {
            $token->delete() or die "failed to delete authentication token\n";
        }
        printf "%d tokens removed\n", scalar @$tokens;
sub get_token {
    if ($options{token}) {
        $args{token} = $options{token};
    my $token =
      IdPAccountManager::AuthenticationToken->new(db => $db, %args);
    die "No corresponding token found in DB\n"
        unless $token->load();
    if ($options{sp_entityid}) {
        die "Authentication token cannot be used for this SP\n"
            unless $token->get('sp_entityid') eq $options{sp_entityid};
    $token->print();
sub add_token {
    pod2usage(
        -message => "missing email_address option, aborting\n",
        -verbose => 0
    ) unless $options{email_address};
    pod2usage(
        -message => "missing sp_entityid option, aborting\n",
        -verbose => 0
    ) unless $options{sp_entityid};
    my $token = IdPAccountManager::AuthenticationToken->new(
        db            => $db,
        email_address => $options{email_address},
        sp_entityid   => $options{sp_entityid}

    die "failed to create authentication token\n"
        unless $token;

    ## First remove token if on exist for this email+SP
    if ($token->load(speculative => 1)) {
        $token->delete() or die "failed to delete authentication token\n";
        $token = IdPAccountManager::AuthenticationToken->new(
            db            => $db,
            email_address => $options{email_address},
            sp_entityid   => $options{sp_entityid}
        die "failed to create authentication token\n"
            unless $token;
    $token->save() or die "failed to save authentication token\n";
    $token->print();
account-manager-client.pl - Command line client to the Test IdP Account manager
B<account-manager-client.pl> B<add_account>
S<B<--account_profile> I<string>>
S<B<--sp_entityid> I<string>>

B<account-manager-client.pl> B<list_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_metadata>
S<[B<--sp_entityid> I<string>]>

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

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

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

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

=head1 DESCRIPTION

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_account \
Guillaume ROUSSE's avatar
Guillaume ROUSSE committed
    --sp_entityid https://test.federation.renater.fr/test/ressource \
    --account_profile student1

Adds a new test account.

    $> account-manager-client.pl list_accounts \
Guillaume ROUSSE's avatar
Guillaume ROUSSE committed
    --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_accounts --filter_expired
    $> account-manager-client.pl list_accounts --filter_expired \
    --delete

Remove all expired test accounts from DB.

    $> account-manager-client.pl parse_metadata
Parses the SAML metadata file, as defined by the
C<federation_metadata_file> configuration parameter.
    $> account-manager-client.pl list_tokens \
Guillaume ROUSSE's avatar
Guillaume ROUSSE committed
    --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_tokens \
    --filter_expired

List all expired authentication tokens.

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

Remove all expired authentication tokens from DB.

    $> account-manager-client.pl get_token \
Guillaume ROUSSE's avatar
Guillaume ROUSSE committed
    --token dhj67sjJ

Get informations on a token.

    $> account-manager-client.pl add_token \
Guillaume ROUSSE's avatar
Guillaume ROUSSE committed
    --email_address john@my.fqdn \
    --sp_entityid https://test.federation.renater.fr/test/ressource

Adds a new test account.

    $> account-manager-client.pl add_provider \
Guillaume ROUSSE's avatar
Guillaume ROUSSE committed
    --sp_entityid https://test.federation.renater.fr/test/ressource \
    --displayname 'Test SP' --contacts email1@dom,email2@dom

Adds a new Service provider