diff --git a/bin/account-manager-client.pl b/bin/account-manager-client.pl index 79a2c3c06b86ee289f6362786bf016435a259892..8f98bfaa0c6227da24c9d64c3ca2a15ae5012b2f 100755 --- a/bin/account-manager-client.pl +++ b/bin/account-manager-client.pl @@ -134,7 +134,8 @@ if ($options{'add_test_account'}) { IdPAccountManager::Tools::do_log('error',"Failed to create token object"); exit -1; } - unless ($authentication_token->set('email_address' => $options{'email_address'})) { + unless ($authentication_token->set('email_address' => $options{'email_address'}, + 'sp_entityid' => $options{'sp_entityid'})) { IdPAccountManager::Tools::do_log('error',"Failed to set token value"); exit -1; } diff --git a/bin/account-manager-web.pl b/bin/account-manager-web.pl index 5707ee989e3ecf13b2872f986b59cb2a01cd83f8..eaf7e61cf25f0f134e2ccb5c88d0bde0b50cbc26 100755 --- a/bin/account-manager-web.pl +++ b/bin/account-manager-web.pl @@ -17,6 +17,9 @@ use POSIX; use IdPAccountManager::TestAccount; use IdPAccountManager::SAMLMetadata; +use IdPAccountManager::ServiceProvider; + +use IdPAccountManager::AuthenticationToken; ## Defining parameters format my $urn_or_url_regex = '(http(s?):\/\/|urn:)[^\\\$\*\"\'\`\^\|\<\>\n\s]+'; ## Format de type URL HTTP ou URN @@ -31,6 +34,7 @@ my %format = ( my %actions = ('select_sp' => {'title_en' => 'Select your Service Provider' }, 'get_sp_list' => {'title_en' => 'Select your Service Provider' }, + 'generate_token' => {'title_en' => 'Generate an authentication token'}, ); ## Gives writes for the group @@ -210,17 +214,18 @@ sub respond { } ## Ignore some type of errors - #my @errors_admin; - #foreach my $id_error (@{$self->{'param_out'}{'errors'}}) { - # unless ($id_error =~ /^(error_x)$/) { - # push @errors_admin, $id_error; - # } - #} + my @errors_admin; + foreach my $id_error (@{$self->{'param_out'}{'errors'}}) { + unless ($id_error =~ /^(error_x)$/) { + push @errors_admin, $id_error; + } + } ## Mail notification of admins about the error - &IdPAccountManager::Tools::mail_notice('template' => 'templates/mail/notification_generic_error.tt2.eml', - 'data' => $self->{'param_out'}); - + if (@errors_admin) { + &IdPAccountManager::Tools::mail_notice('template' => 'templates/mail/notification_generic_error.tt2.eml', + 'data' => $self->{'param_out'}); + } } ## Return the list of known SPs @@ -276,3 +281,55 @@ sub req_select_sp { return 1; } + +## Generate an authentication token to validate an email address +## Sample call : dev-edugain.renater.fr/accountmanager?action=generate_token&style=nobanner&sp_entityid=https%3A%2F%2Fsourcesup.cru.fr%2Fshibboleth&email_address=support%40renater.fr +sub req_generate_token { + my $self = shift; + &IdPAccountManager::Tools::do_log('info', ""); + + unless ($self->{'param_in'}{'sp_entityid'}) { + push @{$self->{'param_out'}{'errors'}}, "missing_sp_entityid"; + &IdPAccountManager::Tools::do_log('error', "Missing parameter sp_entityid"); + return undef; + } + + unless ($self->{'param_in'}{'email_address'}) { + push @{$self->{'param_out'}{'errors'}}, "email_address"; + &IdPAccountManager::Tools::do_log('error', "Missing parameter email_address"); + return undef; + } + + my $authentication_token = new IdPAccountManager::AuthenticationToken(); + unless (defined $authentication_token) { + push @{$self->{'param_out'}{'errors'}}, "internal"; + &IdPAccountManager::Tools::do_log('error', "Failed to create authentication token"); + return undef; + } + + unless ($authentication_token->set('email_address' => $self->{'param_in'}{'email_address'}, + 'sp_entityid' => $self->{'param_in'}{'sp_entityid'})) { + push @{$self->{'param_out'}{'errors'}}, "internal"; + &IdPAccountManager::Tools::do_log('error', "Failed to update authentication token"); + return undef; + } + + unless ($authentication_token->save()) { + push @{$self->{'param_out'}{'errors'}}, "internal"; + &IdPAccountManager::Tools::do_log('error', "Failed to save authentication token"); + return undef; + } + + $self->{'param_out'}{'authentication_token'} = $authentication_token->get('token'); + $self->{'param_out'}{'email_address'} = $self->{'param_in'}{'email_address'}; + $self->{'param_out'}{'sp_entityid'} = $self->{'param_in'}{'sp_entityid'}; + $self->{'param_out'}{'to'} = $self->{'param_in'}{'email_address'}; + + ## Send the challenge email with the token + &IdPAccountManager::Tools::mail_notice('template' => 'templates/mail/send_authentication_token.tt2.eml', + 'data' => $self->{'param_out'}); + + return 1; +} + + diff --git a/lib/IdPAccountManager/AuthenticationToken.pm b/lib/IdPAccountManager/AuthenticationToken.pm index 3ebc1570d2e20461fdc24d429e44a41e6b668ba6..94ede6f36c78cd9fc34540e38ce4184e91553c02 100644 --- a/lib/IdPAccountManager/AuthenticationToken.pm +++ b/lib/IdPAccountManager/AuthenticationToken.pm @@ -92,8 +92,8 @@ sub print { my $self = shift; my $fd = shift || \*STDOUT; - printf $fd "AuthenticationToken ID=%s; token=%s; email_address=%s; creation_date=%s\n", - $self->get('id'), $self->get('token'), $self->get('email_address'), + 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'))); return 1. diff --git a/lib/IdPAccountManager/Tools.pm b/lib/IdPAccountManager/Tools.pm index e0df349626c6ab14f28a7d5dc15da6f5c7894ff7..d00bfd7df087cd64aefeb372c2b22cd35d0af3b4 100644 --- a/lib/IdPAccountManager/Tools.pm +++ b/lib/IdPAccountManager/Tools.pm @@ -153,14 +153,10 @@ sub mail_notice { $mail_data->{'to'} = $notice_email; ## Protection to prevent notifications during test dev phases - ## Notify only adresses @renater.fr + ## Notify only admin_email if ($Conf::global{'no_mail_outside'}) { - foreach my $email (split /,/, $notice_email) { - unless ($email =~ /\@(cru|renater)\.fr$/) { - &do_log('error',"Notification to an external address skipped"); - return undef; - } - } + &do_log('info',"no_mail_outside option set; notification for %s rerouted to admins ; ", $notice_email); + $notice_email = $Conf::global{'admin_email'}; } &do_log('trace', '(template=%s, to=%s)', $in{'template'}, $mail_data->{'to'}); diff --git a/templates/mail/send_authentication_token.tt2.eml b/templates/mail/send_authentication_token.tt2.eml new file mode 100644 index 0000000000000000000000000000000000000000..cfc11cd508ea1379a1633f4984e0e12970e76930 --- /dev/null +++ b/templates/mail/send_authentication_token.tt2.eml @@ -0,0 +1,13 @@ +From: [% conf.app_name %] <[% conf.notice_from %]> +To: [% to %] +Subject: [% conf.app_name %] - Test accounts request +Content-type: text/plain; charset=UTF-8; format=flowed + +This is an email challenge automatically sent to you by [% conf.app_name %]. Somebody has requested creation of test accounts +for the service provider with entityid [% sp_entityid %] declared in eduGAIN interfederation. You are listed as +contact for this service provider in eduGAIN metadata. + +To complete test accounts activation you should copy and paste the validation token below in the [% conf.app_name %] web form. +Validation token: [% authentication_token %] + + diff --git a/templates/web/content.tt2.html b/templates/web/content.tt2.html index 7bf2612a16f9743a88c0896b68c7408e3c1bff85..5036c762897fbd0876eb9944764485266a9643c8 100644 --- a/templates/web/content.tt2.html +++ b/templates/web/content.tt2.html @@ -21,6 +21,13 @@ An error occured [% END %] +[% ELSIF action == 'generate_token' %] + [% TRY %] + [% PROCESS 'templates/web/generate_token.tt2.html' %] + [% CATCH %] + An error occured + [% END %] + [% ELSE %] Error: unknown action diff --git a/templates/web/generate_token.tt2.html b/templates/web/generate_token.tt2.html new file mode 100644 index 0000000000000000000000000000000000000000..f2d8ae944ccd3e0b155d973ef4d2510fbe2fe905 --- /dev/null +++ b/templates/web/generate_token.tt2.html @@ -0,0 +1,17 @@ +<h3>Validate challenge</h3> + +<div> +An email challenge including a validation token has been emailed to you at [% email_address %]. You need to copy and paste this token in the form below.</div> + +<fieldset> + <legend>Provide token</legend> + <label for="authentication_token">PLease provide the secret token here :</label> + +<input name="authentication_token" value="" id="authentication_token" type="text" class="required"/> + +<input type="hidden" name="sp_entityid" value="[% sp_entityid %]" id="sp_entityid"/> +<input type="hidden" name="email_address" value="[% email_address %]" id="email_address"/> + + +</fieldset> + diff --git a/templates/web/get_sp_list.tt2.html b/templates/web/get_sp_list.tt2.html index 36be36fe29fc731a8e80e83bec4e15fb2fec6c04..1821ba8d2334fa467e59c06febbf299c6ca154a5 100644 --- a/templates/web/get_sp_list.tt2.html +++ b/templates/web/get_sp_list.tt2.html @@ -26,6 +26,19 @@ jQuery(document).ready(function($){ }); } + // Trigger loading of the 'select_sp' with the selected SP entityid as parameter + // Result gets included in the next tab + if (currentIndex === 1 && newIndex === 2) + { + form.steps("remove", 2); + form.steps("insert", 2, { + title: "Validate challenge", + contentMode: "async", + contentUrl: "https://dev-edugain.renater.fr/accountmanager?action=generate_token&style=nobanner&sp_entityid="+ + encodeURIComponent($('#sp_entityid').val())+"&email_address="+encodeURIComponent($('#email_address').val()) + }); + } + // Allways allow previous action even if the current form is not valid! if (currentIndex > newIndex) { diff --git a/templates/web/select_sp.tt2.html b/templates/web/select_sp.tt2.html index 40488c3639996eb903537e5699f8f1303fa60de1..b28867fa125ecf921d134fd4de23398dd4e258cf 100644 --- a/templates/web/select_sp.tt2.html +++ b/templates/web/select_sp.tt2.html @@ -18,8 +18,11 @@ Before you can create test accounts at this Identity Provider, we need to ensure [% matches = contact.EmailAddress.match('^(mailto:)?(.*)$') %] [% SET email = matches.1%] -<input name="email" value="[% email %]" id="[% email %]" type="radio"/> -<label for="[% email %]">[% email %]</label> +<input name="email_address" value="[% email %]" id="email_address" type="radio" class="required"/> +<label for="email_address">[% email %]</label> + +<input type="hidden" name="sp_entityid" value="[% sp_metadata_as_hashref.entityid %]" id="sp_entityid"/> + [% END %] [% ELSE %]