From a211a9466a293fbc70082863656d5699aab90fed Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Wed, 16 May 2018 15:15:03 +0100 Subject: Refactor name part of form_user out. --- templates/web/base/report/new/form_user_loggedin.html | 13 +------------ .../web/base/report/new/form_user_loggedout_by_email.html | 14 +------------- templates/web/base/report/new/form_user_name.html | 10 ++++++++++ 3 files changed, 12 insertions(+), 25 deletions(-) create mode 100644 templates/web/base/report/new/form_user_name.html diff --git a/templates/web/base/report/new/form_user_loggedin.html b/templates/web/base/report/new/form_user_loggedin.html index b82be3202..7f81764be 100644 --- a/templates/web/base/report/new/form_user_loggedin.html +++ b/templates/web/base/report/new/form_user_loggedin.html @@ -45,18 +45,7 @@ [% INCLUDE 'report/new/extra_name.html' %] [% PROCESS 'user/_anonymity.html' anonymous = report.anonymous %] - - - [% IF field_errors.name %] -

[% field_errors.name %]

- [% END %] - - + [% INCLUDE 'report/new/form_user_name.html' %] [% INCLUDE 'report/_show_name_label.html' %] [% IF NOT c.user.phone_verified AND NOT c.cobrand.call_hook('disable_phone_number_entry') %] diff --git a/templates/web/base/report/new/form_user_loggedout_by_email.html b/templates/web/base/report/new/form_user_loggedout_by_email.html index 6ec0278ce..b633c4843 100644 --- a/templates/web/base/report/new/form_user_loggedout_by_email.html +++ b/templates/web/base/report/new/form_user_loggedout_by_email.html @@ -7,19 +7,7 @@ [% INCLUDE 'report/new/extra_name.html' %] [% PROCESS 'user/_anonymity.html' anonymous = report.anonymous %] - - - [% IF field_errors.name %] -

[% field_errors.name %]

- [% END %] - - - + [% INCLUDE 'report/new/form_user_name.html' extra_class='form-focus-trigger' %] [% INCLUDE 'report/_show_name_label.html' %] [% UNLESS c.cobrand.call_hook('disable_phone_number_entry') %] diff --git a/templates/web/base/report/new/form_user_name.html b/templates/web/base/report/new/form_user_name.html new file mode 100644 index 000000000..1f745eadb --- /dev/null +++ b/templates/web/base/report/new/form_user_name.html @@ -0,0 +1,10 @@ + +[% IF field_errors.name %] +

[% field_errors.name %]

+[% END %] + -- cgit v1.2.3 From f5eb9577828d4ebdb060a5bbff0b72ca7da03868 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Wed, 16 May 2018 15:07:01 +0100 Subject: [Bromley] Refactor templates into separate files. --- templates/web/bromley/report/new/form_user.html | 132 ++---------------- .../bromley/report/new/form_user_loggedout.html | 7 + .../report/new/form_user_loggedout_by_email.html | 37 ++++++ .../report/new/form_user_loggedout_password.html | 18 +++ .../web/bromley/report/new/form_user_name.html | 12 ++ templates/web/bromley/report/update-form.html | 147 +++------------------ .../web/bromley/report/update/form_update.html | 54 ++++++++ .../bromley/report/update/form_user_loggedout.html | 7 + .../update/form_user_loggedout_by_email.html | 23 ++++ .../report/update/form_user_loggedout_email.html | 8 ++ .../update/form_user_loggedout_password.html | 18 +++ 11 files changed, 214 insertions(+), 249 deletions(-) create mode 100644 templates/web/bromley/report/new/form_user_loggedout.html create mode 100644 templates/web/bromley/report/new/form_user_loggedout_by_email.html create mode 100644 templates/web/bromley/report/new/form_user_loggedout_password.html create mode 100644 templates/web/bromley/report/new/form_user_name.html create mode 100644 templates/web/bromley/report/update/form_update.html create mode 100644 templates/web/bromley/report/update/form_user_loggedout.html create mode 100644 templates/web/bromley/report/update/form_user_loggedout_by_email.html create mode 100644 templates/web/bromley/report/update/form_user_loggedout_email.html create mode 100644 templates/web/bromley/report/update/form_user_loggedout_password.html diff --git a/templates/web/bromley/report/new/form_user.html b/templates/web/bromley/report/new/form_user.html index cce985c95..20f522dcd 100644 --- a/templates/web/bromley/report/new/form_user.html +++ b/templates/web/bromley/report/new/form_user.html @@ -5,130 +5,18 @@ title, first name, and last name separately. %] -

Private details

-

- [% tprintf( - loc('These will be sent to the council, but will never be shown online. (See our privacy policy.)') - '/faq#privacy' - ); %] +

[% loc('Private details') %]

+

+ [% IF js %] + [% loc('These will be sent to the council, but will never be shown online.') %] + ([% loc('See our privacy policy') %].) + [% ELSE %] + [% PROCESS 'report/new/councils_text_private.html' %] + [% END %]

[% IF c.user_exists %] -
- [% INCLUDE 'report/new/extra_name.html' %] - - [% names = c.user.split_name %] - - [% IF field_errors.first_name %] -

[% field_errors.first_name %]

- [% END %] - - - - [% IF field_errors.last_name %] -

[% field_errors.last_name %]

- [% END %] - - - - [%# if there is nothing in the name field then set check box as default on form %] -
- - -
- - - - -
-

[% loc('We never show your email address or phone number.') %]

-
- -
- -
-
+ [% PROCESS "report/new/form_user_loggedin.html" %] [% ELSE %] - - - [% IF field_errors.username %] -

[% field_errors.username %]

- [% END %] - - -
- -

To submit your report you now need to confirm it either by email or by using a FixMyStreet password.

- -
-
Confirm my report by email
- - [% INCLUDE 'report/new/extra_name.html' %] - - - [% IF field_errors.first_name %] -

[% field_errors.first_name %]

- [% END %] - - - - [% IF field_errors.last_name %] -

[% field_errors.last_name %]

- [% END %] - - - [%# if there is nothing in the name field then set check box as default on form %] -
- - -
- - - - -
-

[% loc('We never show your email address or phone number.') %]

-
- - - [% IF field_errors.password_register %] -

[% field_errors.password_register %]

- [% END %] - -
-

[% loc('Providing a password is optional, but doing so will allow you to more easily report future problems, leave updates and manage your reports.') %]

-
- -
- - -
- -
-

[% tprintf(loc('Your password should include %d or more characters.'), c.cobrand.password_minimum_length) %]

-
- -
- -
- -
Confirm my report with my FixMyStreet password
- - -
- [% IF field_errors.password %] -

[% field_errors.password %]

- [% END %] - - -
- -
- - -
-
- -
- + [% PROCESS "report/new/form_user_loggedout.html" %] [% END %] diff --git a/templates/web/bromley/report/new/form_user_loggedout.html b/templates/web/bromley/report/new/form_user_loggedout.html new file mode 100644 index 000000000..8d46e7b60 --- /dev/null +++ b/templates/web/bromley/report/new/form_user_loggedout.html @@ -0,0 +1,7 @@ +[% PROCESS 'report/new/form_user_loggedout_email.html' required = 1 %] + +
+

To submit your report you now need to confirm it either by email or by using a FixMyStreet password.

+ [% PROCESS 'report/new/form_user_loggedout_by_email.html' %] + [% PROCESS 'report/new/form_user_loggedout_password.html' %] +
diff --git a/templates/web/bromley/report/new/form_user_loggedout_by_email.html b/templates/web/bromley/report/new/form_user_loggedout_by_email.html new file mode 100644 index 000000000..aea672483 --- /dev/null +++ b/templates/web/bromley/report/new/form_user_loggedout_by_email.html @@ -0,0 +1,37 @@ +
+
Confirm my report by email
+ + [% INCLUDE 'report/new/extra_name.html' %] + [% PROCESS 'user/_anonymity.html' anonymous = report.anonymous %] + [% INCLUDE 'report/new/form_user_name.html' extra_class='form-focus-trigger' %] + [% INCLUDE 'report/_show_name_label.html' %] + + [% UNLESS c.cobrand.call_hook('disable_phone_number_entry') %] +
+ + +
+ [% END %] +
+ + +
+ + + [% IF field_errors.password_register %] +

[% field_errors.password_register %]

+ [% END %] +
+

[% loc('Providing a password is optional, but doing so will allow you to more easily report future problems, leave updates and manage your reports.') %]

+
+ +
+ + +
+ +
+

[% tprintf(loc('Your password should include %d or more characters.'), c.cobrand.password_minimum_length) %]

+
+ +
diff --git a/templates/web/bromley/report/new/form_user_loggedout_password.html b/templates/web/bromley/report/new/form_user_loggedout_password.html new file mode 100644 index 000000000..a4255f647 --- /dev/null +++ b/templates/web/bromley/report/new/form_user_loggedout_password.html @@ -0,0 +1,18 @@ +
+ +
Confirm my report with my FixMyStreet password
+ + + [% IF field_errors.password %] +

[% field_errors.password %]

+ [% END %] +
+ + +
+ +
+ + +
+
diff --git a/templates/web/bromley/report/new/form_user_name.html b/templates/web/bromley/report/new/form_user_name.html new file mode 100644 index 000000000..8102c0ea7 --- /dev/null +++ b/templates/web/bromley/report/new/form_user_name.html @@ -0,0 +1,12 @@ +[% names = c.user.split_name %] + +[% IF field_errors.first_name %] +

[% field_errors.first_name %]

+[% END %] + + + +[% IF field_errors.last_name %] +

[% field_errors.last_name %]

+[% END %] + diff --git a/templates/web/bromley/report/update-form.html b/templates/web/bromley/report/update-form.html index 9778a0db3..bdabe12c5 100644 --- a/templates/web/bromley/report/update-form.html +++ b/templates/web/bromley/report/update-form.html @@ -5,140 +5,33 @@ [% INCLUDE 'errors.html' %] -
+
- - - - [% IF c.cobrand.allow_photo_upload %] - - - - [% IF field_errors.photo %] -

[% field_errors.photo %]

- [% END %] - -
- [% IF upload_fileid %] -

[% loc('You have already attached photos to this update. Note that you can attach a maximum of 3 to this update (if you try to upload more, the oldest will be removed).') %]

- [% FOREACH id IN upload_fileid.split(',') %] - - [% END %] - [% END %] - - - - - -
- [% END %] - -
-

Please note that new and separate occurrences of issues - should be logged as new reports, to avoid conflicting - information or updates and ensure the information is passed - promptly to our teams. Please log any new issue via - https://www.bromley.gov.uk/report - using the map marker and description to detail where the issue - is located.

-
- - - [% IF field_errors.update %] -
[% field_errors.update %]
- [% END %] - - - [% IF c.user && c.user.belongs_to_body( problem.bodies_str ) %] - - [% INCLUDE 'report/inspect/state_groups_select.html' %] - [% ELSE %] - [% IF problem.is_fixed AND c.user_exists AND c.user.id == problem.user_id %] - - - - - [% ELSIF !problem.is_fixed %] - -
- - -
- - [% END %] - [% END %] - - [% IF c.user_exists %] - + [% IF NOT login_success AND NOT oauth_need_email %] + [% INCLUDE 'report/update/form_update.html' %] + [% END %] + [% IF c.user_exists %] [% INCLUDE 'report/update/form_name.html' %] - - - - - [% ELSE %] - - - - [% IF field_errors.username %] -

[% field_errors.username %]

- [% END %] - - +
+ [% ELSIF oauth_need_email %] + [% INCLUDE 'report/update/form_user_loggedout_email.html' required = 1 %]
-

To submit your update you now need to confirm it either by email or by using a FixMyStreet password.

- -
-
Confirm my report by email
- - [% INCLUDE 'report/update/form_name.html' %] - - - [% IF field_errors.password_register %] -

[% field_errors.password_register %]

- [% END %] - -
-

[% loc('Providing a password is optional, but doing so will allow you to more easily report problems, leave updates and manage your reports.') %]

-
- -
- - -
- -
-

[% tprintf(loc('Your password should include %d or more characters.'), c.cobrand.password_minimum_length) %]

-
- -
-
-
Confirm my report with my FixMyStreet password
- - - [% IF field_errors.password %] -

[% field_errors.password %]

- [% END %] -
- - -
- -
- - -
-
+

[% loc("Now to submit your update…") %]

+

[% tprintf(loc("Do you have a %s password?", "%s is the site name"), site_name) %]

+ [% INCLUDE 'report/update/form_user_loggedout_by_email.html' %] + [% INCLUDE 'report/update/form_user_loggedout_password.html' %] +
+ [% ELSE %] + [% INCLUDE 'report/update/form_user_loggedout.html' %] + [% END %] - [% END %] - -

Your information will only be used in accordance with our privacy policy.

+

Your information will only be used in accordance with our privacy policy.

+ [% IF login_success OR oauth_need_email %] + [% INCLUDE 'report/update/form_update.html' %] + [% END %]
diff --git a/templates/web/bromley/report/update/form_update.html b/templates/web/bromley/report/update/form_update.html new file mode 100644 index 000000000..06d7c455e --- /dev/null +++ b/templates/web/bromley/report/update/form_update.html @@ -0,0 +1,54 @@ + + + +[% IF c.cobrand.allow_photo_upload %] + + + + [% IF field_errors.photo %] +

[% field_errors.photo %]

+ [% END %] + +
+ [% IF upload_fileid %] +

[% loc('You have already attached photos to this update. Note that you can attach a maximum of 3 to this update (if you try to upload more, the oldest will be removed).') %]

+ [% FOREACH id IN upload_fileid.split(',') %] + + [% END %] + [% END %] + + + + + +
+[% END %] + +
+

Please note that new and separate occurrences of issues + should be logged as new reports, to avoid conflicting + information or updates and ensure the information is passed + promptly to our teams. Please log any new issue via + https://www.bromley.gov.uk/report + using the map marker and description to detail where the issue + is located.

+
+ + +[% IF c.user && c.user.belongs_to_body( problem.bodies_str ) %] + [% INCLUDE 'admin/response_templates_select.html' for='form_update' %] +[% END %] +[% IF field_errors.update %] +
[% field_errors.update %]
+[% END %] + + +[% IF c.user && c.user.belongs_to_body( problem.bodies_str ) %] + + [% INCLUDE 'report/inspect/state_groups_select.html' %] +[% ELSE %] + [% INCLUDE report/update/form_state_checkbox.html %] +[% END %] + diff --git a/templates/web/bromley/report/update/form_user_loggedout.html b/templates/web/bromley/report/update/form_user_loggedout.html new file mode 100644 index 000000000..f19238934 --- /dev/null +++ b/templates/web/bromley/report/update/form_user_loggedout.html @@ -0,0 +1,7 @@ +[% INCLUDE 'report/update/form_user_loggedout_email.html' required=1 %] + +
+

To submit your update you now need to confirm it either by email or by using a FixMyStreet password.

+ [% INCLUDE 'report/update/form_user_loggedout_by_email.html' %] + [% INCLUDE 'report/update/form_user_loggedout_password.html' %] +
diff --git a/templates/web/bromley/report/update/form_user_loggedout_by_email.html b/templates/web/bromley/report/update/form_user_loggedout_by_email.html new file mode 100644 index 000000000..393d8e4cc --- /dev/null +++ b/templates/web/bromley/report/update/form_user_loggedout_by_email.html @@ -0,0 +1,23 @@ +
+
Confirm my report by email
+ + [% INCLUDE 'report/update/form_name.html' %] + + + [% IF field_errors.password_register %] +

[% field_errors.password_register %]

+ [% END %] +
+

[% loc('Providing a password is optional, but doing so will allow you to more easily report future problems, leave updates and manage your reports.') %]

+
+ +
+ + +
+ +
+

[% tprintf(loc('Your password should include %d or more characters.'), c.cobrand.password_minimum_length) %]

+
+ +
diff --git a/templates/web/bromley/report/update/form_user_loggedout_email.html b/templates/web/bromley/report/update/form_user_loggedout_email.html new file mode 100644 index 000000000..228ca7509 --- /dev/null +++ b/templates/web/bromley/report/update/form_user_loggedout_email.html @@ -0,0 +1,8 @@ + + +[% IF field_errors.username %] +

[% field_errors.username %]

+[% END %] + diff --git a/templates/web/bromley/report/update/form_user_loggedout_password.html b/templates/web/bromley/report/update/form_user_loggedout_password.html new file mode 100644 index 000000000..3b7adb84e --- /dev/null +++ b/templates/web/bromley/report/update/form_user_loggedout_password.html @@ -0,0 +1,18 @@ +
+ +
Confirm my report with my FixMyStreet password
+ + + [% IF field_errors.password %] +

[% field_errors.password %]

+ [% END %] +
+ + +
+ +
+ + +
+
-- cgit v1.2.3 From a82cbf8c4709c4c04c8a1625946132bac8f4e74e Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Mon, 14 May 2018 15:25:46 +0100 Subject: [FixaMinGata] Add to CronFns list. This is so e.g. inactive accounts script will use the cobranded emails. --- perllib/CronFns.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/perllib/CronFns.pm b/perllib/CronFns.pm index eb54d7627..76295d2c8 100755 --- a/perllib/CronFns.pm +++ b/perllib/CronFns.pm @@ -26,6 +26,7 @@ sub options { sub site { my $base_url = shift; my $site = 'fixmystreet'; + $site = 'fixamingata' if $base_url =~ /fixamingata/; $site = 'zurich' if $base_url =~ /zurich|zueri/; $site = 'smidsy' if $base_url =~ /smidsy|collideosco/; $site = 'kiitc' if $base_url =~ /kiitc|acv|keepitinthecommunity/; -- cgit v1.2.3 From a3c182e75b022b3002eb4801fd446c891391b675 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Fri, 11 May 2018 15:40:26 +0100 Subject: Add created and last_active columns to user. --- bin/update-schema | 1 + db/downgrade_0062---0061.sql | 6 ++++++ db/schema.sql | 2 ++ db/schema_0062-add-user-created-last-active.sql | 7 +++++++ perllib/FixMyStreet/DB/Result/User.pm | 26 +++++++++++++++++++------ 5 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 db/downgrade_0062---0061.sql create mode 100644 db/schema_0062-add-user-created-last-active.sql diff --git a/bin/update-schema b/bin/update-schema index fb88c84a1..2ae374e61 100755 --- a/bin/update-schema +++ b/bin/update-schema @@ -212,6 +212,7 @@ else { # (assuming schema change files are never half-applied, which should be the case) sub get_db_version { return 'EMPTY' if ! table_exists('problem'); + return '0062' if column_exists('users', 'created'); return '0061' if column_exists('body', 'extra'); return '0060' if column_exists('body', 'convert_latlong'); return '0059' if column_exists('response_templates', 'external_status_code'); diff --git a/db/downgrade_0062---0061.sql b/db/downgrade_0062---0061.sql new file mode 100644 index 000000000..fa958169a --- /dev/null +++ b/db/downgrade_0062---0061.sql @@ -0,0 +1,6 @@ +BEGIN; + +ALTER TABLE users DROP created; +ALTER TABLE users DROP last_active; + +COMMIT; diff --git a/db/schema.sql b/db/schema.sql index fa0bd07bd..30f5d3a30 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -30,6 +30,8 @@ create table users ( from_body integer, flagged boolean not null default 'f', is_superuser boolean not null default 'f', + created timestamp not null default current_timestamp, + last_active timestamp not null default current_timestamp, title text, twitter_id bigint unique, facebook_id bigint unique, diff --git a/db/schema_0062-add-user-created-last-active.sql b/db/schema_0062-add-user-created-last-active.sql new file mode 100644 index 000000000..0e8875870 --- /dev/null +++ b/db/schema_0062-add-user-created-last-active.sql @@ -0,0 +1,7 @@ +BEGIN; + +ALTER TABLE users ADD created timestamp default current_timestamp not null; +ALTER TABLE users ADD last_active timestamp default current_timestamp not null; + +COMMIT; + diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index db68236bf..c624a2efe 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -20,10 +20,14 @@ __PACKAGE__->add_columns( }, "email", { data_type => "text", is_nullable => 1 }, + "email_verified", + { data_type => "boolean", default_value => \"false", is_nullable => 0 }, "name", { data_type => "text", is_nullable => 1 }, "phone", { data_type => "text", is_nullable => 1 }, + "phone_verified", + { data_type => "boolean", default_value => \"false", is_nullable => 0 }, "password", { data_type => "text", default_value => "", is_nullable => 0 }, "from_body", @@ -42,10 +46,20 @@ __PACKAGE__->add_columns( { data_type => "integer", is_nullable => 1 }, "extra", { data_type => "text", is_nullable => 1 }, - "email_verified", - { data_type => "boolean", default_value => \"false", is_nullable => 0 }, - "phone_verified", - { data_type => "boolean", default_value => \"false", is_nullable => 0 }, + "created", + { + data_type => "timestamp", + default_value => \"current_timestamp", + is_nullable => 0, + original => { default_value => \"now()" }, + }, + "last_active", + { + data_type => "timestamp", + default_value => \"current_timestamp", + is_nullable => 0, + original => { default_value => \"now()" }, + }, ); __PACKAGE__->set_primary_key("id"); __PACKAGE__->add_unique_constraint("users_facebook_id_key", ["facebook_id"]); @@ -105,8 +119,8 @@ __PACKAGE__->has_many( ); -# Created by DBIx::Class::Schema::Loader v0.07035 @ 2017-09-19 18:02:17 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:OKHKCSahWD3Ov6ulj+2f/w +# Created by DBIx::Class::Schema::Loader v0.07035 @ 2018-05-23 18:54:36 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/V7+Ygv/t6VX8dDhNGN16w # These are not fully unique constraints (they only are when the *_verified # is true), but this is managed in ResultSet::User's find() wrapper. -- cgit v1.2.3 From 110a80eff22e852974bc5a6f90295803ef7e0de6 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Fri, 11 May 2018 15:40:56 +0100 Subject: Factor anonymize function to User model. --- perllib/FixMyStreet/App/Controller/Admin.pm | 15 +-------------- perllib/FixMyStreet/DB/Result/User.pm | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 8f8d7cc47..0d897e71e 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -1911,20 +1911,7 @@ sub user_hide_everywhere : Private { sub user_remove_account : Private { my ( $self, $c, $user ) = @_; $c->forward('user_logout_everywhere', [ $user ]); - $user->problems->update({ anonymous => 1, name => '', send_questionnaire => 0 }); - $user->comments->update({ anonymous => 1, name => '' }); - $user->alerts->update({ whendisabled => \'current_timestamp' }); - $user->password('', 1); - $user->update({ - email => 'removed-' . $user->id . '@' . FixMyStreet->config('EMAIL_DOMAIN'), - email_verified => 0, - name => '', - phone => '', - phone_verified => 0, - title => undef, - twitter_id => undef, - facebook_id => undef, - }); + $user->anonymize_account; $c->stash->{status_message} = _('That user’s personal details have been removed.'); } diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index c624a2efe..3ec6ae92c 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -456,6 +456,25 @@ sub adopt { $other->delete; } +sub anonymize_account { + my $self = shift; + + $self->problems->update({ anonymous => 1, name => '', send_questionnaire => 0 }); + $self->comments->update({ anonymous => 1, name => '' }); + $self->alerts->update({ whendisabled => \'current_timestamp' }); + $self->password('', 1); + $self->update({ + email => 'removed-' . $self->id . '@' . FixMyStreet->config('EMAIL_DOMAIN'), + email_verified => 0, + name => '', + phone => '', + phone_verified => 0, + title => undef, + twitter_id => undef, + facebook_id => undef, + }); +} + # Planned reports / shortlist # Override the default auto-created function as we only want one live entry so -- cgit v1.2.3 From 910b1b8fef7e19b102459c97fc700a117d7a12aa Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Mon, 14 May 2018 11:53:40 +0100 Subject: Refactor out some session functions. --- bin/expire-sessions | 27 ++++----------------------- perllib/FixMyStreet/DB/Result/Session.pm | 21 ++++++++++++++++++++- t/app/model/session.t | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 24 deletions(-) create mode 100644 t/app/model/session.t diff --git a/bin/expire-sessions b/bin/expire-sessions index 8cfdd57e3..2ec0a09da 100755 --- a/bin/expire-sessions +++ b/bin/expire-sessions @@ -17,8 +17,6 @@ BEGIN { use FixMyStreet::DB; use Getopt::Long; use List::Util qw(uniq); -use MIME::Base64; -use Storable; GetOptions( 'init' => \my $init, @@ -28,8 +26,8 @@ my $rs = FixMyStreet::DB->resultset("Session"); # Delete expired sessions (including from in User object) while (my $session = $rs->search({ expires => { '<', time() } })->next) { - if (my $user = get_user($session)) { - my $id = get_id($session); + if (my $user = $session->user) { + my $id = $session->id_code; my $sessions = $user->get_extra_metadata('sessions'); my @new_sessions = grep { $_ ne $id } @$sessions; update_user_sessions($user, \@new_sessions) if @new_sessions != @$sessions; @@ -41,8 +39,8 @@ if ($init) { # Update sessions to make sure all present in User objects print "Setting up sessions in user objects\n"; while (my $session = $rs->next) { - my $user = get_user($session) or next; - my $id = get_id($session); + my $user = $session->user or next; + my $id = $session->id_code; my $sessions = $user->get_extra_metadata('sessions'); my @new_sessions = uniq @$sessions, $id; update_user_sessions($user, \@new_sessions) if @new_sessions != @$sessions; @@ -51,23 +49,6 @@ if ($init) { # --- -sub get_user { - my $session = shift; - return unless $session->session_data; - my $data = Storable::thaw(MIME::Base64::decode($session->session_data)); - return unless $data->{__user}; - my $user = FixMyStreet::DB->resultset("User")->find($data->{__user}{id}); - return $user; -} - -sub get_id { - my $session = shift; - my $id = $session->id; - $id =~ s/^session://; - $id =~ s/\s+$//; - return $id; -} - sub update_user_sessions { my ($user, $sessions) = @_; if (@$sessions) { diff --git a/perllib/FixMyStreet/DB/Result/Session.pm b/perllib/FixMyStreet/DB/Result/Session.pm index 4713c99eb..a478c5444 100644 --- a/perllib/FixMyStreet/DB/Result/Session.pm +++ b/perllib/FixMyStreet/DB/Result/Session.pm @@ -24,5 +24,24 @@ __PACKAGE__->set_primary_key("id"); # Created by DBIx::Class::Schema::Loader v0.07017 @ 2012-03-08 17:19:55 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:MVmCn4gLQWXTDIIaDHiVmA -# You can replace this text with custom code or comments, and it will be preserved on regeneration +use Storable; +use MIME::Base64; + +sub id_code { + my $self = shift; + my $id = $self->id; + $id =~ s/^session://; + $id =~ s/\s+$//; + return $id; +} + +sub user { + my $self = shift; + return unless $self->session_data; + my $data = Storable::thaw(MIME::Base64::decode($self->session_data)); + return unless $data->{__user}; + my $user = $self->result_source->schema->resultset("User")->find($data->{__user}{id}); + return $user; +} + 1; diff --git a/t/app/model/session.t b/t/app/model/session.t new file mode 100644 index 000000000..f76533727 --- /dev/null +++ b/t/app/model/session.t @@ -0,0 +1,14 @@ +use FixMyStreet::TestMech; + +my $mech = FixMyStreet::TestMech->new; + +$mech->log_in_ok('test@example.com'); + +my $session = FixMyStreet::DB->resultset("Session")->first; + +my $id = $session->id; +$id =~ s/\s+$//; +is $id, "session:" . $session->id_code; +is $session->user->email, 'test@example.com'; + +done_testing; -- cgit v1.2.3 From 4264a9aac285fc31b354a74805c5bff72b517fb7 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Mon, 14 May 2018 12:38:36 +0100 Subject: Update last_active on login/logout/session expiry. --- CHANGELOG.md | 1 + bin/expire-sessions | 17 +++++++++++++++-- .../Plugin/FixMyStreet/Session/StoreSessions.pm | 2 ++ perllib/FixMyStreet/DB/Result/User.pm | 7 +++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b54031a4..104ad1c3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ - Nicer Open311 errors. #2078 - Deleted body categories now hidden by default #1962 - Display contents of report's extra field #1809 + - Store user creation and last active times. - Development improvements: - Add HTML email previewer. - Add CORS header to Open311 output. #2022 diff --git a/bin/expire-sessions b/bin/expire-sessions index 2ec0a09da..351c4a483 100755 --- a/bin/expire-sessions +++ b/bin/expire-sessions @@ -26,13 +26,19 @@ my $rs = FixMyStreet::DB->resultset("Session"); # Delete expired sessions (including from in User object) while (my $session = $rs->search({ expires => { '<', time() } })->next) { - if (my $user = $session->user) { + my $user = $session->user; + my $expires = $session->expires; + if ($user) { my $id = $session->id_code; 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; + if ($user) { + update_user_last_active($user, $expires); + $user->update; + } } if ($init) { @@ -44,11 +50,19 @@ if ($init) { my $sessions = $user->get_extra_metadata('sessions'); my @new_sessions = uniq @$sessions, $id; update_user_sessions($user, \@new_sessions) if @new_sessions != @$sessions; + $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) { @@ -56,5 +70,4 @@ sub update_user_sessions { } else { $user->unset_extra_metadata('sessions'); } - $user->update; } diff --git a/perllib/Catalyst/Plugin/FixMyStreet/Session/StoreSessions.pm b/perllib/Catalyst/Plugin/FixMyStreet/Session/StoreSessions.pm index 5e7a3cede..30149fc2b 100644 --- a/perllib/Catalyst/Plugin/FixMyStreet/Session/StoreSessions.pm +++ b/perllib/Catalyst/Plugin/FixMyStreet/Session/StoreSessions.pm @@ -7,6 +7,7 @@ after set_authenticated => sub { my $sessions = $c->user->get_extra_metadata('sessions'); push @$sessions, $c->sessionid; $c->user->set_extra_metadata('sessions', $sessions); + $c->user->set_last_active; $c->user->update; }; @@ -16,6 +17,7 @@ before logout => sub { my $sessions = $user->get_extra_metadata('sessions'); $sessions = [ grep { $_ ne $c->sessionid } @$sessions ]; @$sessions ? $user->set_extra_metadata('sessions', $sessions) : $user->unset_extra_metadata('sessions'); + $user->set_last_active; $user->update; } }; diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index 3ec6ae92c..8b539f85d 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -544,4 +544,11 @@ has categories => ( }, ); +sub set_last_active { + my $self = shift; + my $time = shift; + $self->unset_extra_metadata('inactive_email_sent'); + $self->last_active($time or \'current_timestamp'); +} + 1; -- cgit v1.2.3 From e663d5e373dfafedd4be7e6e79ac79eae511b54d Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Mon, 14 May 2018 12:43:09 +0100 Subject: Update last_active on active sessions too. --- bin/expire-sessions | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/bin/expire-sessions b/bin/expire-sessions index 351c4a483..375ba4c6f 100755 --- a/bin/expire-sessions +++ b/bin/expire-sessions @@ -1,11 +1,11 @@ #!/usr/bin/env perl # expire-sessions: Run regularly to remove old sessions (plus -# can set up data for 'log user out' admin functionality). +# can set up data for 'log user out' admin functionality, and +# inactive user processing). -use strict; +use v5.14; use warnings; -require 5.8.0; BEGIN { use File::Basename qw(dirname); @@ -19,41 +19,37 @@ 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) -while (my $session = $rs->search({ expires => { '<', time() } })->next) { +# 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 ($user) { - my $id = $session->id_code; + 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 = grep { $_ ne $id } @$sessions; + my @new_sessions = uniq @$sessions, $id; update_user_sessions($user, \@new_sessions) if @new_sessions != @$sessions; } - $session->delete; if ($user) { update_user_last_active($user, $expires); $user->update; } } -if ($init) { - # Update sessions to make sure all present in User objects - print "Setting up sessions in user objects\n"; - while (my $session = $rs->next) { - my $user = $session->user or next; - my $id = $session->id_code; - my $sessions = $user->get_extra_metadata('sessions'); - my @new_sessions = uniq @$sessions, $id; - update_user_sessions($user, \@new_sessions) if @new_sessions != @$sessions; - $user->update; - } -} - # --- sub update_user_last_active { -- cgit v1.2.3 From df731c5a0ffccc434550ca4dd2ecace5287848fa Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Mon, 14 May 2018 15:25:20 +0100 Subject: Script to email/anonymize inactive users. --- CHANGELOG.md | 1 + bin/process-inactive-accounts | 43 +++++++++++++ perllib/FixMyStreet/Script/Inactive.pm | 93 +++++++++++++++++++++++++++ t/script/inactive.t | 28 ++++++++ templates/email/default/inactive-account.html | 26 ++++++++ templates/email/default/inactive-account.txt | 18 ++++++ 6 files changed, 209 insertions(+) create mode 100755 bin/process-inactive-accounts create mode 100644 perllib/FixMyStreet/Script/Inactive.pm create mode 100644 t/script/inactive.t create mode 100644 templates/email/default/inactive-account.html create mode 100644 templates/email/default/inactive-account.txt diff --git a/CHANGELOG.md b/CHANGELOG.md index 104ad1c3c..13d45bd5b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ - 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. - Development improvements: - Add HTML email previewer. - Add CORS header to Open311 output. #2022 diff --git a/bin/process-inactive-accounts b/bin/process-inactive-accounts new file mode 100755 index 000000000..3df200d3d --- /dev/null +++ b/bin/process-inactive-accounts @@ -0,0 +1,43 @@ +#!/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', 'email=i', 'verbose|v', 'help|h', 'dry-run|n'); +pod2usage(0) if $h{help}; +pod2usage(1) if !$h{anonymize}; +pod2usage("Anonymize time must be greater than email time") + if $h{email} && $h{email} >= $h{anonymize}; + +FixMyStreet::Script::Inactive->new(%h)->users; + +__END__ + +=head1 NAME + +process-inactive-accounts - deal with anonymizing old inactive accounts + +=head1 SYNOPSIS + +process-inactive-accounts --anonymize N [--email N] + + Options: + --anonymize Anonymize accounts inactive longer than this time (months) + --email Email accounts inactive longer than this time (months) + --dry-run Don't actually anonymize anything or send any emails + --verbose Output as to which users are being affected + --help This help message + +=cut diff --git a/perllib/FixMyStreet/Script/Inactive.pm b/perllib/FixMyStreet/Script/Inactive.pm new file mode 100644 index 000000000..766135e12 --- /dev/null +++ b/perllib/FixMyStreet/Script/Inactive.pm @@ -0,0 +1,93 @@ +package FixMyStreet::Script::Inactive; + +use v5.14; +use warnings; + +use Moo; +use CronFns; +use FixMyStreet; +use FixMyStreet::Cobrand; +use FixMyStreet::DB; +use FixMyStreet::Email; + +has anonymize => ( is => 'ro' ); +has email => ( is => 'ro' ); +has verbose => ( is => 'ro' ); +has dry_run => ( is => 'ro' ); + +sub BUILDARGS { + my ($cls, %args) = @_; + $args{dry_run} = delete $args{'dry-run'}; + return \%args; +} + +has cobrand => ( + is => 'lazy', + default => sub { + my $base_url = FixMyStreet->config('BASE_URL'); + my $site = CronFns::site($base_url); + my $cobrand = FixMyStreet::Cobrand->get_class_for_moniker($site)->new; + $cobrand->set_lang_and_domain(undef, 1); + $cobrand; + }, +); + +sub users { + my $self = shift; + + say "DRY RUN" if $self->dry_run; + $self->anonymize_users; + $self->email_inactive_users if $self->email; +} + +sub anonymize_users { + my $self = shift; + + my $users = FixMyStreet::DB->resultset("User")->search({ + last_active => { '<', interval($self->anonymize) }, + }); + + while (my $user = $users->next) { + say "Anonymizing user #" . $user->id if $self->verbose; + next if $self->dry_run; + $user->anonymize_account; + } +} + +sub email_inactive_users { + my $self = shift; + + my $users = FixMyStreet::DB->resultset("User")->search({ + last_active => [ -and => { '<', interval($self->email) }, + { '>=', interval($self->anonymize) } ], + }); + while (my $user = $users->next) { + next if $user->get_extra_metadata('inactive_email_sent'); + + say "Emailing user #" . $user->id if $self->verbose; + next if $self->dry_run; + FixMyStreet::Email::send_cron( + $user->result_source->schema, + 'inactive-account.txt', + { + email_from => $self->email, + anonymize_from => $self->anonymize, + user => $user, + url => $self->cobrand->base_url_with_lang . '/my', + }, + { To => [ $user->email, $user->name ] }, + undef, 0, $self->cobrand, + ); + + $user->set_extra_metadata('inactive_email_sent', 1); + $user->update; + } +} + +sub interval { + my $interval = shift; + my $s = "current_timestamp - '$interval months'::interval"; + return \$s; +} + +1; diff --git a/t/script/inactive.t b/t/script/inactive.t new file mode 100644 index 000000000..0eaeea2ad --- /dev/null +++ b/t/script/inactive.t @@ -0,0 +1,28 @@ +use FixMyStreet::TestMech; + +use_ok 'FixMyStreet::Script::Inactive'; + +my $in = FixMyStreet::Script::Inactive->new( anonymize => 6, email => 3 ); +my $mech = FixMyStreet::TestMech->new; + +my $user = FixMyStreet::DB->resultset("User")->find_or_create({ email => 'test@example.com' }); +my $t = DateTime->new(year => 2016, month => 1, day => 1, hour => 12); +$user->last_active($t); +$user->update; + +my $user_inactive = FixMyStreet::DB->resultset("User")->find_or_create({ email => 'inactive@example.com' }); +$t = DateTime->now->subtract(months => 4); +$user_inactive->last_active($t); +$user_inactive->update; + +subtest 'Anonymization of inactive users' => sub { + $in->users; + + my $email = $mech->get_email; + like $email->as_string, qr/inactive\@example.com/, 'Inactive email sent'; + + $user->discard_changes; + is $user->email, 'removed-' . $user->id . '@example.org', 'User has been anonymized'; +}; + +done_testing; diff --git a/templates/email/default/inactive-account.html b/templates/email/default/inactive-account.html new file mode 100644 index 000000000..78b277877 --- /dev/null +++ b/templates/email/default/inactive-account.html @@ -0,0 +1,26 @@ +[% + +email_summary = "Your inactive account on " _ site_name; +email_columns = 1; + +PROCESS '_email_settings.html'; + +INCLUDE '_email_top.html'; + +%] + + +

Your inactive account

+

+Your account on [% site_name %] has been inactive for [% email_from %] +[% nget('month', 'months', email_from) %], and we automatically remove +accounts that have been inactive after [% anonymize_from %] +[% nget('month', 'months', anonymize_from) %]. If you wish to keep your +account, please log in to the site and that will keep it active: +

+

+ Visit [% site_name %] +

+

Thanks for using the site.

+ +[% INCLUDE '_email_bottom.html' %] diff --git a/templates/email/default/inactive-account.txt b/templates/email/default/inactive-account.txt new file mode 100644 index 000000000..1b6b8b5bd --- /dev/null +++ b/templates/email/default/inactive-account.txt @@ -0,0 +1,18 @@ +Subject: Your inactive account on [% site_name %] + +Hello [% user.name %], + +Your account on [% site_name %] has been inactive for [% email_from %] +[% nget('month', 'months', email_from) %], and we automatically remove +accounts that have been inactive after [% anonymize_from %] +[% nget('month', 'months', anonymize_from) %]. If you wish to keep your +account, please log in to the site and that will keep it active: + +[% url %] + +Thanks for using the site. + +[% INCLUDE 'signature.txt' %] + +This email was sent automatically, from an unmonitored email account - so +please do not reply to it. -- cgit v1.2.3 From eb58ad65f8b25be9dc4321ca5914ad1d89f8bf3a Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Fri, 11 May 2018 19:57:49 +0100 Subject: Script to scrub old non-open reports. --- CHANGELOG.md | 3 +- bin/process-inactive-reports | 40 ++++++++++++++++++++++++ perllib/FixMyStreet/Script/Inactive.pm | 57 ++++++++++++++++++++++++++++++++++ t/script/inactive.t | 35 +++++++++++++++++++++ 4 files changed, 134 insertions(+), 1 deletion(-) create mode 100755 bin/process-inactive-reports 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; -- cgit v1.2.3 From 15678f4923a3395fc3bb4b6c6cc82cf38d09021e Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Tue, 15 May 2018 13:05:17 +0100 Subject: Add ability to close updates on reports. The inactive report script can mark matched reports as closed for updates. This removes the update form and signing up for updates from a report page. --- CHANGELOG.md | 2 +- bin/process-inactive-reports | 7 ++++--- .../FixMyStreet/App/Controller/Report/Update.pm | 1 + perllib/FixMyStreet/Script/Inactive.pm | 24 ++++++++++++++++++++++ t/script/inactive.t | 8 ++++++++ templates/web/base/report/display.html | 4 ++-- templates/web/base/report/display_tools.html | 2 +- templates/web/base/report/update-form.html | 2 +- templates/web/bromley/report/update-form.html | 3 +++ 9 files changed, 45 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5baa0408..78b50e945 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,7 +55,7 @@ - Display contents of report's extra field #1809 - Store user creation and last active times. - Add scripts to anonymize inactive users and reports, - or email inactive users. + email inactive users, or to close reports to new updates. - 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 index 3f133d11a..d2c030c2c 100755 --- a/bin/process-inactive-reports +++ b/bin/process-inactive-reports @@ -15,9 +15,9 @@ use FixMyStreet::Script::Inactive; use Pod::Usage; my %h; -GetOptions(\%h, 'anonymize=i', 'verbose|v', 'help|h', 'dry-run|n'); +GetOptions(\%h, 'anonymize=i', 'close=i', 'verbose|v', 'help|h', 'dry-run|n'); pod2usage(0) if $h{help}; -pod2usage(1) unless $h{anonymize}; +pod2usage(1) unless $h{anonymize} || $h{close}; FixMyStreet::Script::Inactive->new(%h)->reports; @@ -29,10 +29,11 @@ process-inactive-reports - deal with anonymizing inactive non-open reports =head1 SYNOPSIS -process-inactive-reports --anonymize N +process-inactive-reports [--anonymize N] [--close N] Options: --anonymize Anonymize non-open reports (and related) inactive longer than this time (months) + --close Close comments on non-open reports 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 diff --git a/perllib/FixMyStreet/App/Controller/Report/Update.pm b/perllib/FixMyStreet/App/Controller/Report/Update.pm index 13eceadb0..4a5b8db5d 100644 --- a/perllib/FixMyStreet/App/Controller/Report/Update.pm +++ b/perllib/FixMyStreet/App/Controller/Report/Update.pm @@ -240,6 +240,7 @@ This makes sure we only proceed to processing if we've had the form submitted sub check_form_submitted : Private { my ( $self, $c ) = @_; + return if $c->stash->{problem}->get_extra_metadata('closed_updates'); return $c->get_param('submit_update') || ''; } diff --git a/perllib/FixMyStreet/Script/Inactive.pm b/perllib/FixMyStreet/Script/Inactive.pm index 3c6be9901..0468d2a52 100644 --- a/perllib/FixMyStreet/Script/Inactive.pm +++ b/perllib/FixMyStreet/Script/Inactive.pm @@ -11,6 +11,7 @@ use FixMyStreet::DB; use FixMyStreet::Email; has anonymize => ( is => 'ro' ); +has close => ( is => 'ro' ); has email => ( is => 'ro' ); has verbose => ( is => 'ro' ); has dry_run => ( is => 'ro' ); @@ -53,6 +54,29 @@ sub reports { my $self = shift; say "DRY RUN" if $self->dry_run; + $self->anonymize_reports if $self->anonymize; + $self->close_updates if $self->close; +} + +sub close_updates { + my $self = shift; + + my $problems = FixMyStreet::DB->resultset("Problem")->search({ + lastupdate => { '<', interval($self->close) }, + state => [ FixMyStreet::DB::Result::Problem->closed_states(), FixMyStreet::DB::Result::Problem->fixed_states() ], + extra => [ undef, { -not_like => '%closed_updates%' } ], + }); + + while (my $problem = $problems->next) { + say "Closing updates on problem #" . $problem->id if $self->verbose; + next if $self->dry_run; + $problem->set_extra_metadata( closed_updates => 1 ); + $problem->update; + } +} + +sub anonymize_reports { + my $self = shift; # Need to look though them all each time, in case any new updates/alerts my $problems = FixMyStreet::DB->resultset("Problem")->search({ diff --git a/t/script/inactive.t b/t/script/inactive.t index 9d1e3f4bd..4d78b385f 100644 --- a/t/script/inactive.t +++ b/t/script/inactive.t @@ -50,6 +50,14 @@ subtest 'Anonymization of inactive fixed/closed reports' => sub { is $comment->user->email, 'removed-automatically@example.org', 'Comment user anonymized'; }; +subtest 'Closing updates on inactive fixed/closed reports' => sub { + my $in = FixMyStreet::Script::Inactive->new( close => 1 ); + $in->reports; + $problems[2]->discard_changes; + is $problems[2]->get_extra_metadata('closed_updates'), 1, 'Closed to updates'; + # TODO Visit page, check closed for updates +}; + subtest 'Anonymization of inactive users' => sub { $in->users; diff --git a/templates/web/base/report/display.html b/templates/web/base/report/display.html index f9c42b35d..8c461dced 100644 --- a/templates/web/base/report/display.html +++ b/templates/web/base/report/display.html @@ -53,7 +53,7 @@ [% TRY %][% INCLUDE 'report/sharing.html' %][% CATCH file %][% END %] [% INCLUDE 'report/updates.html' %] -[% IF two_column_sidebar %] +[% IF two_column_sidebar AND NOT problem.extra.closed_updates %]
[% END %] @@ -62,7 +62,7 @@ [% ELSIF NOT shown_form %] [% INCLUDE 'report/update-form.html' %] [% END %] -[% IF two_column_sidebar %] +[% IF two_column_sidebar AND NOT problem.extra.closed_updates %]
[% END %] diff --git a/templates/web/base/report/display_tools.html b/templates/web/base/report/display_tools.html index 8ed86c228..e0d8e3f99 100644 --- a/templates/web/base/report/display_tools.html +++ b/templates/web/base/report/display_tools.html @@ -10,7 +10,7 @@ c.cobrand.moniker == 'fixmystreet' ? 'Unsuitable?' : loc('Report abuse') %] [% END %] - [% IF c.cobrand.moniker != 'zurich' %] + [% IF NOT problem.extra.closed_updates AND c.cobrand.moniker != 'zurich' %]
  • [% loc('Get updates' ) %]
  • [% END %] [% IF c.cobrand.moniker == 'fixmystreet' %] diff --git a/templates/web/base/report/update-form.html b/templates/web/base/report/update-form.html index 1e67c2072..9276acde9 100644 --- a/templates/web/base/report/update-form.html +++ b/templates/web/base/report/update-form.html @@ -1,5 +1,5 @@ [% allow_creation = !c.cobrand.only_authed_can_create || (c.user && c.user.from_body) %] -[% RETURN IF NOT allow_creation %] +[% RETURN IF NOT allow_creation OR problem.extra.closed_updates %]
    [% IF NOT login_success AND NOT oauth_need_email %] diff --git a/templates/web/bromley/report/update-form.html b/templates/web/bromley/report/update-form.html index bdabe12c5..6c3ca9298 100644 --- a/templates/web/bromley/report/update-form.html +++ b/templates/web/bromley/report/update-form.html @@ -1,3 +1,6 @@ +[% allow_creation = !c.cobrand.only_authed_can_create || (c.user && c.user.from_body) %] +[% RETURN IF NOT allow_creation OR problem.extra.closed_updates %] +
    [% UNLESS hide_header %] [% loc('Provide an update') %] -- cgit v1.2.3 From 87f82f0caa7a7d25d09a8861582d087395578007 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Tue, 15 May 2018 16:52:47 +0100 Subject: Add admin tickbox to close report to updates. --- CHANGELOG.md | 1 + perllib/FixMyStreet/App/Controller/Admin.pm | 6 ++++ t/app/controller/admin/report_edit.t | 46 +++++++++++++++++++++++++++-- templates/web/base/admin/report_edit.html | 3 ++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78b50e945..a3645a6c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -56,6 +56,7 @@ - Store user creation and last active times. - Add scripts to anonymize inactive users and reports, email inactive users, or to close reports to new updates. + - Admin ability to close reports to new updates. #43 - Development improvements: - Add HTML email previewer. - Add CORS header to Open311 output. #2022 diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 0d897e71e..7d04f5ff9 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -928,6 +928,12 @@ sub report_edit : Path('report_edit') : Args(1) { } $problem->set_inflated_columns(\%columns); + if ($c->get_param('closed_updates')) { + $problem->set_extra_metadata(closed_updates => 1); + } else { + $problem->unset_extra_metadata('closed_updates'); + } + $c->forward( '/admin/report_edit_category', [ $problem, $problem->state ne $old_state ] ); $c->forward('update_user', [ $problem ]); diff --git a/t/app/controller/admin/report_edit.t b/t/app/controller/admin/report_edit.t index 0a4e702bb..5e3e6c315 100644 --- a/t/app/controller/admin/report_edit.t +++ b/t/app/controller/admin/report_edit.t @@ -79,6 +79,7 @@ foreach my $test ( anonymous => 0, flagged => undef, non_public => undef, + closed_updates => undef, }, changes => { title => 'Edited Report', }, log_entries => [qw/edit/], @@ -95,6 +96,7 @@ foreach my $test ( anonymous => 0, flagged => undef, non_public => undef, + closed_updates => undef, }, changes => { detail => 'Edited Detail', }, log_entries => [qw/edit edit/], @@ -111,6 +113,7 @@ foreach my $test ( anonymous => 0, flagged => undef, non_public => undef, + closed_updates => undef, }, changes => { name => 'Edited User', }, log_entries => [qw/edit edit edit/], @@ -128,6 +131,7 @@ foreach my $test ( anonymous => 0, flagged => undef, non_public => undef, + closed_updates => undef, }, changes => { flagged => 'on', @@ -147,6 +151,7 @@ foreach my $test ( anonymous => 0, flagged => 'on', non_public => undef, + closed_updates => undef, }, changes => { username => $user2->email, }, log_entries => [qw/edit edit edit edit edit/], @@ -164,6 +169,7 @@ foreach my $test ( anonymous => 0, flagged => 'on', non_public => undef, + closed_updates => undef, }, expect_comment => 1, changes => { state => 'unconfirmed' }, @@ -181,6 +187,7 @@ foreach my $test ( anonymous => 0, flagged => 'on', non_public => undef, + closed_updates => undef, }, expect_comment => 1, changes => { state => 'confirmed' }, @@ -198,6 +205,7 @@ foreach my $test ( anonymous => 0, flagged => 'on', non_public => undef, + closed_updates => undef, }, expect_comment => 1, changes => { state => 'fixed' }, @@ -216,6 +224,7 @@ foreach my $test ( anonymous => 0, flagged => 'on', non_public => undef, + closed_updates => undef, }, expect_comment => 1, changes => { state => 'hidden' }, @@ -235,6 +244,7 @@ foreach my $test ( anonymous => 0, flagged => 'on', non_public => undef, + closed_updates => undef, }, expect_comment => 1, changes => { @@ -257,6 +267,7 @@ foreach my $test ( anonymous => 1, flagged => 'on', non_public => undef, + closed_updates => undef, }, changes => {}, log_entries => [ @@ -275,6 +286,7 @@ foreach my $test ( anonymous => 1, flagged => 'on', non_public => undef, + closed_updates => undef, }, changes => { non_public => 'on', @@ -284,6 +296,24 @@ foreach my $test ( ], resend => 0, }, + { + description => 'close to updates', + fields => { + title => 'Edited Report', + detail => 'Edited Detail', + state => 'confirmed', + name => 'Edited User', + username => $user2->email, + anonymous => 1, + flagged => 'on', + non_public => 'on', + closed_updates => undef, + }, + changes => { closed_updates => 'on' }, + log_entries => [ + qw/edit edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ + ], + }, { description => 'change state to investigating as body superuser', fields => { @@ -295,12 +325,13 @@ foreach my $test ( anonymous => 1, flagged => 'on', non_public => 'on', + closed_updates => undef, }, expect_comment => 1, user_body => $oxfordshire, changes => { state => 'investigating' }, log_entries => [ - qw/edit state_change edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ + qw/edit state_change edit edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ ], resend => 0, }, @@ -315,13 +346,14 @@ foreach my $test ( anonymous => 1, flagged => 'on', non_public => 'on', + closed_updates => undef, }, expect_comment => 1, expected_text => '*Category changed from ‘Other’ to ‘Potholes’*', user_body => $oxfordshire, changes => { state => 'in progress', category => 'Potholes' }, log_entries => [ - qw/edit state_change edit state_change edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ + qw/edit state_change edit state_change edit edit resend edit state_change edit state_change edit state_change edit state_change edit state_change edit edit edit edit edit/ ], resend => 0, }, @@ -371,6 +403,15 @@ foreach my $test ( $test->{changes}->{flagged} = 1 if $test->{changes}->{flagged}; $test->{changes}->{non_public} = 1 if $test->{changes}->{non_public}; + if ($test->{changes}->{closed_updates}) { + is $report->get_extra_metadata('closed_updates'), 1, "closed_updates updated"; + $mech->get_ok("/report/$report_id"); + $mech->content_lacks('Provide an update'); + $report->unset_extra_metadata('closed_updates'); + $report->update; + delete $test->{changes}->{closed_updates}; + } + is $report->$_, $test->{changes}->{$_}, "$_ updated" for grep { $_ ne 'username' } keys %{ $test->{changes} }; if ( $test->{user} ) { @@ -451,6 +492,7 @@ subtest 'change email to new user' => sub { anonymous => 1, flagged => 'on', non_public => 'on', + closed_updates => undef, external_id => '13', external_body => '', external_team => '', diff --git a/templates/web/base/admin/report_edit.html b/templates/web/base/admin/report_edit.html index 138ba8c05..10eb0eea1 100644 --- a/templates/web/base/admin/report_edit.html +++ b/templates/web/base/admin/report_edit.html @@ -172,6 +172,9 @@ class="admin-offsite-link">[% problem.latitude %], [% problem.longitude %] [% END %] +
  • +
  • + -- cgit v1.2.3 From 9eb0b8ba50ab3835023477f7a44fa9cd4d8c787c Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Mon, 21 May 2018 15:53:48 +0100 Subject: [Open311] Cope with undefined names. --- perllib/Open311.pm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/perllib/Open311.pm b/perllib/Open311.pm index dc40076db..a91de0a7c 100644 --- a/perllib/Open311.pm +++ b/perllib/Open311.pm @@ -132,7 +132,7 @@ sub _populate_service_request_params { description => $description, service_code => $service_code, first_name => $firstname, - last_name => $lastname || '', + last_name => $lastname, }; $params->{phone} = $problem->user->phone if $problem->user->phone; @@ -413,9 +413,11 @@ sub _populate_service_request_update_params { sub split_name { my ( $self, $name ) = @_; + return ('', '') unless $name; + my ( $first, $last ) = ( $name =~ /(\w+)(?:\.?\s+(.+))?/ ); - return ( $first, $last ); + return ( $first || '', $last || ''); } sub _params_to_string { -- cgit v1.2.3 From ec4fb8fe445efd5cb584ac7021707c41a0188cdb Mon Sep 17 00:00:00 2001 From: Jon Kristensen Date: Tue, 22 May 2018 18:17:19 +0200 Subject: [FixaMinGata] Update privacy policy --- templates/web/fixamingata/about/privacy.html | 39 ++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/templates/web/fixamingata/about/privacy.html b/templates/web/fixamingata/about/privacy.html index 805ca5f00..ced2c3b27 100755 --- a/templates/web/fixamingata/about/privacy.html +++ b/templates/web/fixamingata/about/privacy.html @@ -15,35 +15,48 @@

    Offentlighet, kakor och tredjepartstjänster

    Vår användning av din information och vad du behöver veta.

    Offentlighetsprincipen är en viktig del i det demokratiska samhället. Genom tryckfrihetsförordningen och offentlighetslagen har du rätt att ta del av allmänna offentliga handlingar hos statliga och kommunala myndigheter. Det kan ge dig insyn i hur förtroendevalda (politiker) och tjänstemän handlägger ärenden, vilka handlingar som kommit in till kommunens olika förvaltningar och vilka som skickats ut.

    -

    Lagen som reglerar hur personuppgifter samlas in, bearbetas och sprids heter Personuppgiftslagen (PuL). Lagen skyddar den enskildes integritet vid behandling av personuppgifter. Fr.o.m. 2018-05-25 införs ett nytt regelverk i EU för behandling av personuppgifter och ska börja tillämpas av medlemsstaterna i maj 2018.

    -

    Dataskyddsförordning

    -

    FixaMinGata använder kakor för att hjälpa oss att göra tjänsten bättre. Nedan beskrivs hur din data används.

    +

    Fr.o.m. 2018-05-25 tillämpas ett nytt regelverk inom EU för behandling av personuppgifter – i Sverige kallad Dataskyddsfördordningen.

    +

    Laglig grund för behandling av personuppgifter
    FixaMinGata.se behandlar all data, inklusive personuppgifter, baserat på Dataskyddsförordningens Artikel 6.1f - Behandlingen är nödvändig för ändamål som rör den personuppgiftsansvariges eller en tredje parts berättigade intressen.

    +

     

    +

    Dataskyddsförordningen

    +

    Förordningen innehåller regler om hur personuppgifter får behandlas. Förordningen gäller i alla EU:s medlemsländer och ersätter nationella regler, som till exempel Personuppgiftslagen i Sverige.

    +

    Dataskyddsförordningens syfte är dels att skydda enskildas grundläggande rättigheter och friheter, särskilt deras rätt till skydd av personuppgifter och dels att skapa en enhetlig och likvärdig nivå för skyddet av personuppgifter inom EU, så att det fria flödet av uppgifter inom unionen inte hindras.

    +

    En tillsynsmyndighet i varje EU-land ska övervaka att de som behandlar personuppgifter följer dataskyddsförordningen. Tillsynsmyndigheten ska vara fullständigt oberoende i utförandet av sina uppgifter och utövandet av sina befogenheter. I Sverige föreslås Datainspektionen få det uppdraget.

    +

    FixaMinGata använder s k kakor för att hjälpa oss att göra tjänsten bättre. Nedan beskrivs hur de data du rapporterar in via FixaMinGata – inklusive eventuella uppgifter om dig själv – används.

    Offentlighet och personuppgifter

    +

    För att Du som rapportör ska kunna rapportera ärenden behandlas och lagras personuppgifter i samband med skapande av konto. Inrapporterade ärenden kommer avidentifieras tre månader efter den senaste aktiviteten i ärendet. Det innebär att eventuella personuppgifter i ärendet kommer att raderas, medan uppgifterna om ärendet kan vara av allmänt intresse och kommer att finnas kvar som underlag för forskning, statistik o dyl. Konton som inte använts på 12 månader kommer att raderas och när Du återigen ska rapportera behöver ett nytt konto skapas.

    -
    Hur hanteras mina personuppgifter?
    -
    Din e-postadress och namn lagras i vår databas. Du har rätt att begära att få ta del av de uppgifter som finns registrerade om dig genom att kontakta vårt personuppgiftsombud.
    -
    Hur hanteras min information hos FixaMinGata?
    -
    Vi kommer att visa en rapports ärende och information publikt, dock inte visa din e-postadress eller ditt namn, om du inte ger oss tillstånd.
    -
    Hur hanteras min information hos kommunen?
    -
    All information som du anger kring ett problem kommer att skickas till berörd kommun. Alla handlingar som inkommer till en kommun betraktas som offentliga och därmed kommer också alla rapporter från FixaMinGata att vara offentliga via den berörda kommunen.
    +
    Hur behandlas mina personuppgifter?
    +
    Din e-postadress och namn lagras i vår databas. Du har rätt att begära att få ta del av de uppgifter som finns registrerade om dig, begära rättning av uppgifter eller att uppgifter ska raderas genom att kontakta vårt personuppgiftsombud.

    Konton som inte använts på 12 månader kommer att raderas.

    +
    Hur behandlas min information hos FixaMinGata?
    +
    Vi kommer att visa en rapports ärende och information publikt, dock inte visa din e-postadress eller ditt namn, om du inte samtycker till detta. Lösta ärenden kommer att avidentifieras tre månader efter den senaste aktiviteten i ärendet (se ovan).
    +
    Hur behandlas min information hos kommunen?
    +
    All information som du anger kring ett problem kommer att skickas till berörd kommun eller den part som behandlar en kommuns ärenden. Alla handlingar som inkommer till en kommun betraktas som offentliga och därmed kommer också alla rapporter från FixaMinGata att vara offentliga via den berörda kommunen.

    Sekretess

    -
    Vem ser min epostadress?
    -
    Om du rapporterar ett problem kommer vi att skicka - din information och upplysning om problemet - till den kommun som är ansvarig för det område där du lokaliserat problemet. Förutom kommunen, som ser din e-postadress, kommer personer som är ansvariga för tjänsten FixaMinGata att kunna se din e-postadress. Ingen kommer att använda din e-postadress för något annat än för att kunna administrera FixaMinGata. Vi kommer inte att ge ut eller sälja din e-postadress till någon annan om vi inte blir tvingade till det av domstol. Ditt namn, som du anger det, kommer inte att publiceras om du inte ger oss tillstånd. Observera dock att om du skriver ditt namn någon annanstans, exempelvis i rapportens information, kommer det att vara synligt.
    +
    Vem ser min e-postadress?
    +
    Om du rapporterar ett problem kommer vi att skicka din information och upplysning om problemet till den kommun, eller den part som behandlar en kommuns ärende, som är ansvarig för det område där du lokaliserat problemet. Förutom kommun/partner, som ser din e-postadress, kommer personer som är ansvariga för tjänsten FixaMinGata att kunna se din e-postadress.

    Din e-postadress kommer bara användas för att kunna administrera FixaMinGata. Vi kommer inte att ge ut eller sälja din e-postadress till någon annan om vi inte blir tvingade till det av domstol. Ditt namn, som du anger det, kommer inte att publiceras om du inte ger samtycke. Observera dock att om du skriver ditt namn någon annanstans, exempelvis i rapportens information, kommer det att vara synligt.

    Kommer ni att skicka spam?
    Aldrig. Vi kommer att skicka ett e-postmeddelande till dig om någon lämnar en uppdatering på ett problem som du rapporterat, och fyra veckor efter din rapportering skickas ett frågeformulär. Vi kommer endast att skicka e-postmeddelande som relaterar till ditt problem.
    +
    Borttag av information, bilder e dyl.
    +
    Om du laddar upp bilder och annan information kring ett problem, bör du vara försiktig så att inte personer, bilar eller andra uppgifter som kan identifiera en annan person följer med.

    Begäran om radering av personuppgift sker genom att kontakta vårt personuppgiftsombud.

    Kakor

    -

    Kakor används för att ge en besökare tillgång till olika funktioner. För att göra tjänsten lättare och mer användbara skickas små datafiler till din dator eller mobiltelefon. Dessa kallas för kakor och de flesta webbplatser använder dem. Informationen används för att, till exempel, komma ihåg tidigare inloggning, och för att mäta hur tjänsten används som underlag för förbättringar.

    -

    Om kakor och hur du kan hantera dem, Post- och telestyrelsen

    +

    S k kakor används för att ge en användare tillgång till olika funktioner. För att göra tjänsten lättare och mer användbara skickas små datafiler till din dator eller mobiltelefon. Dessa kallas för kakor och de flesta webbplatser använder dem. Informationen används för att, till exempel, komma ihåg tidigare inloggning, och för att mäta hur tjänsten används som underlag för förbättringar.

    +

    Läs mer om kakor och hur du kan hantera dem på Post- och telestyrelsens webbplats.

    Nedan visas en lista med kakor som tjänsten använder.

    NamnInnehållGiltighet
    fixmystreet_app_sessionA slumpvis strängRaderas när webbläsaren stängs, eller efter fyra veckor om “Håll mig inloggad” är valt
    +
    +
    Vad är INTE FixaMinGata till för?
    +
    FixaMinGata är inte lämpligt för andra typer av problem än de som anges ovan. Du måste kontakta din kommun eller fastighetsägare direkt för problem i stil med:
    • Brådskande och akuta problem
    • Oljud i din närmiljö
    • Brand och rök
    • Förslag på nya vägar, farthinder, etc.
    • Klaga på dina grannar
    • Klaga på din kommun
    • Droger, djurplågeri, stöld, eller andra kriminella aktiviteter.
    • Information kring brott/överträdelser eller misstanke om detsamma
    +
    + [% INCLUDE 'footer.html' pagefooter = 'yes' %] -- cgit v1.2.3