From cb737a5cb98758619ef3cb534d4acaf46129bd64 Mon Sep 17 00:00:00 2001 From: Guillaume Rousse <guillaume.rousse@renater.fr> Date: Thu, 2 Nov 2017 14:50:51 +0100 Subject: [PATCH] merge AuthenticationToken and Data::AuthenticationToken classes --- bin/account-manager-client.pl | 25 +- bin/account-manager-web.pl | 1 - lib/IdPAccountManager/AuthenticationToken.pm | 233 ------------------ .../Data/AuthenticationToken.pm | 34 +++ lib/IdPAccountManager/WebRequest.pm | 9 +- 5 files changed, 52 insertions(+), 250 deletions(-) delete mode 100644 lib/IdPAccountManager/AuthenticationToken.pm diff --git a/bin/account-manager-client.pl b/bin/account-manager-client.pl index 9e99dee..49491db 100755 --- a/bin/account-manager-client.pl +++ b/bin/account-manager-client.pl @@ -16,11 +16,12 @@ use Getopt::Long qw(:config auto_help); use Pod::Usage; use Conf; +use IdPAccountManager::Data::AuthenticationToken; +use IdPAccountManager::Data::AuthenticationToken::Manager; use IdPAccountManager::Data::TestAccount; use IdPAccountManager::Data::TestAccount::Manager; use IdPAccountManager::SAMLMetadata; use IdPAccountManager::ServiceProvider; -use IdPAccountManager::AuthenticationToken; use IdPAccountManager::Logger; my %options; @@ -210,22 +211,22 @@ if ($action eq 'add_test_account') { { lt => time - ($Conf::global{'tokens_validity_period'} * 3600) }; } - my $all = - IdPAccountManager::AuthenticationToken::list_authentication_tokens(%args); + my $tokens = + IdPAccountManager::Data::AuthenticationToken::Manager->get_authenticationtokens(%args); - if ($#{$all} < 0) { + if (!@$tokens) { printf "No corresponding token found in DB\n"; } - foreach my $authentication_token (@$all) { - $authentication_token->print(); - next unless options{'delete'}; + foreach my $token (@$tokens) { + $token->print(); + next unless $options{'delete'}; die "failed to delete authentication token\n" - unless $authentication_token->delete(); + unless $token->delete(); } if ($options{'delete'}) { - printf "%d tokens removed\n", $#{$all} + 1; + printf "%d tokens removed\n", @$tokens; } @@ -262,7 +263,7 @@ if ($action eq 'add_test_account') { -verbose => 0 ) unless $options{'sp_entityid'}; - my $authentication_token = IdPAccountManager::AuthenticationToken->new( + my $authentication_token = IdPAccountManager::Data::AuthenticationToken->new( 'email_address' => $options{'email_address'}, 'sp_entityid' => $options{'sp_entityid'} ); @@ -271,11 +272,11 @@ if ($action eq 'add_test_account') { unless $authentication_token; ## First remove token if on exist for this email+SP - if ($authentication_token->load()) { + if ($authentication_token->load(speculative => 1)) { die "failed to delete authentication token\n" unless $authentication_token->delete(); - $authentication_token = IdPAccountManager::AuthenticationToken->new( + $authentication_token = IdPAccountManager::Data::AuthenticationToken->new( 'email_address' => $options{'email_address'}, 'sp_entityid' => $options{'sp_entityid'} ); diff --git a/bin/account-manager-web.pl b/bin/account-manager-web.pl index 2b7201a..09f0ef0 100755 --- a/bin/account-manager-web.pl +++ b/bin/account-manager-web.pl @@ -22,7 +22,6 @@ use Conf; use IdPAccountManager::SAMLMetadata; use IdPAccountManager::ServiceProvider; -use IdPAccountManager::AuthenticationToken; use IdPAccountManager::WebRequest; ## Defining parameters format diff --git a/lib/IdPAccountManager/AuthenticationToken.pm b/lib/IdPAccountManager/AuthenticationToken.pm deleted file mode 100644 index 8d03e73..0000000 --- a/lib/IdPAccountManager/AuthenticationToken.pm +++ /dev/null @@ -1,233 +0,0 @@ -package IdPAccountManager::AuthenticationToken; - -## 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). - -use strict; -use warnings; - -use IdPAccountManager::Data::AuthenticationToken; -use IdPAccountManager::Data::AuthenticationToken::Manager; - -use Digest::MD5; -use POSIX qw(strftime); - -use Carp; - -INIT { - ## Set error mode to non fatal - IdPAccountManager::Data::AuthenticationToken::Manager->error_mode('return'); -} - -sub new { - my ($pkg, %args) = @_; - - my $self = {}; - - bless $self, $pkg; - - ## Object may be created either with a hashref as argument or an IdPAccountManager::Data::AuthenticationToken object - ## Second case is usefull when fetching a set of IdPAccountManager::Data::AuthenticationToken via IdPAccountManager::Data::AuthenticationToken::Manager - if (ref($_[0]) eq 'IdPAccountManager::Data::AuthenticationToken') { - $self->{'persistent'} = $_[0]; - } else { - $self->{'persistent'} = - IdPAccountManager::Data::AuthenticationToken->new(%args); - } - - return $self; -} - -## Load an authentication token from DB -sub load { - my ($self) = @_; - - return $self->{'persistent'}->load(speculative => 1); -} - -## Get object parameter -sub get { - my ($self, $parameter) = @_; - - return $self->{'persistent'}->$parameter; -} - -## Set object parameters -sub set { - my ($self, %args) = @_; - - foreach my $parameter (keys %args) { - $self->{'persistent'}->$parameter($args{$parameter}); - } -} - -## Save object to DB -sub save { - my ($self) = @_; - - ## If no id is defined, it is a new account - unless (defined $self->{'persistent'}->id) { - $self->{'persistent'}->creation_date(time); - $self->{'persistent'} - ->token(_generate_token($self->{'persistent'}->{'email_address'})); - } - - unless ($self->{'persistent'}->save()) { - return undef; - } -} - -## Delete a test account -sub delete { - my ($self) = @_; - - unless ($self->{'persistent'}->delete()) { - return undef; - } -} - -## Print the content of a test account -sub print { - my ($self, $fd) = @_; - $fd = \*STDOUT unless $fd; - - printf $fd -"AuthenticationToken ID=%s; token=%s; email_address=%s; sp_entityid=%s; creation_date=%s\n", - $self->get('id'), $self->get('token'), $self->get('email_address'), - $self->get('sp_entityid'), - POSIX::strftime('%Y:%m:%d', localtime($self->get('creation_date'))); -} - -## list all authentication tokens -## Class method -sub list_authentication_tokens { - my (%args) = @_; - - my $persistent_tokens = - IdPAccountManager::Data::AuthenticationToken::Manager - ->get_authenticationtokens(%args); - my $authentication_tokens; - foreach my $persistent_token (@{$persistent_tokens}) { - my $authentication_token = - new IdPAccountManager::AuthenticationToken($persistent_token); - push @$authentication_tokens, $authentication_token; - } - - return $authentication_tokens; -} - -## generate a random authentication token -sub _generate_token { - my ($salt, $size) = @_; - $size = 20 unless $size; - - ## ID is based on time + PID - return substr(Digest::MD5::md5_hex(time . $$ . $salt), -1 * $size); -} - -1; -__END__ - -=head1 NAME - -IdPAccountManager::AuthenticationToken - Manage Authentication tokens used to validate test account creation requests - -=head1 SYNOPSIS - - my $authentication_token = new IdPAccountManager::AuthenticationToken(token => 'sdfkl4fslkj44'); - - unless ($authentication_token->load()) { - die "No corresponding token found in DB\n"; - } - - $authentication_token->print(); - -=head1 DESCRIPTION - -The Test Account manager instanciates test accounts associated to a SAML Identity Provider. -This module allows to manage authentication tokens to validate requestor identity. - -=head1 SUBROUTINES/METHODS - -=over 8 - -=item C<new ARGS> - -Class method. Create a new IdPAccountManager::AuthenticationToken object. -Example: - - my $authentication_token = new IdPAccountManager::AuthenticationToken(token => 'sdfkl4fslkj44'); - -Supported arguments include: - -=over 12 - -=item C<token> - -ID of the token. - -=item C<sp_entityid> - -EntityID (SAML ID) of the Service Provider associated to the authentication token. - -=item C<email_address> - -Email address of the user associated to the authentication token. - -=back - - -=item C<delete> - -Deletes the token in the database. - -=item C<get> ATTR_NAME - -Returns the value of the specified ATTR_NAME attribute of the token. - -=item C<list_authentication_tokens ARGS> - -Class method. List all tokens in database. - -Supported arguments include: - -=over 12 - -=item C<sp_entityid> - -Entityid of a SAML Service Provider to list only tokens linked to this Service Provider. - -=item C<token> - -ID of the tokens to list only those tokens. - -=back - -=item C<load> - -Loads the token from the database. - -=item C<print FD> - -Dumps the content of the authentication token to the specified FD file handler (default to STDOUT) - -=item C<set ARGS> - -Sets token attributes in ARGS. - -=item C<save> - -Save the token in the database. - -=back - -=head1 AUTHOR - -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). diff --git a/lib/IdPAccountManager/Data/AuthenticationToken.pm b/lib/IdPAccountManager/Data/AuthenticationToken.pm index 8c5c192..a888724 100644 --- a/lib/IdPAccountManager/Data/AuthenticationToken.pm +++ b/lib/IdPAccountManager/Data/AuthenticationToken.pm @@ -5,6 +5,9 @@ use warnings; use base 'IdPAccountManager::DB::Object'; +use Digest::MD5; +use POSIX qw(strftime); + __PACKAGE__->meta->setup( table => 'authenticationtokens', @@ -24,5 +27,36 @@ __PACKAGE__->meta->setup( ], ); +sub print { + my ($self, $fd) = @_; + $fd = \*STDOUT unless $fd; + + printf $fd +"AuthenticationToken ID=%s; token=%s; email_address=%s; sp_entityid=%s; creation_date=%s\n", + $self->id(), $self->token(), $self->email_address(), + $self->sp_entityid(), + POSIX::strftime('%Y:%m:%d', localtime($self->creation_date())); +} + +sub save { + my ($self) = @_; + + # If no ID is defined, it is a new account + if (! defined $self->id()) { + $self->creation_date(time); + $self->token(_generate_token($self->email_address())); + } + + $self->SUPER::save(); +} + +sub _generate_token { + my ($salt, $size) = @_; + $size = 20 unless $size; + + # ID is based on time + PID + return substr(Digest::MD5::md5_hex(time . $$ . $salt), -1 * $size); +} + 1; diff --git a/lib/IdPAccountManager/WebRequest.pm b/lib/IdPAccountManager/WebRequest.pm index 0899649..42553e9 100755 --- a/lib/IdPAccountManager/WebRequest.pm +++ b/lib/IdPAccountManager/WebRequest.pm @@ -6,6 +6,7 @@ use warnings; use English qw(-no_match_vars); use IdPAccountManager::Logger; use IdPAccountManager::Data::TestAccount; +use IdPAccountManager::Data::AuthenticationToken; use Conf; ## New web request @@ -420,7 +421,7 @@ sub req_generate_token { return undef; } - my $authentication_token = IdPAccountManager::AuthenticationToken->new( + my $authentication_token = IdPAccountManager::Data::AuthenticationToken->new( 'email_address' => $self->{'param_in'}{'email_address'}, 'sp_entityid' => $self->{'param_in'}{'sp_entityid'} ); @@ -434,7 +435,7 @@ sub req_generate_token { } ## First remove token if one exist for this email+SP - if ($authentication_token->load()) { + if ($authentication_token->load(speculative => 1)) { unless ($authentication_token->delete()) { push @{ $self->{'param_out'}{'errors'} }, "internal"; $self->{logger}->log( @@ -447,7 +448,7 @@ sub req_generate_token { return undef; } - $authentication_token = IdPAccountManager::AuthenticationToken->new( + $authentication_token = IdPAccountManager::Data::AuthenticationToken->new( 'email_address' => $self->{'param_in'}{'email_address'}, 'sp_entityid' => $self->{'param_in'}{'sp_entityid'} ); @@ -520,7 +521,7 @@ sub req_validate_token { return undef; } - my $authentication_token = IdPAccountManager::AuthenticationToken->new( + my $authentication_token = IdPAccountManager::Data::AuthenticationToken->new( token => $self->{'param_in'}{'authentication_token'}); unless ($authentication_token->load()) { -- GitLab