diff --git a/lib/AccountManager/WebRequest.pm b/lib/AccountManager/WebRequest.pm index fe0587b9e6e9299aa26b0d02718541355ca79811..3215458e6895df985f91a383f5194fcb61eaaa06 100644 --- a/lib/AccountManager/WebRequest.pm +++ b/lib/AccountManager/WebRequest.pm @@ -72,24 +72,6 @@ sub new { sub run { my ($self) = @_; - # initialize output parameters - $self->{out} = { - env => { - REMOTE_HOST => $ENV{REMOTE_HOST}, - REMOTE_ADDR => $ENV{REMOTE_ADDR}, - SCRIPT_NAME => $ENV{SCRIPT_NAME} - }, - conf => { - accounts_validity_period => $self->{configuration}->{service}->{account_validity_period}, - app_name => $self->{configuration}->{app}->{name}, - app_url => $self->{configuration}->{app}->{url}, - idp_scope => $self->{configuration}->{idp}->{scope}, - idp_displayname => $self->{configuration}->{idp}->{displayname}, - support_email => $self->{configuration}->{app}->{support_email}, - version => $self->{configuration}->{app}->{version}, - }, - title => $self->{configuration}->{app}->{name} - }; # process input parameters my %parameters = $self->{cgi}->Vars(); @@ -105,11 +87,10 @@ sub run { if (defined $format{$parameter} && !ref($format{$parameter})) { if ($parameters{$parameter} !~ /^$format{$parameter}$/) { - push @{ $self->{out}->{errors} }, "format_$parameter"; $self->{logger}->error( "Incorrect parameter format : $parameter" ); - $self->respond(); + $self->respond({ errors => [ "format_$parameter" ] }); } } @@ -129,15 +110,13 @@ sub run { # process requested action my $action = $parameters{action} || 'home'; - $self->{out}->{action} = $action; if ($actions{$action}) { my $method = $actions{$action}; $self->$method(); } else { ## unknown action - push @{ $self->{out}->{errors} }, "unknown_action"; $self->{logger}->error( "Unknown action '$action'"); - $self->respond(); + $self->respond({ errors => [ "Unknown action '$action'" ] }); } return 1; @@ -145,7 +124,24 @@ sub run { ## Return HTML content sub respond { - my ($self) = @_; + my ($self, $data) = @_; + + $data->{env} = { + REMOTE_HOST => $ENV{REMOTE_HOST}, + REMOTE_ADDR => $ENV{REMOTE_ADDR}, + SCRIPT_NAME => $ENV{SCRIPT_NAME} + }; + + $data->{conf} = { + accounts_validity_period => $self->{configuration}->{service}->{account_validity_period}, + app_name => $self->{configuration}->{app}->{name}, + app_url => $self->{configuration}->{app}->{url}, + idp_scope => $self->{configuration}->{idp}->{scope}, + idp_displayname => $self->{configuration}->{idp}->{displayname}, + support_email => $self->{configuration}->{app}->{support_email}, + version => $self->{configuration}->{app}->{version}, + }; + $data->{title} = $self->{configuration}->{app}->{name}; ## Parse template my $tt2 = Template->new({ @@ -168,7 +164,7 @@ sub respond { -charset => '' ); - unless ($tt2->process($template, $self->{out}, \*STDOUT)) { + unless ($tt2->process($template, $data, \*STDOUT)) { printf "Content-type: text/plain\n\n Error: %s", $tt2->error(); $self->{logger}->errorf("Web parser error : %s", $tt2->error()); } @@ -186,23 +182,22 @@ sub req_select_sp { ); }; if ($EVAL_ERROR) { - push @{ $self->{out}->{errors} }, "internal"; $self->{logger}->error("Failed to load federation metadata: $EVAL_ERROR"); - $self->respond(); + $self->respond({ errors => [ "internal" ] }); } - $self->{out}->{metadata} = $metadata->parse(type => 'sp'); - - $self->respond(); + $self->respond({ + metadata => $metadata->parse(type => 'sp'), + action => 'select_sp' + }); } sub req_select_email { my ($self) = @_; unless ($self->{in}->{entityid}) { - push @{ $self->{out}->{errors} }, "missing_entityid"; $self->{logger}->error("Missing parameter entityid"); - $self->respond(); + $self->respond({ errors => [ "missing_entityid" ] }); } # Create a persistent service provider object @@ -223,18 +218,16 @@ sub req_select_email { ); }; if ($EVAL_ERROR) { - push @{ $self->{out}->{errors} }, "internal"; $self->{logger}->error("Failed to load federation metadata: $EVAL_ERROR"); - $self->respond(); + $self->respond({ errors => [ "internal" ] }); } my $sps = $metadata->parse(id => $self->{in}->{entityid}); if (!@$sps) { - push @{ $self->{out}->{errors} }, "no_such_entity"; $self->{logger}->errorf( "No such SP '%s' in metadata", $self->{in}->{entityid} ); - $self->respond(); + $self->respond({ errors => [ "no_such_entity" ] }); } my $sp = $sps->[0]; @@ -245,9 +238,8 @@ sub req_select_email { # save in DB unless ($provider->save()) { - push @{ $self->{out}->{errors} }, "internal"; $self->{logger}->error("Failed to save service provider object"); - $self->respond(); + $self->respond({ errors => [ "internal" ] }); } } @@ -266,24 +258,23 @@ sub req_select_email { } } - $self->{out}->{provider} = $provider; - - $self->respond(); + $self->respond({ + provider => $provider, + action => 'select_email' + }); } sub req_complete_challenge { my ($self) = @_; unless ($self->{in}->{entityid}) { - push @{ $self->{out}->{errors} }, "missing_entityid"; $self->{logger}->error("Missing parameter entityid"); - $self->respond(); + $self->respond({ errors => [ "missing_entityid" ] }); } unless ($self->{in}->{email}) { - push @{ $self->{out}->{errors} }, "missing_email"; $self->{logger}->error("Missing parameter email"); - $self->respond(); + $self->respond({ errors => [ "missing_email" ] }); } my $provider = AccountManager::Service->new( @@ -292,9 +283,8 @@ sub req_complete_challenge { ); unless ($provider->load(speculative => 1)) { - push @{ $self->{out}->{errors} }, "no_such_entity"; $self->{logger}->errorf("No such SP '%s' in database", $self->{in}->{entityid}); - $self->respond(); + $self->respond({ errors => [ "no_such_entity" ] }); } # override metadata contacts if needed @@ -315,13 +305,12 @@ sub req_complete_challenge { ## Check that email is a known contact for this SP unless ($provider->is_contact($self->{in}->{email})) { - push @{ $self->{out}->{errors} }, "internal"; $self->{logger}->errorf( "Requested a token for %s for an unautorized address '%s'", $self->{in}->{entityid}, $self->{in}->{email} ); - $self->respond(); + $self->respond({ errors => [ "internal" ] }); } # delete any previous token for the same email/service couple @@ -333,12 +322,11 @@ sub req_complete_challenge { 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", $old_token->id() ); - $self->respond(); + $self->respond({ errors => [ "internal" ] }); } } @@ -355,23 +343,18 @@ sub req_complete_challenge { ); unless ($token->save()) { - push @{ $self->{out}->{errors} }, "internal"; $self->{logger}->error("Failed to save authentication token"); - $self->respond(); + $self->respond({ errors => [ "internal" ] }); } - $self->{out}->{email} = $self->{in}->{email}; - $self->{out}->{entityid} = $self->{in}->{entityid}; - my $sender = $self->{configuration}->{_}->{notice_from}; my $recipient = $self->{in}->{email}; my $sendmail = $self->{configuration}->{_}->{sendmail_path} || '/usr/sbin/sendmail'; open(my $handle, '|-', "$sendmail -f $sender $recipient") or do { - push @{ $self->{out}->{errors} }, "mail_notification_error"; $self->{logger}->errorf("Unable to run sendmail executable: %s", $ERRNO); - $self->respond(); + $self->respond({ errors => [ "mail_notification_error" ] }); }; my $tt2 = Template->new({ @@ -395,9 +378,8 @@ sub req_complete_challenge { }; unless ($tt2->process($template, $data, $handle)) { - push @{ $self->{out}->{errors} }, "mail_notification_error"; $self->{logger}->errorf("Mail notification error: %s", $tt2->error()); - $self->respond(); + $self->respond({ errors => [ "mail_notification_error" ] }); } close $handle; @@ -409,22 +391,24 @@ sub req_complete_challenge { $token->token(), ); - $self->respond(); + $self->respond({ + email => $self->{in}->{email}, + entityid => $self->{in}->{entityid}, + action => 'complete_challenge' + }); } sub req_create_accounts { my ($self) = @_; unless ($self->{in}->{entityid}) { - push @{ $self->{out}->{errors} }, "missing_entityid"; $self->{logger}->error("Missing parameter entityid"); - $self->respond(); + $self->respond({ errors => [ "missing_entityid" ] }); } unless ($self->{in}->{token}) { - push @{ $self->{out}->{errors} }, "missing_token"; $self->{logger}->error("Missing parameter token"); - $self->respond(); + $self->respond({ errors => [ "missing_token" ] }); } my $token = AccountManager::Token->new( @@ -433,23 +417,21 @@ sub req_create_accounts { ); if (! $token->load(speculative => 1)) { - push @{ $self->{out}->{errors} }, "wrong_token"; $self->{logger}->errorf( "Failed to validate authentication token %s for entityid %s", $self->{in}->{token}, $self->{in}->{entityid} ); - $self->respond(); + $self->respond({ errors => [ "wrong_token" ] }); } if (! $token->sp_entityid() eq $self->{in}->{entityid}) { - push @{ $self->{out}->{errors} }, "wrong_token_for_sp"; $self->{logger}->errorf( "Authentication token %s cannot be used for SP with entityid %s", $self->{in}->{token}, $self->{in}->{entityid} ); - $self->respond(); + $self->respond({ errors => [ "wrong_token_for_sp" ] }); } ## delete the token @@ -488,12 +470,11 @@ sub req_create_accounts { } unless (@accounts) { - push @{ $self->{out}->{errors} }, "accounts_creation_failed"; $self->{logger}->errorf( "Failed to create test accounts for SP with entityid %s", $self->{in}->{entityid} ); - $self->respond(); + $self->respond({ errors => [ "accounts_creation_failed" ] }); } ## Update simpleSAMLphp configuration to enable test accounts @@ -509,12 +490,11 @@ sub req_create_accounts { ); }; if ($EVAL_ERROR) { - push @{ $self->{out}->{errors} }, "accounts_creation_failed"; $self->{logger}->errorf( "Failed to create simpleSAMLphp configuration file: %s", $EVAL_ERROR ); - $self->respond(); + $self->respond({ errors => [ "accounts_creation_failed" ] }); } $self->{logger}->infof( @@ -523,17 +503,20 @@ sub req_create_accounts { $self->{in}->{token} ); - $self->{out}->{entityid} = $self->{in}->{entityid}; - $self->{out}->{accounts} = \@accounts; - - $self->respond(); + $self->respond({ + accounts => \@accounts, + entityid => $self->{in}->{entityid}, + action => 'create_accounts' + }); } ## Return the homepage of the service sub req_home { my ($self) = @_; - $self->respond(); + $self->respond({ + action => 'home' + }); } 1;