aboutsummaryrefslogtreecommitdiffstats
path: root/bin/expire-sessions
blob: 375ba4c6f6d79559a3404969c0e7c4555c578850 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/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');
    }
}