Skip to content
Snippets Groups Projects
Commit 5e5e604f authored by renater.salaun's avatar renater.salaun
Browse files

Added token validation and test accounts creation.

First working version of the code


git-svn-id: https://svn.geant.net/GEANT/edugain_testidp_account_manager/trunk@20 047e039d-479c-447e-8a29-aa6bf4a09bab
parent 8400a920
No related branches found
No related tags found
No related merge requests found
......@@ -17,7 +17,7 @@ use IdPAccountManager::ServiceProvider;
use IdPAccountManager::AuthenticationToken;
my %options;
unless (&GetOptions(\%options, 'help', 'add_test_account', 'account_profile=s', 'sp_entityid=s', 'list_test_accounts', 'parse_federation_metadata', 'list_service_providers','list_authentication_tokens', 'add_authentication_token','email_address=s')) {
unless (&GetOptions(\%options, 'help', 'add_test_account', 'account_profile=s', 'sp_entityid=s', 'list_test_accounts', 'parse_federation_metadata', 'list_service_providers','list_authentication_tokens', 'get_authentication_token', 'add_authentication_token','email_address=s','token=s')) {
die "Unknown options.";
}
......@@ -108,17 +108,45 @@ if ($options{'add_test_account'}) {
}elsif ($options{'list_authentication_tokens'}) {
my %args;
if ($options{'sp_entityid'}) {
push @{$args{'query'}}, 'sp_entityid' => $options{'sp_entityid'};
}
if ($options{'token'}) {
push @{$args{'query'}}, 'token' => $options{'token'};
}
my $all = IdPAccountManager::AuthenticationToken::list_authentication_tokens(%args);
if ($#{$all} < 0) {
printf "No token in DB\n";
printf "No corresponding token found in DB\n";
}
foreach my $authentication_token (@$all) {
$authentication_token->print();
}
}elsif ($options{'get_authentication_token'}) {
my %args;
if ($options{'token'}) {
$args{'token'} = $options{'token'};
}
my $authentication_token = new IdPAccountManager::AuthenticationToken(%args);
unless ($authentication_token->load()) {
die "No corresponding token found in DB\n";
}
if ($options{'sp_entityid'}) {
unless ($authentication_token->get('sp_entityid') eq $options{'sp_entityid'}) {
die "Authentication token cannot be used for this SP\n";
}
}
$authentication_token->print();
}elsif ($options{'add_authentication_token'}) {
unless ($options{'email_address'}) {
......
......@@ -35,6 +35,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'},
'validate_token' => {'title_en' => 'Validate an authentication token'},
);
## Gives writes for the group
......@@ -332,4 +333,68 @@ sub req_generate_token {
return 1;
}
## Validate an authentication token
## Test accounts get created
## Sample call : dev-edugain.renater.fr/accountmanager?action=validate_token&style=nobanner&sp_entityid=https%3A%2F%2Fsourcesup.cru.fr%2Fshibboleth&authentication_token=c1cfecb51ea40d39a695
sub req_validate_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'}{'authentication_token'}) {
push @{$self->{'param_out'}{'errors'}}, "missing_authentication_token";
&IdPAccountManager::Tools::do_log('error', "Missing parameter authentication_token");
return undef;
}
my $authentication_token = new IdPAccountManager::AuthenticationToken(token => $self->{'param_in'}{'authentication_token'});
unless ($authentication_token->load()) {
push @{$self->{'param_out'}{'errors'}}, "wrong_token";
&IdPAccountManager::Tools::do_log('error', "Failed to validate authentication token %s for sp_entityid %s",
$self->{'param_in'}{'token'}, $self->{'param_in'}{'sp_entityid'});
return undef;
}
unless ($authentication_token->get('sp_entityid') eq $self->{'param_in'}{'sp_entityid'}) {
push @{$self->{'param_out'}{'errors'}}, "wrong_token_for_sp";
&IdPAccountManager::Tools::do_log('error', "Authentication token %s cannot be used for SP with entityid %s",
$self->{'param_in'}{'token'}, $self->{'param_in'}{'sp_entityid'});
return undef;
}
## delete the token
unless ($authentication_token->delete()) {
&IdPAccountManager::Tools::do_log('error', "Failed to delete authentication token %s",
$self->{'param_in'}{'token'});
}
## create test accounts
my @test_accounts = &IdPAccountManager::TestAccount::create_test_accounts_for_sp(sp_entityid => $self->{'param_in'}{'sp_entityid'});
unless (@test_accounts) {
push @{$self->{'param_out'}{'errors'}}, "accounts_creation_failed";
&IdPAccountManager::Tools::do_log('error', "Failed to create test accounts for SP with entityid %s",
$self->{'param_in'}{'sp_entityid'});
return undef;
}
## Update simpleSAMLphp configuration to enable test accounts
unless (&IdPAccountManager::Tools::update_ssp_authsources()) {
push @{$self->{'param_out'}{'errors'}}, "accounts_creation_failed";
&IdPAccountManager::Tools::do_log('error', "Failed to create simpleSAMLphp configuration file");
return undef;
}
$self->{'param_out'}{'sp_entityid'} = $self->{'param_in'}{'sp_entityid'};
$self->{'param_out'}{'test_accounts'} = \@test_accounts;
return 1;
}
......@@ -41,6 +41,13 @@ sub new {
return $self;
}
## Load an authentication token from DB
sub load {
my $self = shift;
return $self->{'persistent'}->load(speculative => 1);
}
## Get object parameter
sub get {
my $self = shift;
......
......@@ -106,6 +106,35 @@ sub list_test_accounts {
return $accounts;
}
## create test accounts for all active account profiles
sub create_test_accounts_for_sp {
my %args = @_;
my @test_accounts;
unless ($args{'sp_entityid'}) {
IdPAccountManager::Tools::do_log('error',"Failed to create test account");
return undef;
}
foreach my $profile (@{$Conf::global{'account_profiles'}}) {
my $test_account = new IdPAccountManager::TestAccount(account_profile => $profile,
sp_entityid => $args{'sp_entityid'});
unless (defined $test_account) {
IdPAccountManager::Tools::do_log('error',"Failed to create test account");
return undef;
}
unless ($test_account->save()) {
IdPAccountManager::Tools::do_log('error',"Failed to create test account");
return undef;
}
push @test_accounts, $test_account;
}
return @test_accounts;
}
#before 'new' => sub { print "about to call new\n"; };
1; # Magic true value required at end of module
......
'user[% account.get('id') %]:{SHA256}[% account.get('user_password_hash') %]=' => array(
'uid' => 'user[% account.get('id') %]',
'eduPersonAffiliation' => array('member', 'faculty'),
'eduPersonScopedAffiliation' => array('member@[% conf.idp_scope %]', 'faculty@[% conf.idp_scope %]'),
'displayName' => 'Peter Smith',
'cn' => 'Peter Smith',
'mail' => 'peter.smith@[% conf.idp_scope %]',
'eduPersonPrincipalName' =>'[% account.get('id') %]@[% conf.idp_scope %]',
'eduPersonTargetedID' =>'[% conf.idp_entityid %]![% account.get('sp_entityid') %]!X622UR2A7PG1uVhATobBOrMz+Ys=',
'schacHomeOrganization' => '[% conf.idp_scope %]',
'schacHomeOrganizationType' => 'urn:schac:homeOrganizationType:int:university',
'associatedSP' => '[% account.get('sp_entityid') %]',
),
......@@ -4,10 +4,10 @@ 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.
for the service provider with entityid [% sp_entityid %]. This SAML entity is registered with eduGAIN interfederation. You are
identified as a contact for this service provider within eduGAIN metadata.
To complete test accounts activation you should copy and paste the validation token below in the [% conf.app_name %] web form.
To complete these test accounts creation, paste the following validation token on the [% conf.app_name %] web form.
Validation token: [% authentication_token %]
[% conf.app_name %]: [% conf.app_url %]
\ No newline at end of file
......@@ -28,6 +28,13 @@
An error occured
[% END %]
[% ELSIF action == 'validate_token' %]
[% TRY %]
[% PROCESS 'templates/web/validate_token.tt2.html' %]
[% CATCH %]
An error occured
[% END %]
[% ELSE %]
Error: unknown action
......
[% IF errors %]
[% FOREACH err IN errors %]
<p class="ui-state-error ui-corner-all" style="margin-top: 20px; padding: 0 .7em;"><span class="ui-icon ui-icon-info" style="float: left; margin-right: .3em;"></span>
......@@ -9,6 +10,15 @@
[% ELSIF err == 'internal' %]
internal error; administrators of the federation registry have been notified.
[% ELSIF err == 'wrong_token' %]
the validation token you provided is incorrect or it has already been used
[% ELSIF err == 'wrong_token_for_sp' %]
the validation token you provided cannot be used to obtain test accounts for this service provider ([% sp_entityid %])
[% ELSIF err == 'accounts_creation_failed' %]
failed to create your test accounts
[% ELSIF (matches = err.match('missing_(\w+)')) %]
missing parameter '[% matches.0 %]'
......@@ -19,3 +29,6 @@
</p>
<br/>
[% END %] <!-- FOREACH -->
You can report the issue to the administrators (<a href="mailto:[% conf.support_email %]>[% conf.support_email %]</a>).
[% END %]
......@@ -5,7 +5,7 @@ An email challenge including a validation token has been emailed to you at [% em
<fieldset>
<legend>Provide token</legend>
<label for="authentication_token">PLease provide the secret token here :</label>
<label for="authentication_token">Please provide the secret token here :</label>
<input name="authentication_token" value="" id="authentication_token" type="text" class="required"/>
......
......@@ -26,7 +26,7 @@ jQuery(document).ready(function($){
});
}
// Trigger loading of the 'select_sp' with the selected SP entityid as parameter
// Trigger loading of the 'generate_token' with the selected SP entityid as parameter
// Result gets included in the next tab
if (currentIndex === 1 && newIndex === 2)
{
......@@ -39,6 +39,19 @@ jQuery(document).ready(function($){
});
}
// Trigger loading of the 'validate_token' with the list of test accounts created
// Result gets included in the next tab
if (currentIndex === 2 && newIndex === 3)
{
form.steps("remove", 3);
form.steps("insert", 3, {
title: "Get test accounts",
contentMode: "async",
contentUrl: "https://dev-edugain.renater.fr/accountmanager?action=validate_token&style=nobanner&sp_entityid="+
encodeURIComponent($('#sp_entityid').val())+"&authentication_token="+encodeURIComponent($('#authentication_token').val())
});
}
// Allways allow previous action even if the current form is not valid!
if (currentIndex > newIndex)
{
......@@ -94,7 +107,7 @@ in eduGAIN inter-federation. Note that only a Service Provider administrator can
<select id="sp_entityid" name="sp_entityid" class="required">
<option value="">Select your Service Provider below</option>
[% FOREACH entity IN federation_metadata_as_hashref %]
[% FOREACH entity IN federation_metadata_as_hashref.sort('entityid') %]
<option value="[% entity.entityid %]">[% IF entity.display_name && entity.display_name.en %][% entity.display_name.en %] - [% END %][% entity.entityid %]</option>
[% END %]
</select>
......
......@@ -4,4 +4,10 @@ Content-Type: text/html
<?xml version="1.0" encoding="utf-8" ?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/x
html1/DTD/xhtml1-transitional.dtd">
[% IF errors %]
<div class="ui-widget">
[% PROCESS 'templates/web/errors.tt2.html' %]
</div>
[% ELSE %]
[% PROCESS 'templates/web/content.tt2.html' %]
[% END %]
<h3>Get test accounts</h3>
<div>
Your identity has been checked successfully.
Test accounts with different profiles have been created for you, see details below. Note that these accounts will automatically
expire in [% conf.accounts_validity_period %] days. Note also that these test accounts can only be used to login on your SP [% sp_entityid %].
<ol>
[% FOREACH test_account IN test_accounts %]
<li>account profile: [% test_account.get('account_profile') %]
<dl>
<dd>user name: user[% test_account.get('id') %]</dd>
<dd>user password: [% test_account.get('user_password') %]</dd>
</dl>
</li>
[% END %]
</ol>
You can now use these accounts to login at your federated service.
To do so, you should select "[% conf.app_name %]" in your service discovery service menu.
You should keep a record of these user names and passwords since we don't provide any mecanism to remind you the credentials. If
you forget the credentials you can however ask for new test accounts via this service.
Thank you for using the [% conf.app_name %]
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment