aboutsummaryrefslogtreecommitdiffstats
path: root/perllib/FixMyStreet/App/Controller/Tokens.pm
diff options
context:
space:
mode:
authorMatthew Somerville <matthew-github@dracos.co.uk>2015-07-09 20:33:51 +0100
committerMatthew Somerville <matthew@mysociety.org>2015-07-10 13:49:25 +0100
commit2ac123a2e0e4594099a11057647ffc190219993d (patch)
tree4cfa460cb78461b6c5958f6d06dce497d11378a5 /perllib/FixMyStreet/App/Controller/Tokens.pm
parenta978c0a1ad216f7004ef88b8a58b9731242155dc (diff)
Alter token logging in and timeout behaviour.
Restrict email_sign_in token to one day, unused confirmation tokens to one month. Used tokens will redirect to the created thing but not log in; don't log in with alert links (unsubscribe link never expires, reply link will still show "reopen" tickbox).
Diffstat (limited to 'perllib/FixMyStreet/App/Controller/Tokens.pm')
-rw-r--r--perllib/FixMyStreet/App/Controller/Tokens.pm107
1 files changed, 79 insertions, 28 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Tokens.pm b/perllib/FixMyStreet/App/Controller/Tokens.pm
index 96bcedd37..21c269502 100644
--- a/perllib/FixMyStreet/App/Controller/Tokens.pm
+++ b/perllib/FixMyStreet/App/Controller/Tokens.pm
@@ -43,17 +43,17 @@ sub confirm_problem : Path('/P') {
# Load the problem
my $data = $auth_token->data;
- my $problem_id = ref $data ? $data->{id} : $data;
+ $data = { id => $data } unless ref $data;
+
+ my $problem_id = $data->{id};
# Look at all problems, not just cobrand, in case am approving something we don't actually show
my $problem = $c->model('DB::Problem')->find( { id => $problem_id } )
|| $c->detach('token_error');
$c->stash->{report} = $problem;
- if ( $problem->state eq 'unconfirmed' && $auth_token->created < DateTime->now->subtract( months => 1 ) ) {
- $c->stash->{template} = 'errors/generic.html';
- $c->stash->{message} = _("I'm afraid we couldn't validate that token, as the report was made too long ago.");
- return;
- }
+ $c->detach('token_too_old')
+ if $problem->state eq 'unconfirmed'
+ && $auth_token->created < DateTime->now->subtract( months => 1 );
# check that this email or domain are not the cause of abuse. If so hide it.
if ( $problem->is_from_abuser ) {
@@ -71,7 +71,7 @@ sub confirm_problem : Path('/P') {
confirmed => \'ms_current_timestamp()',
} );
- if ( ref($data) && ( $data->{name} || $data->{password} ) ) {
+ if ( $data->{name} || $data->{password} ) {
$problem->user->name( $data->{name} ) if $data->{name};
$problem->user->phone( $data->{phone} ) if $data->{phone};
$problem->user->update;
@@ -80,21 +80,26 @@ sub confirm_problem : Path('/P') {
return 1;
}
- # We have a problem - confirm it if needed!
- my $old_state = $problem->state;
+ if ($problem->state ne 'unconfirmed') {
+ my $report_uri = $c->cobrand->base_url_for_report( $problem ) . $problem->url;
+ $c->res->redirect($report_uri);
+ return;
+ }
+
+ # We have an unconfirmed problem
$problem->update(
{
state => 'confirmed',
confirmed => \'ms_current_timestamp()',
lastupdate => \'ms_current_timestamp()',
}
- ) if $problem->state eq 'unconfirmed';
+ );
# Subscribe problem reporter to email updates
$c->forward( '/report/new/create_reporter_alert' );
# log the problem creation user in to the site
- if ( ref($data) && ( $data->{name} || $data->{password} ) ) {
+ if ( $data->{name} || $data->{password} ) {
$problem->user->name( $data->{name} ) if $data->{name};
$problem->user->phone( $data->{phone} ) if $data->{phone};
$problem->user->password( $data->{password}, 1 ) if $data->{password};
@@ -104,11 +109,6 @@ sub confirm_problem : Path('/P') {
$c->authenticate( { email => $problem->user->email }, 'no_password' );
$c->set_session_cookie_expire(0);
- if ( FixMyStreet::DB::Result::Problem->visible_states()->{$old_state} ) {
- my $report_uri = $c->cobrand->base_url_for_report( $problem ) . $problem->url;
- $c->res->redirect($report_uri);
- }
-
$c->stash->{created_report} = 'fromemail';
return 1;
}
@@ -149,21 +149,27 @@ sub confirm_alert : Path('/A') {
my $auth_token = $c->forward( 'load_auth_token', [ $token_code, 'alert' ] );
- # Load the problem
+ # Load the alert
my $alert_id = $auth_token->data->{id};
$c->stash->{confirm_type} = $auth_token->data->{type};
my $alert = $c->model('DB::Alert')->find( { id => $alert_id } )
|| $c->detach('token_error');
$c->stash->{alert} = $alert;
+ $c->detach('token_too_old')
+ if $c->stash->{confirm_type} ne 'unsubscribe'
+ && $auth_token->created < DateTime->now->subtract( months => 1 );
+
# check that this email or domain are not the cause of abuse. If so hide it.
if ( $alert->is_from_abuser ) {
$c->stash->{template} = 'tokens/abuse.html';
return;
}
- $c->authenticate( { email => $alert->user->email }, 'no_password' );
- $c->set_session_cookie_expire(0);
+ if (!$alert->confirmed && $c->stash->{confirm_type} ne 'unsubscribe') {
+ $c->authenticate( { email => $alert->user->email }, 'no_password' );
+ $c->set_session_cookie_expire(0);
+ }
$c->forward('/alert/confirm');
@@ -195,7 +201,7 @@ sub confirm_update : Path('/C') {
my $auth_token =
$c->forward( 'load_auth_token', [ $token_code, 'comment' ] );
- # Load the problem
+ # Load the update
my $data = $auth_token->data;
my $comment_id = $data->{id};
$c->stash->{add_alert} = $data->{add_alert};
@@ -204,26 +210,32 @@ sub confirm_update : Path('/C') {
|| $c->detach('token_error');
$c->stash->{update} = $comment;
+ $c->detach('token_too_old')
+ if $comment->state ne 'confirmed'
+ && $auth_token->created < DateTime->now->subtract( months => 1 );
+
# check that this email or domain are not the cause of abuse. If so hide it.
if ( $comment->is_from_abuser ) {
$c->stash->{template} = 'tokens/abuse.html';
return;
}
+ if ( $comment->state ne 'unconfirmed' ) {
+ my $report_uri = $c->cobrand->base_url_for_report( $comment->problem ) . $comment->problem->url;
+ $c->res->redirect($report_uri);
+ return;
+ }
+
if ( $data->{name} || $data->{password} ) {
$comment->user->name( $data->{name} ) if $data->{name};
$comment->user->password( $data->{password}, 1 ) if $data->{password};
$comment->user->update;
}
+
$c->authenticate( { email => $comment->user->email }, 'no_password' );
$c->set_session_cookie_expire(0);
- if ( $comment->confirmed ) {
- my $report_uri = $c->cobrand->base_url_for_report( $comment->problem ) . $comment->problem->url;
- $c->res->redirect($report_uri);
- } else {
- $c->forward('/report/update/confirm');
- }
+ $c->forward('/report/update/confirm');
return 1;
}
@@ -234,6 +246,7 @@ sub load_questionnaire : Private {
my $auth_token = $c->forward( 'load_auth_token', [ $token_code, 'questionnaire' ] );
$c->stash->{id} = $auth_token->data;
$c->stash->{token} = $token_code;
+ $c->stash->{token_obj} = $auth_token;
my $questionnaire = $c->model('DB::Questionnaire')->find(
{ id => $c->stash->{id} },
@@ -247,11 +260,43 @@ sub questionnaire : Path('/Q') : Args(1) {
my ( $self, $c, $token_code ) = @_;
$c->forward( 'load_questionnaire', [ $token_code ] );
- $c->authenticate( { email => $c->stash->{questionnaire}->problem->user->email }, 'no_password' );
- $c->set_session_cookie_expire(0);
+ $c->detach('token_too_old') if $c->stash->{token_obj}->created < DateTime->now->subtract( months => 1 );
+
+ my $questionnaire = $c->stash->{questionnaire};
+ if (!$questionnaire->whenanswered) {
+ $c->authenticate( { email => $questionnaire->problem->user->email }, 'no_password' );
+ $c->set_session_cookie_expire(0);
+ }
$c->forward( '/questionnaire/show' );
}
+=head2 alert_to_reporter
+
+ /R/([0-9A-Za-z]{16,18}).*$
+
+A link in an update alert to a problem reporter - show the "reopen report"
+tickbox but don't log the person in.
+
+=cut
+
+sub alert_to_reporter : Path('/R') {
+ my ( $self, $c, $token_code ) = @_;
+
+ my $auth_token =
+ $c->forward( 'load_auth_token', [ $token_code, 'alert_to_reporter' ] );
+ my $data = $auth_token->data;
+
+ my $problem_id = $data->{id};
+ my $problem = $c->model('DB::Problem')->find( { id => $problem_id } )
+ || $c->detach('token_error');
+
+ $c->detach('token_too_old') if $auth_token->created < DateTime->now->subtract( months => 1 );
+
+ $c->flash->{alert_to_reporter} = 1;
+ my $report_uri = $c->cobrand->base_url_for_report( $problem ) . $problem->url;
+ $c->res->redirect($report_uri);
+}
+
=head2 load_auth_token
my $auth_token =
@@ -298,6 +343,12 @@ sub token_error : Private {
$c->stash->{template} = 'tokens/error.html';
}
+sub token_too_old : Private {
+ my ( $self, $c ) = @_;
+ $c->stash->{token_not_found} = 1;
+ $c->stash->{template} = 'auth/token.html';
+}
+
__PACKAGE__->meta->make_immutable;
1;