diff options
author | Struan Donald <struan@exo.org.uk> | 2018-04-19 15:58:02 +0100 |
---|---|---|
committer | Struan Donald <struan@exo.org.uk> | 2018-06-25 10:12:25 +0100 |
commit | 7c009ce048fbe36db24dd1a24f3542503db2e898 (patch) | |
tree | dba5f5e7d0b4bab9a5d3565781fe1bbd12aff807 | |
parent | 43ef59400d632c3c29321c6908128932a31148a7 (diff) |
add a send login email button to user edit page
Add a button to the user edit page that sends a login token email to the
user. Helpful for user support situations where someone is having
trouble logging in. Also for situations where you have added a user and
want to get them logged in.
Fixes #2041
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 43 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Auth.pm | 3 | ||||
-rw-r--r-- | t/app/controller/admin/users.t | 65 | ||||
-rw-r--r-- | templates/web/base/admin/user-form.html | 7 |
5 files changed, 111 insertions, 8 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d070c62f..a6bf42122 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - Defect type is recorded if category change made. #2172 - Admin improvements: - Mandatory defect type selection if defect raised. + - Send login email button on user edit page #2041 - Open311 improvements: - CLOSED status maps to 'closed' state if extended statuses are enabled. diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 9d6c7d922..dfea6f8d4 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -1417,12 +1417,6 @@ sub user_add : Path('user_edit') : Args(0) { my $email_v = $c->get_param('email_verified'); my $phone_v = $c->get_param('phone_verified'); - unless ($email || $phone) { - $c->stash->{field_errors}->{username} = _('Please enter a valid email or phone number'); - } - if (!$email_v && !$phone_v) { - $c->stash->{field_errors}->{username} = _('Please verify at least one of email/phone'); - } if ($email && !is_valid_email($email)) { $c->stash->{field_errors}->{email} = _('Please enter a valid email'); } @@ -1430,6 +1424,13 @@ sub user_add : Path('user_edit') : Args(0) { $c->stash->{field_errors}->{name} = _('Please enter a name'); } + unless ($email || $phone) { + $c->stash->{field_errors}->{username} = _('Please enter a valid email or phone number'); + } + if (!$email_v && !$phone_v) { + $c->stash->{field_errors}->{username} = _('Please verify at least one of email/phone'); + } + if ($phone_v) { my $parsed_phone = $c->forward('phone_check', [ $phone ]); $phone = $parsed_phone if $parsed_phone; @@ -1503,6 +1504,11 @@ sub user_edit : Path('user_edit') : Args(1) { $c->forward('user_hide_everywhere', [ $user ]); } elsif ( $c->get_param('submit') and $c->get_param('remove_account') ) { $c->forward('user_remove_account', [ $user ]); + } elsif ( $c->get_param('submit') and $c->get_param('send_login_email') ) { + my $email = lc $c->get_param('email'); + my %args = ( email => $email ); + $args{user_id} = $id if $user->email ne $email || !$user->email_verified; + $c->forward('send_login_email', [ \%args ]); } elsif ( $c->get_param('submit') ) { my $edited = 0; @@ -1917,6 +1923,31 @@ sub user_hide_everywhere : Private { $c->stash->{status_message} = _('That user’s reports and updates have been hidden.'); } +sub send_login_email : Private { + my ( $self, $c, $args ) = @_; + + my $token_data = { + email => $args->{email}, + }; + + $token_data->{old_user_id} = $args->{user_id} if $args->{user_id}; + $token_data->{name} = $args->{name} if $args->{name}; + + my $token_obj = $c->model('DB::Token')->create({ + scope => 'email_sign_in', + data => $token_data, + }); + + $c->stash->{token} = $token_obj->token; + my $template = 'login.txt'; + + # do not use relative URIs in the email, obvs. + $c->uri_disposition('absolute'); + $c->send_email( $template, { to => $args->{email} } ); + + $c->stash->{status_message} = _('The user has been sent a login email'); +} + # Anonymize and remove name from all problems/updates, disable all alerts. # Remove their account's email address, phone number, password, etc. sub user_remove_account : Private { diff --git a/perllib/FixMyStreet/App/Controller/Auth.pm b/perllib/FixMyStreet/App/Controller/Auth.pm index fa3403f6d..41674e377 100644 --- a/perllib/FixMyStreet/App/Controller/Auth.pm +++ b/perllib/FixMyStreet/App/Controller/Auth.pm @@ -224,7 +224,8 @@ sub token : Path('/M') : Args(1) { my $data = $c->forward('get_token', [ $url_token, 'email_sign_in' ]) || return; $c->stash->{token_not_found} = 1, return - if $data->{old_user_id} && (!$c->user_exists || $c->user->id ne $data->{old_user_id}); + if $data->{old_user_id} && $data->{r} && $data->{r} eq 'auth/change_email/success' + && (!$c->user_exists || $c->user->id ne $data->{old_user_id}); my $type = $data->{login_type} || 'email'; $c->detach( '/auth/process_login', [ $data, $type ] ); diff --git a/t/app/controller/admin/users.t b/t/app/controller/admin/users.t index 0d8290c37..37d95feed 100644 --- a/t/app/controller/admin/users.t +++ b/t/app/controller/admin/users.t @@ -401,6 +401,71 @@ FixMyStreet::override_config { $user = $mech->create_user_ok('test@example.com', name => 'Test User'); +subtest "Send login email from admin" => sub { + $mech->email_count_is(0); + $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->submit_form_ok( + { + button => 'send_login_email' + }, + "send login email form submitted" + ); + + my $email = $mech->get_email; + ok $email, "got an email"; + + is $email->header('Subject'), "Your FixMyStreet account details", + "subject is correct"; + is $email->header('To'), $user->email, "to is correct"; + + my $link = $mech->get_link_from_email($email); + + my $mech2 = FixMyStreet::TestMech->new; + $mech2->not_logged_in_ok; + $mech2->get_ok($link); + $mech2->logged_in_ok; + $mech2->log_out_ok; + + $mech->clear_emails_ok; +}; + +subtest "Send login email from admin for unverified email" => sub { + $user->update( { email_verified => 0 } ); + $mech->email_count_is(0); + $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->submit_form_ok( + { + button => 'send_login_email' + }, + "send login email form submitted" + ); + + my $email = $mech->get_email; + ok $email, "got an email"; + + is $email->header('Subject'), "Your FixMyStreet account details", + "subject is correct"; + is $email->header('To'), 'test@example.com', "to is correct"; + + my $link = $mech->get_link_from_email($email); + + my $mech2 = FixMyStreet::TestMech->new; + $mech2->not_logged_in_ok; + $mech2->get_ok($link); + $mech2->logged_in_ok; + + my $test_user = FixMyStreet::DB->resultset('User')->search({ + email => $user->email + }, { order_by => [ { -desc => 'id' } ] } ); + $user->discard_changes; + + is $test_user->count, 1, "only one user"; + is $test_user->first->id, $user->id, "User is same"; + ok $user->email_verified, 'email is verified now'; + $mech2->log_out_ok; + $user->update( { email_verified => 1 } ); +}; + subtest "Anonymizing user from admin" => sub { $mech->create_problems_for_body(4, 2237, 'Title'); my $count_p = FixMyStreet::DB->resultset('Problem')->search({ user_id => $user->id })->count; diff --git a/templates/web/base/admin/user-form.html b/templates/web/base/admin/user-form.html index e8e647a09..bb8511726 100644 --- a/templates/web/base/admin/user-form.html +++ b/templates/web/base/admin/user-form.html @@ -17,7 +17,11 @@ <input type='text' class="form-control" name='name' id='name' value='[% user.name | html %]'> </li> <li><label for="email">[% loc('Email:') %]</label> - <input type='text' class="form-control" id='email' name='email' value='[% user.email | html %]'></li> + <input type='text' class="form-control" id='email' name='email' value='[% user.email | html %]'> + [% IF user %] + <input class="btn" type="submit" name="send_login_email" value="[% loc('Send login email') %]"> + [% END %] + </li> <li><label class="inline" for="email_verified">[% loc('Email verified:') %]</label> <input type="checkbox" id="email_verified" name="email_verified" value="1" [% user.email_verified ? ' checked' : '' %]> <li><label for="phone">[% loc('Phone:') %]</label> @@ -190,6 +194,7 @@ <p> <input type="submit" class="btn" name="Submit changes" value="[% loc('Submit changes') %]" > </p> + [% IF user AND NOT user.from_body %] <ul class="no-bullets danger-zone"> <li><input class="btn-danger" type="submit" name="logout_everywhere" value="[% loc('Log out of all sessions') %]"> |