diff --git a/bin/account-manager.pl.in b/bin/account-manager.pl.in index 4356bf1a1a95d8edafe0c38e0b0ce33ed7a380f1..3a1bd57173e76eb171cfed49eee999654eb6cfc7 100755 --- a/bin/account-manager.pl.in +++ b/bin/account-manager.pl.in @@ -311,23 +311,26 @@ sub add_token { -verbose => 0 ) unless $options{sp_entityid}; - my $token = IdPAccountManager::AuthenticationToken->new( + # delete any previous token for the same email/service couple + my $old_token = IdPAccountManager::AuthenticationToken->new( db => $db, email_address => $options{email_address}, sp_entityid => $options{sp_entityid} ); - ## 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} - ); + if ($old_token->load(speculative => 1)) { + $old_token->delete() or die "failed to delete authentication token\n"; } + # compute a new token + my $token = IdPAccountManager::AuthenticationToken->new( + db => $db, + email_address => $options{email_address}, + sp_entityid => $options{sp_entityid}, + creation_date => DateTime->today(), + token => IdPAccountManager::Tools::generate_token() + ); + $token->save() or die "failed to save authentication token\n"; $token->print(); diff --git a/lib/IdPAccountManager/AuthenticationToken.pm b/lib/IdPAccountManager/AuthenticationToken.pm index cbc33158c34751d6ebd950f8f34a05253b18264a..85292f608e31768542a8499929825203eca05e69 100644 --- a/lib/IdPAccountManager/AuthenticationToken.pm +++ b/lib/IdPAccountManager/AuthenticationToken.pm @@ -5,9 +5,6 @@ use warnings; use base 'IdPAccountManager::DB::Object'; -use Digest::MD5; -use DateTime; - __PACKAGE__->meta->setup( table => 'authenticationtokens', @@ -38,25 +35,4 @@ sub print { $self->creation_date()->strftime('%Y:%m:%d'); } -sub save { - my ($self) = @_; - - # If no ID is defined, it is a new account - if (! defined $self->id()) { - $self->creation_date(DateTime->today()); - $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/Tools.pm b/lib/IdPAccountManager/Tools.pm index 9587f6ed0f21c7c2f4d7c74b9e98e3702936c3b0..bf3c930af79cbadc318c6ac6fa0ad678943edbbc 100644 --- a/lib/IdPAccountManager/Tools.pm +++ b/lib/IdPAccountManager/Tools.pm @@ -4,7 +4,9 @@ use strict; use warnings; use Digest::SHA; +use Digest::MD5; use Encode; +use English qw(-no_match_vars); use Template; # get SHA256 hash for a string @@ -61,6 +63,14 @@ sub generate_password { return $rndstring; } +# ID is based on time + PID +sub generate_token { + my ($salt, $size) = @_; + $size = 20 unless $size; + + return substr(Digest::MD5::md5_hex(time . $PID . $salt), -1 * $size); +} + ## Updates simpleSamlPhp authsources.php configuration file sub update_ssp_authsources { my ($templates_dir, $output, $accounts) = @_; diff --git a/lib/IdPAccountManager/WebRequest.pm b/lib/IdPAccountManager/WebRequest.pm index 7b40270ae99a3a27b64a73e513e2043c119bf100..d6c384cb89989cf8fcfee67e9a06bbcb74162e30 100644 --- a/lib/IdPAccountManager/WebRequest.pm +++ b/lib/IdPAccountManager/WebRequest.pm @@ -319,30 +319,33 @@ sub req_generate_token { return; } - my $token = IdPAccountManager::AuthenticationToken->new( + # delete any previous token for the same email/service couple + my $old_token = IdPAccountManager::AuthenticationToken->new( db => $self->{db}, email_address => $self->{in}->{email_address}, sp_entityid => $self->{in}->{sp_entityid} ); - ## First remove token if one exist for this email+SP - if ($token->load(speculative => 1)) { - unless ($token->delete()) { + if ($old_token->load(speculative => 1)) { + unless ($old_token->delete()) { push @{ $self->{out}->{errors} }, "internal"; $self->{logger}->errorf( "Failed to delete previous authentication token with ID %s", - $token->id() + $old_token->id() ); return; } - - $token = IdPAccountManager::AuthenticationToken->new( - db => $self->{db}, - email_address => $self->{in}->{email_address}, - sp_entityid => $self->{in}->{sp_entityid} - ); } + # compute a new token + my $token = IdPAccountManager::AuthenticationToken->new( + db => $self->{db}, + email_address => $self->{in}->{email_address}, + sp_entityid => $self->{in}->{sp_entityid}, + creation_date => DateTime->today(), + token => IdPAccountManager::Tools::generate_token() + ); + unless ($token->save()) { push @{ $self->{out}->{errors} }, "internal"; $self->{logger}->error("Failed to save authentication token");