#!/usr/bin/env perl # expire-sessions: Run regularly to remove old sessions (plus # can set up data for 'log user out' admin functionality, and # inactive user processing). use v5.14; use warnings; BEGIN { use File::Basename qw(dirname); use File::Spec; my $d = dirname(File::Spec->rel2abs($0)); require "$d/../setenv.pl"; } use FixMyStreet::DB; use Getopt::Long; use List::Util qw(uniq); GetOptions( # Update sessions to make sure all present in User objects 'init' => \my $init, ); my $rs = FixMyStreet::DB->resultset("Session"); my $now = time(); # Delete expired sessions (including from in User object) # And update last active time of current sessions while (my $session = $rs->next) { my $id = $session->id_code; my $user = $session->user; my $expires = $session->expires; if (!$expires || $expires < $now) { if ($user) { my $sessions = $user->get_extra_metadata('sessions'); my @new_sessions = grep { $_ ne $id } @$sessions; update_user_sessions($user, \@new_sessions) if @new_sessions != @$sessions; } $session->delete; } elsif ($user && $init) { my $sessions = $user->get_extra_metadata('sessions'); my @new_sessions = uniq @$sessions, $id; update_user_sessions($user, \@new_sessions) if @new_sessions != @$sessions; } if ($user) { update_user_last_active($user, $expires); $user->update; } } # --- sub update_user_last_active { my ($user, $expires) = @_; return unless $expires; my $t = DateTime->from_epoch(epoch => $expires)->subtract(weeks => 4); $user->set_last_active($t) if !$user->last_active || $user->last_active < $t; } sub update_user_sessions { my ($user, $sessions) = @_; if (@$sessions) { $user->set_extra_metadata('sessions', $sessions); } else { $user->unset_extra_metadata('sessions'); } }