From 99aa3a4a0d467fd83ba78096cf34113df797f0d8 Mon Sep 17 00:00:00 2001
From: Daniel Friesel
Date: Tue, 30 Apr 2019 12:47:32 +0200
Subject: [PATCH] Implement deletion of inactive accounts
---
lib/Travelynx.pm | 18 +++++++++++++++---
lib/Travelynx/Command/database.pm | 12 ++++++++++++
lib/Travelynx/Command/maintenance.pm | 7 +++++++
lib/Travelynx/Controller/Account.pm | 2 ++
lib/Travelynx/Controller/Traveling.pm | 2 ++
templates/register.html.ep | 2 +-
6 files changed, 39 insertions(+), 4 deletions(-)
diff --git a/lib/Travelynx.pm b/lib/Travelynx.pm
index d828f84..99d0fb2 100755
--- a/lib/Travelynx.pm
+++ b/lib/Travelynx.pm
@@ -577,6 +577,18 @@ sub startup {
}
);
+ $self->helper(
+ 'mark_seen' => sub {
+ my ( $self, $uid ) = @_;
+
+ $self->pg->db->update(
+ 'users',
+ { last_seen => DateTime->now( time_zone => 'Europe/Berlin' ) },
+ { id => $uid }
+ );
+ }
+ );
+
$self->helper(
'update_journey_part' => sub {
my ( $self, $db, $journey_id, $key, $value ) = @_;
@@ -878,7 +890,7 @@ sub startup {
'users',
'id, name, status, public_level, email, '
. 'extract(epoch from registered_at) as registered_at_ts, '
- . 'extract(epoch from last_login) as last_login_ts, '
+ . 'extract(epoch from last_seen) as last_seen_ts, '
. 'extract(epoch from deletion_requested) as deletion_requested_ts',
{ id => $uid }
)->hash;
@@ -895,7 +907,7 @@ sub startup {
time_zone => 'Europe/Berlin'
),
last_seen => DateTime->from_epoch(
- epoch => $user_data->{last_login_ts},
+ epoch => $user_data->{last_seen_ts},
time_zone => 'Europe/Berlin'
),
deletion_requested => $user_data->{deletion_requested_ts}
@@ -967,7 +979,7 @@ sub startup {
token => $token,
password => $password,
registered_at => $now,
- last_login => $now,
+ last_seen => $now,
},
{ returning => 'id' }
);
diff --git a/lib/Travelynx/Command/database.pm b/lib/Travelynx/Command/database.pm
index be5db72..05b43d6 100644
--- a/lib/Travelynx/Command/database.pm
+++ b/lib/Travelynx/Command/database.pm
@@ -412,6 +412,18 @@ my @migrations = (
}
);
},
+
+ # v8 -> v9
+ sub {
+ my ($db) = @_;
+ $db->query(
+ qq{
+ alter table users rename column last_login to last_seen;
+ drop table user_actions;
+ update schema_version set version = 9;
+ }
+ );
+ },
);
sub setup_db {
diff --git a/lib/Travelynx/Command/maintenance.pm b/lib/Travelynx/Command/maintenance.pm
index 2030705..8c07728 100644
--- a/lib/Travelynx/Command/maintenance.pm
+++ b/lib/Travelynx/Command/maintenance.pm
@@ -13,6 +13,7 @@ sub run {
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
my $verification_deadline = $now->clone->subtract( hours => 48 );
my $deletion_deadline = $now->clone->subtract( hours => 72 );
+ my $old_deadline = $now->clone->subtract( years => 1 );
my $db = $self->app->pg->db;
my $tx = $db->begin;
@@ -80,6 +81,12 @@ sub run {
{ deletion_requested => { '<', $deletion_deadline } } );
my @uids_to_delete = $to_delete->arrays->map( sub { shift->[0] } )->each;
+ $to_delete
+ = $db->select( 'users', ['id'], { last_seen => { '<', $old_deadline } } );
+
+ push( @uids_to_delete,
+ $to_delete->arrays->map( sub { shift->[0] } )->each );
+
if ( @uids_to_delete > 10 ) {
printf STDERR (
"About to delete %d accounts, which is quite a lot.\n",
diff --git a/lib/Travelynx/Controller/Account.pm b/lib/Travelynx/Controller/Account.pm
index 962a33a..dc3adb4 100644
--- a/lib/Travelynx/Controller/Account.pm
+++ b/lib/Travelynx/Controller/Account.pm
@@ -38,6 +38,7 @@ sub do_login {
else {
if ( $self->authenticate( $user, $password ) ) {
$self->redirect_to( $self->req->param('redirect_to') // '/' );
+ $self->mark_seen( $self->current_user->{id} );
}
else {
my $data = $self->get_user_password($user);
@@ -535,6 +536,7 @@ sub account {
my ($self) = @_;
$self->render('account');
+ $self->mark_seen( $self->current_user->{id} );
}
sub json_export {
diff --git a/lib/Travelynx/Controller/Traveling.pm b/lib/Travelynx/Controller/Traveling.pm
index ee8d27d..0a7250f 100755
--- a/lib/Travelynx/Controller/Traveling.pm
+++ b/lib/Travelynx/Controller/Traveling.pm
@@ -13,6 +13,7 @@ sub homepage {
with_autocomplete => 1,
with_geolocation => 1
);
+ $self->mark_seen( $self->current_user->{id} );
}
else {
$self->render( 'landingpage', intro => 1 );
@@ -272,6 +273,7 @@ sub station {
title => "travelynx: $status->{station_name}",
);
}
+ $self->mark_seen( $self->current_user->{id} );
}
sub redirect_to_station {
diff --git a/templates/register.html.ep b/templates/register.html.ep
index 599f2b3..c1b8650 100644
--- a/templates/register.html.ep
+++ b/templates/register.html.ep
@@ -51,7 +51,7 @@
an Dritte weitergegeben. Die Datenschutzerklärung beschreibt weitere
erhobene Daten sowie deren Zweck und Speicherfristen.
- Accounts werden nach einem Jahr ohne Nutzung automatisch gelöscht.
+ Accounts werden nach einem Jahr ohne Aktivität automatisch gelöscht.
Bitte beachten: Travelynx ist ein privat betriebenes Projekt ohne