diff options
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | perllib/Catalyst/Plugin/FixMyStreet/Session/StoreSessions.pm | 23 | ||||
-rw-r--r-- | perllib/FixMyStreet/App.pm | 3 | ||||
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 11 | ||||
-rw-r--r-- | t/app/controller/admin/users.t | 10 | ||||
-rw-r--r-- | t/app/controller/report_new.t | 8 | ||||
-rw-r--r-- | templates/web/base/admin/user-form.html | 1 |
7 files changed, 50 insertions, 7 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 680d4b412..c2efc0ddd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - Fix error sending `requires_inspection` reports. #1961 - Admin improvements: - Admin can anonymize/hide all a user's reports. #1942 #1943 + - Admin can log a user out. #1975 - UK: - Lazy load images in the footer. diff --git a/perllib/Catalyst/Plugin/FixMyStreet/Session/StoreSessions.pm b/perllib/Catalyst/Plugin/FixMyStreet/Session/StoreSessions.pm new file mode 100644 index 000000000..5e7a3cede --- /dev/null +++ b/perllib/Catalyst/Plugin/FixMyStreet/Session/StoreSessions.pm @@ -0,0 +1,23 @@ +package Catalyst::Plugin::FixMyStreet::Session::StoreSessions; +use Moose::Role; +use namespace::autoclean; + +after set_authenticated => sub { + my $c = shift; + my $sessions = $c->user->get_extra_metadata('sessions'); + push @$sessions, $c->sessionid; + $c->user->set_extra_metadata('sessions', $sessions); + $c->user->update; +}; + +before logout => sub { + my $c = shift; + if (my $user = $c->user) { + my $sessions = $user->get_extra_metadata('sessions'); + $sessions = [ grep { $_ ne $c->sessionid } @$sessions ]; + @$sessions ? $user->set_extra_metadata('sessions', $sessions) : $user->unset_extra_metadata('sessions'); + $user->update; + } +}; + +__PACKAGE__; diff --git a/perllib/FixMyStreet/App.pm b/perllib/FixMyStreet/App.pm index e47336b7c..a3331d32a 100644 --- a/perllib/FixMyStreet/App.pm +++ b/perllib/FixMyStreet/App.pm @@ -18,13 +18,14 @@ use URI; use URI::QueryParam; use Catalyst ( - 'Static::Simple', # + 'Static::Simple', 'Unicode::Encoding', 'Session', 'Session::Store::DBIC', 'Session::State::Cookie', # FIXME - we're using our own override atm 'Authentication', 'SmartURI', + 'FixMyStreet::Session::StoreSessions', ); extends 'Catalyst'; diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index a1d301249..c2470e325 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -1423,6 +1423,8 @@ sub user_edit : Path('user_edit') : Args(1) { if ( $c->get_param('submit') and $c->get_param('unban') ) { $c->forward('unban_user', [ $user ]); + } elsif ( $c->get_param('submit') and $c->get_param('logout_everywhere') ) { + $c->forward('user_logout_everywhere', [ $user ]); } elsif ( $c->get_param('submit') and $c->get_param('anon_everywhere') ) { $c->forward('user_anon_everywhere', [ $user ]); } elsif ( $c->get_param('submit') and $c->get_param('hide_everywhere') ) { @@ -1756,6 +1758,15 @@ sub ban_user : Private { return 1; } +sub user_logout_everywhere : Private { + my ( $self, $c, $user ) = @_; + my $sessions = $user->get_extra_metadata('sessions'); + foreach (grep { $_ ne $c->sessionid } @$sessions) { + $c->delete_session_data("session:$_"); + } + $c->stash->{status_message} = _('That user has been logged out.'); +} + sub user_anon_everywhere : Private { my ( $self, $c, $user ) = @_; $user->problems->update({anonymous => 1}); diff --git a/t/app/controller/admin/users.t b/t/app/controller/admin/users.t index e6cf51449..187652b3c 100644 --- a/t/app/controller/admin/users.t +++ b/t/app/controller/admin/users.t @@ -410,4 +410,14 @@ subtest "Hiding user's reports from admin" => sub { is $c, $count_u; }; +subtest "Logging user out" => sub { + my $mech2 = FixMyStreet::TestMech->new; + $mech2->log_in_ok($user->email); + $mech2->logged_in_ok; + + $mech->get_ok( '/admin/user_edit/' . $user->id ); + $mech->submit_form_ok({ button => 'logout_everywhere' }, 'Logging user out'); + $mech2->not_logged_in_ok; +}; + done_testing(); diff --git a/t/app/controller/report_new.t b/t/app/controller/report_new.t index e0fe205bd..95461fa8f 100644 --- a/t/app/controller/report_new.t +++ b/t/app/controller/report_new.t @@ -1236,9 +1236,7 @@ for my $test ( is $user->title, $test->{'user_title'}, 'user title correct'; is_deeply $extras, $test->{extra}, 'extra contains correct values'; - $user->problems->delete; - $user->alerts->delete; - $user->delete; + $mech->delete_user($user); }; } @@ -1705,9 +1703,7 @@ subtest "extra google analytics code displayed on email confirmation problem cre $mech->content_contains( "'id': 'report/" . $report->id . "'", 'extra google code present' ); - $user->problems->delete; - $user->alerts->delete; - $user->delete; + $mech->delete_user($user); }; }; diff --git a/templates/web/base/admin/user-form.html b/templates/web/base/admin/user-form.html index 63d4858ab..ca0a3c496 100644 --- a/templates/web/base/admin/user-form.html +++ b/templates/web/base/admin/user-form.html @@ -200,6 +200,7 @@ </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') %]"> <li><input class="btn-danger" type="submit" name="anon_everywhere" value="[% loc('Make anonymous on all reports and updates') %]"> <li><input class="btn-danger" type="submit" name="hide_everywhere" value="[% loc('Hide all reports and updates') %]"> </ul> |