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