Implement deletion of inactive accounts
This commit is contained in:
parent
867a5d4afb
commit
99aa3a4a0d
6 changed files with 39 additions and 4 deletions
|
@ -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(
|
$self->helper(
|
||||||
'update_journey_part' => sub {
|
'update_journey_part' => sub {
|
||||||
my ( $self, $db, $journey_id, $key, $value ) = @_;
|
my ( $self, $db, $journey_id, $key, $value ) = @_;
|
||||||
|
@ -878,7 +890,7 @@ sub startup {
|
||||||
'users',
|
'users',
|
||||||
'id, name, status, public_level, email, '
|
'id, name, status, public_level, email, '
|
||||||
. 'extract(epoch from registered_at) as registered_at_ts, '
|
. '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',
|
. 'extract(epoch from deletion_requested) as deletion_requested_ts',
|
||||||
{ id => $uid }
|
{ id => $uid }
|
||||||
)->hash;
|
)->hash;
|
||||||
|
@ -895,7 +907,7 @@ sub startup {
|
||||||
time_zone => 'Europe/Berlin'
|
time_zone => 'Europe/Berlin'
|
||||||
),
|
),
|
||||||
last_seen => DateTime->from_epoch(
|
last_seen => DateTime->from_epoch(
|
||||||
epoch => $user_data->{last_login_ts},
|
epoch => $user_data->{last_seen_ts},
|
||||||
time_zone => 'Europe/Berlin'
|
time_zone => 'Europe/Berlin'
|
||||||
),
|
),
|
||||||
deletion_requested => $user_data->{deletion_requested_ts}
|
deletion_requested => $user_data->{deletion_requested_ts}
|
||||||
|
@ -967,7 +979,7 @@ sub startup {
|
||||||
token => $token,
|
token => $token,
|
||||||
password => $password,
|
password => $password,
|
||||||
registered_at => $now,
|
registered_at => $now,
|
||||||
last_login => $now,
|
last_seen => $now,
|
||||||
},
|
},
|
||||||
{ returning => 'id' }
|
{ returning => 'id' }
|
||||||
);
|
);
|
||||||
|
|
|
@ -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 {
|
sub setup_db {
|
||||||
|
|
|
@ -13,6 +13,7 @@ sub run {
|
||||||
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
|
my $now = DateTime->now( time_zone => 'Europe/Berlin' );
|
||||||
my $verification_deadline = $now->clone->subtract( hours => 48 );
|
my $verification_deadline = $now->clone->subtract( hours => 48 );
|
||||||
my $deletion_deadline = $now->clone->subtract( hours => 72 );
|
my $deletion_deadline = $now->clone->subtract( hours => 72 );
|
||||||
|
my $old_deadline = $now->clone->subtract( years => 1 );
|
||||||
|
|
||||||
my $db = $self->app->pg->db;
|
my $db = $self->app->pg->db;
|
||||||
my $tx = $db->begin;
|
my $tx = $db->begin;
|
||||||
|
@ -80,6 +81,12 @@ sub run {
|
||||||
{ deletion_requested => { '<', $deletion_deadline } } );
|
{ deletion_requested => { '<', $deletion_deadline } } );
|
||||||
my @uids_to_delete = $to_delete->arrays->map( sub { shift->[0] } )->each;
|
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 ) {
|
if ( @uids_to_delete > 10 ) {
|
||||||
printf STDERR (
|
printf STDERR (
|
||||||
"About to delete %d accounts, which is quite a lot.\n",
|
"About to delete %d accounts, which is quite a lot.\n",
|
||||||
|
|
|
@ -38,6 +38,7 @@ sub do_login {
|
||||||
else {
|
else {
|
||||||
if ( $self->authenticate( $user, $password ) ) {
|
if ( $self->authenticate( $user, $password ) ) {
|
||||||
$self->redirect_to( $self->req->param('redirect_to') // '/' );
|
$self->redirect_to( $self->req->param('redirect_to') // '/' );
|
||||||
|
$self->mark_seen( $self->current_user->{id} );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
my $data = $self->get_user_password($user);
|
my $data = $self->get_user_password($user);
|
||||||
|
@ -535,6 +536,7 @@ sub account {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
|
|
||||||
$self->render('account');
|
$self->render('account');
|
||||||
|
$self->mark_seen( $self->current_user->{id} );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub json_export {
|
sub json_export {
|
||||||
|
|
|
@ -13,6 +13,7 @@ sub homepage {
|
||||||
with_autocomplete => 1,
|
with_autocomplete => 1,
|
||||||
with_geolocation => 1
|
with_geolocation => 1
|
||||||
);
|
);
|
||||||
|
$self->mark_seen( $self->current_user->{id} );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$self->render( 'landingpage', intro => 1 );
|
$self->render( 'landingpage', intro => 1 );
|
||||||
|
@ -272,6 +273,7 @@ sub station {
|
||||||
title => "travelynx: $status->{station_name}",
|
title => "travelynx: $status->{station_name}",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
$self->mark_seen( $self->current_user->{id} );
|
||||||
}
|
}
|
||||||
|
|
||||||
sub redirect_to_station {
|
sub redirect_to_station {
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
an Dritte weitergegeben. Die <a
|
an Dritte weitergegeben. Die <a
|
||||||
href="/impressum">Datenschutzerklärung</a> beschreibt weitere
|
href="/impressum">Datenschutzerklärung</a> beschreibt weitere
|
||||||
erhobene Daten sowie deren Zweck und Speicherfristen.
|
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.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Bitte beachten: Travelynx ist ein privat betriebenes Projekt ohne
|
Bitte beachten: Travelynx ist ein privat betriebenes Projekt ohne
|
||||||
|
|
Loading…
Reference in a new issue