aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Somerville <matthew-github@dracos.co.uk>2018-05-11 19:57:49 +0100
committerMatthew Somerville <matthew-github@dracos.co.uk>2018-05-23 18:55:10 +0100
commiteb58ad65f8b25be9dc4321ca5914ad1d89f8bf3a (patch)
treeff99b2e34567c149a9ecd17c800781c8e40ebb6c
parentdf731c5a0ffccc434550ca4dd2ecace5287848fa (diff)
Script to scrub old non-open reports.
-rw-r--r--CHANGELOG.md3
-rwxr-xr-xbin/process-inactive-reports40
-rw-r--r--perllib/FixMyStreet/Script/Inactive.pm57
-rw-r--r--t/script/inactive.t35
4 files changed, 134 insertions, 1 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 13d45bd5b..c5baa0408 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -54,7 +54,8 @@
- Deleted body categories now hidden by default #1962
- Display contents of report's extra field #1809
- Store user creation and last active times.
- - Add script to anonymize/email inactive users.
+ - Add scripts to anonymize inactive users and reports,
+ or email inactive users.
- Development improvements:
- Add HTML email previewer.
- Add CORS header to Open311 output. #2022
diff --git a/bin/process-inactive-reports b/bin/process-inactive-reports
new file mode 100755
index 000000000..3f133d11a
--- /dev/null
+++ b/bin/process-inactive-reports
@@ -0,0 +1,40 @@
+#!/usr/bin/env perl
+
+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 Getopt::Long;
+use FixMyStreet::Script::Inactive;
+use Pod::Usage;
+
+my %h;
+GetOptions(\%h, 'anonymize=i', 'verbose|v', 'help|h', 'dry-run|n');
+pod2usage(0) if $h{help};
+pod2usage(1) unless $h{anonymize};
+
+FixMyStreet::Script::Inactive->new(%h)->reports;
+
+__END__
+
+=head1 NAME
+
+process-inactive-reports - deal with anonymizing inactive non-open reports
+
+=head1 SYNOPSIS
+
+process-inactive-reports --anonymize N
+
+ Options:
+ --anonymize Anonymize non-open reports (and related) inactive longer than this time (months)
+ --dry-run Don't actually anonymize anything or send any emails
+ --verbose Output as to which reports are being affected
+ --help This help message
+
+=cut
diff --git a/perllib/FixMyStreet/Script/Inactive.pm b/perllib/FixMyStreet/Script/Inactive.pm
index 766135e12..3c6be9901 100644
--- a/perllib/FixMyStreet/Script/Inactive.pm
+++ b/perllib/FixMyStreet/Script/Inactive.pm
@@ -32,6 +32,15 @@ has cobrand => (
},
);
+has anonymous_user => (
+ is => 'lazy',
+ default => sub {
+ FixMyStreet::DB->resultset("User")->find_or_create({
+ email => 'removed-automatically@' . FixMyStreet->config('EMAIL_DOMAIN'),
+ });
+ }
+);
+
sub users {
my $self = shift;
@@ -40,6 +49,54 @@ sub users {
$self->email_inactive_users if $self->email;
}
+sub reports {
+ my $self = shift;
+
+ say "DRY RUN" if $self->dry_run;
+
+ # Need to look though them all each time, in case any new updates/alerts
+ my $problems = FixMyStreet::DB->resultset("Problem")->search({
+ lastupdate => { '<', interval($self->anonymize) },
+ state => [
+ FixMyStreet::DB::Result::Problem->closed_states(),
+ FixMyStreet::DB::Result::Problem->fixed_states(),
+ FixMyStreet::DB::Result::Problem->hidden_states(),
+ ],
+ });
+
+ while (my $problem = $problems->next) {
+ say "Anonymizing problem #" . $problem->id if $self->verbose;
+ next if $self->dry_run;
+
+ # Remove personal data from the report
+ $problem->update({
+ user => $self->anonymous_user,
+ name => '',
+ anonymous => 1,
+ send_questionnaire => 0,
+ }) if $problem->user != $self->anonymous_user;
+
+ # Remove personal data from the report's updates
+ $problem->comments->search({
+ user_id => { '!=' => $self->anonymous_user->id },
+ })->update({
+ user_id => $self->anonymous_user->id,
+ name => '',
+ anonymous => 1,
+ });
+
+ # Remove alerts - could just delete, but of interest how many there were, perhaps?
+ FixMyStreet::DB->resultset('Alert')->search({
+ user_id => { '!=' => $self->anonymous_user->id },
+ alert_type => 'new_updates',
+ parameter => $problem->id,
+ })->update({
+ user_id => $self->anonymous_user->id,
+ whendisabled => \'current_timestamp',
+ });
+ }
+}
+
sub anonymize_users {
my $self = shift;
diff --git a/t/script/inactive.t b/t/script/inactive.t
index 0eaeea2ad..9d1e3f4bd 100644
--- a/t/script/inactive.t
+++ b/t/script/inactive.t
@@ -15,6 +15,41 @@ $t = DateTime->now->subtract(months => 4);
$user_inactive->last_active($t);
$user_inactive->update;
+my @problems;
+for (my $m = 1; $m <= 12; $m++) {
+ my $t = DateTime->new(year => 2017, month => $m, day => 1, hour => 12);
+ push @problems, $mech->create_problems_for_body(1, 2237, 'Title', {
+ dt => $t,
+ lastupdate => "$t",
+ state => $m % 2 ? 'fixed - user' : 'confirmed',
+ });
+}
+
+$mech->create_comment_for_problem($problems[0], $user, 'Name', 'Update', 0, 'confirmed', $problems[0]->state);
+FixMyStreet::DB->resultset("Alert")->create({ alert_type => 'new_updates', parameter => $problems[2]->id, user => $user });
+
+subtest 'Anonymization of inactive fixed/closed reports' => sub {
+ $in->reports;
+
+ my $count = FixMyStreet::DB->resultset("Problem")->search({ user_id => $user->id })->count;
+ is $count, 6, 'Six non-anonymised';
+
+ my $comment = FixMyStreet::DB->resultset("Comment")->first;
+ my $alert = FixMyStreet::DB->resultset("Alert")->first;
+ is $comment->anonymous, 1, 'Comment anonymized';
+ is $comment->user->email, 'removed-automatically@example.org', 'Comment user anonymized';
+ is $alert->user->email, 'removed-automatically@example.org', 'Alert anonymized';
+ isnt $alert->whendisabled, undef, 'Alert disabled';
+
+ $mech->create_comment_for_problem($problems[0], $user, 'Name 2', 'Update', 0, 'confirmed', $problems[0]->state);
+ $comment = FixMyStreet::DB->resultset("Comment")->search({ name => 'Name 2' })->first;
+
+ $in->reports;
+ $comment->discard_changes;
+ is $comment->anonymous, 1, 'Comment anonymized';
+ is $comment->user->email, 'removed-automatically@example.org', 'Comment user anonymized';
+};
+
subtest 'Anonymization of inactive users' => sub {
$in->users;