aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md1
-rw-r--r--perllib/Catalyst/Plugin/FixMyStreet/Session/StoreSessions.pm23
-rw-r--r--perllib/FixMyStreet/App.pm3
-rw-r--r--perllib/FixMyStreet/App/Controller/Admin.pm11
-rw-r--r--t/app/controller/admin/users.t10
-rw-r--r--t/app/controller/report_new.t8
-rw-r--r--templates/web/base/admin/user-form.html1
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>