From 683b188b288fe43526e1649c784fa44435559655 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Thu, 30 Apr 2020 13:51:42 +0100 Subject: Move per-row Contact lookup to the database. On admin report lists, and in front-end lists when an inspector, each row was querying the database for `category_display`. We create a new relationship for this query, and join/prefetch it wherever we request this data. Include staff joins on /around page, copying what happens on /reports to prevent more lookups there too. Also add some joins for user email in admin report list. --- perllib/FixMyStreet/App/Controller/Report.pm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 72f96013a..058edebd8 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -133,11 +133,13 @@ sub support :Chained('id') :Args(0) { sub load_problem_or_display_error : Private { my ( $self, $c, $id ) = @_; + my $attrs = { prefetch => 'contact' }; + # try to load a report if the id is a number my $problem = ( !$id || $id =~ m{\D} ) # is id non-numeric? ? undef # ...don't even search - : $c->cobrand->problems->find( { id => $id } ) + : $c->cobrand->problems->find( { id => $id }, $attrs ) or $c->detach( '/page_error_404_not_found', [ _('Unknown problem ID') ] ); # check that the problem is suitable to show. -- cgit v1.2.3 From 7d395d5ca8049a904473e90957115ce675e57db7 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Fri, 17 Apr 2020 12:43:57 +0100 Subject: Refactor report page permissions. Look up user's permissions once at the start, and use that throughout the report page templates. --- perllib/FixMyStreet/App/Controller/Report.pm | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 058edebd8..82e8b107f 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -85,14 +85,14 @@ sub display :PathPart('') :Chained('id') :Args(0) { $c->forward( 'load_updates' ); $c->forward( 'format_problem_for_display' ); - my $permissions = $c->stash->{_permissions} ||= $c->forward( 'check_has_permission_to', - [ qw/report_inspect report_edit_category report_edit_priority report_mark_private triage/ ] ); - if (any { $_ } values %$permissions) { + my $permissions = $c->stash->{permissions} ||= $c->forward('fetch_permissions'); + + if (grep { $permissions->{$_} } qw/report_inspect report_edit_category report_edit_priority report_mark_private triage/) { $c->stash->{template} = 'report/inspect.html'; $c->forward('inspect'); } - if ($c->user_exists && $c->user->has_permission_to(contribute_as_another_user => $c->stash->{problem}->bodies_str_ids)) { + if ($permissions->{contribute_as_another_user}) { $c->stash->{email} = $c->user->email; } } @@ -160,8 +160,7 @@ sub load_problem_or_display_error : Private { } elsif ( $problem->non_public ) { # Creator, and inspection users can see non_public reports $c->stash->{problem} = $problem; - my $permissions = $c->stash->{_permissions} = $c->forward( 'check_has_permission_to', - [ qw/report_inspect report_edit_category report_edit_priority report_mark_private / ] ); + my $permissions = $c->stash->{permissions} = $c->forward('fetch_permissions'); # If someone has clicked a unique token link in an email to them my $from_email = $c->sessionid && $c->flash->{alert_to_reporter} && $c->flash->{alert_to_reporter} == $problem->id; @@ -386,7 +385,7 @@ sub delete :Chained('id') :Args(0) { sub inspect : Private { my ( $self, $c ) = @_; my $problem = $c->stash->{problem}; - my $permissions = $c->stash->{_permissions}; + my $permissions = $c->stash->{permissions}; $c->forward('/admin/reports/categories_for_point'); $c->stash->{report_meta} = { map { 'x' . $_->{name} => $_ } @{ $c->stash->{problem}->get_extra_fields() } }; @@ -668,22 +667,19 @@ sub _nearby_json :Private { } -=head2 check_has_permission_to +=head2 fetch_permissions -Ensure the currently logged-in user has any of the provided permissions applied -to the current Problem in $c->stash->{problem}. Shows the 403 page if not. +Returns a hash of the user's permissions, applied to the problem +in $c->stash->{problem}. =cut -sub check_has_permission_to : Private { - my ( $self, $c, @permissions ) = @_; +sub fetch_permissions : Private { + my ( $self, $c ) = @_; return {} unless $c->user_exists; - my $bodies = $c->stash->{problem}->bodies_str_ids; - my %permissions = map { $_ => $c->user->has_permission_to($_, $bodies) } @permissions; - return \%permissions; + return $c->user->permissions($c->stash->{problem}); }; - sub stash_category_groups : Private { my ( $self, $c, $contacts, $combine_multiple ) = @_; -- cgit v1.2.3 From ecc5a7b9ca20418f1bdb45cdc3ce5b41a11f3593 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Wed, 15 Apr 2020 19:12:31 +0100 Subject: Add assigned_(users|categories)_only functionality Users with assigned_categories_only will only see staff features on a report page in their assigned categories. Users will only see staff features on a report page in a category with assigned_users_only if it is in their assigned categories. --- perllib/FixMyStreet/App/Controller/Report.pm | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 82e8b107f..3052b1015 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -87,6 +87,24 @@ sub display :PathPart('') :Chained('id') :Args(0) { my $permissions = $c->stash->{permissions} ||= $c->forward('fetch_permissions'); + my $staff_user = $c->user_exists && ($c->user->is_superuser || $c->user->belongs_to_body($c->stash->{problem}->bodies_str)); + + if ($staff_user) { + # Check assigned categories feature + my $okay = 1; + my $contact = $c->stash->{problem}->contact; + if ($contact && ($c->user->get_extra_metadata('assigned_categories_only') || $contact->get_extra_metadata('assigned_users_only'))) { + my $user_cats = $c->user->get_extra_metadata('categories') || []; + $okay = any { $contact->id eq $_ } @$user_cats; + } + if ($okay) { + $c->stash->{relevant_staff_user} = 1; + } else { + # Remove all staff permissions + $permissions = $c->stash->{permissions} = {}; + } + } + if (grep { $permissions->{$_} } qw/report_inspect report_edit_category report_edit_priority report_mark_private triage/) { $c->stash->{template} = 'report/inspect.html'; $c->forward('inspect'); -- cgit v1.2.3 From d1622dc20c1623e3f7fb54d72d99370af796c197 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Fri, 17 Apr 2020 14:07:32 +0100 Subject: Extend assigned_*_only to report lists. Shortlist buttons and extended print information will not appear where not allowed. --- perllib/FixMyStreet/App/Controller/Report.pm | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 3052b1015..8a6047194 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -724,6 +724,19 @@ sub stash_category_groups : Private { $c->stash->{category_groups} = \@category_groups; } +sub assigned_users_only : Private { + my ($self, $c, $categories) = @_; + + # Assigned only category checking + if ($c->user_exists && $c->user->from_body) { + my @assigned_users_only = grep { $_->get_extra_metadata('assigned_users_only') } @$categories; + $c->stash->{assigned_users_only} = { map { $_->category => 1 } @assigned_users_only }; + $c->stash->{assigned_categories_only} = $c->user->get_extra_metadata('assigned_categories_only'); + + $c->stash->{user_categories} = { map { $_ => 1 } @{$c->user->categories} }; + } +} + __PACKAGE__->meta->make_immutable; 1; -- cgit v1.2.3 From 72809e405e690c88d0e2011802820c9ba215ef61 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Mon, 11 May 2020 16:06:37 +0100 Subject: Consistent use of Contact groups. --- perllib/FixMyStreet/App/Controller/Report.pm | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 8a6047194..4d8794c59 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -703,9 +703,8 @@ sub stash_category_groups : Private { my %category_groups = (); for my $category (@$contacts) { - my $group = $category->{group} // $category->get_extra_metadata('group') // ['']; - # this could be an array ref or a string - my @groups = ref $group eq 'ARRAY' ? @$group : ($group); + my $group = $category->{group} // $category->groups; + my @groups = @$group; if (scalar @groups > 1 && $combine_multiple) { @groups = sort @groups; $category->{group} = \@groups; -- cgit v1.2.3 From 6088d10642da56cbea96446da9d9cd87c922ede5 Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Tue, 9 Jun 2020 15:18:16 +0100 Subject: [Highways England] Anonymize all names on cobrand. --- perllib/FixMyStreet/App/Controller/Report.pm | 2 ++ 1 file changed, 2 insertions(+) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 4d8794c59..4f9825cae 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -197,6 +197,7 @@ sub load_problem_or_display_error : Private { } } + $c->cobrand->call_hook(munge_problem_list => $problem); $c->stash->{problem} = $problem; if ( $c->user_exists && $c->user->can_moderate($problem) ) { $c->stash->{problem_original} = $problem->find_or_new_related( @@ -251,6 +252,7 @@ sub load_updates : Private { my @combined; my %questionnaires_with_updates; while (my $update = $updates->next) { + $c->cobrand->call_hook(munge_update_list => $update); push @combined, [ $update->confirmed, $update ]; if (my $qid = $update->get_extra_metadata('questionnaire_id')) { $questionnaires_with_updates{$qid} = $update; -- cgit v1.2.3 From 67823bc788ce744e1228a8602b9a5aa805771ced Mon Sep 17 00:00:00 2001 From: Matthew Somerville Date: Fri, 10 Jul 2020 14:38:17 +0100 Subject: Centralise update creation to include fields. Given the user, we can infer the name if not provided, and the extra data if a staff user. We can also provide defaults for various other fields. Always have superuser take precedence over from_body. --- perllib/FixMyStreet/App/Controller/Report.pm | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 4f9825cae..dd7abc563 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -569,16 +569,11 @@ sub inspect : Private { epoch => $saved_at ); } - my $name = $c->user->from_body ? $c->user->from_body->name : $c->user->name; $problem->add_to_comments( { text => $update_text, created => $timestamp, confirmed => $timestamp, - user_id => $c->user->id, - name => $name, - state => 'confirmed', - mark_fixed => 0, - anonymous => 0, + user => $c->user->obj, %update_params, } ); } -- cgit v1.2.3 From ed0002b0d76560cc3d5b1e62f8395bbfae74403c Mon Sep 17 00:00:00 2001 From: Chris Mytton Date: Wed, 8 Apr 2020 14:39:19 +0100 Subject: Add photo upload field to inspector form This adds the code for photo uploads from the regular update form to the inspector form, and adds details to the documentation. --- perllib/FixMyStreet/App/Controller/Report.pm | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index dd7abc563..991064f55 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -554,6 +554,12 @@ sub inspect : Private { $c->cobrand->call_hook(report_inspect_update_extra => $problem); + $c->forward('/photo/process_photo'); + if ( my $photo_error = delete $c->stash->{photo_error} ) { + $valid = 0; + push @{ $c->stash->{errors} }, $photo_error; + } + if ($valid) { $problem->lastupdate( \'current_timestamp' ); $problem->update; @@ -574,6 +580,7 @@ sub inspect : Private { created => $timestamp, confirmed => $timestamp, user => $c->user->obj, + photo => $c->stash->{upload_fileid} || undef, %update_params, } ); } -- cgit v1.2.3 From 615ddb00265386849f32405426c5232b9127669a Mon Sep 17 00:00:00 2001 From: M Somerville Date: Wed, 5 Aug 2020 17:36:18 +0100 Subject: Remove use of $c from various functions. This means these functions can more easily be used in a non-web context. --- perllib/FixMyStreet/App/Controller/Report.pm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 991064f55..81d5b18b5 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -325,7 +325,7 @@ sub format_problem_for_display : Private { $c->res->content_type('application/json; charset=utf-8'); # encode_json doesn't like DateTime objects, so strip them out - my $report_hashref = $c->cobrand->problem_as_hashref( $problem, $c ); + my $report_hashref = $c->cobrand->problem_as_hashref( $problem ); delete $report_hashref->{created}; delete $report_hashref->{confirmed}; @@ -333,7 +333,7 @@ sub format_problem_for_display : Private { my $content = $json->encode( { report => $report_hashref, - updates => $c->cobrand->updates_as_hashref( $problem, $c ), + updates => $c->cobrand->updates_as_hashref( $problem ), } ); $c->res->body( $content ); @@ -354,7 +354,7 @@ sub generate_map_tags : Private { latitude => $problem->latitude, longitude => $problem->longitude, pins => $problem->used_map - ? [ $problem->pin_data($c, 'report', type => 'big', draggable => 1) ] + ? [ $problem->pin_data('report', type => 'big', draggable => 1) ] : [], ); @@ -670,7 +670,7 @@ sub _nearby_json :Private { # Want to treat these as if they were on map $nearby = [ map { $_->problem } @$nearby ]; my @pins = map { - my $p = $_->pin_data($c, 'around'); + my $p = $_->pin_data('around'); [ $p->{latitude}, $p->{longitude}, $p->{colour}, $p->{id}, $p->{title}, $pin_size, JSON->false ] -- cgit v1.2.3 From e3e1e9d54999692dc01f3fdd32693547af8deb7b Mon Sep 17 00:00:00 2001 From: M Somerville Date: Thu, 1 Oct 2020 14:44:07 +0100 Subject: Do not display deleted priorities in inspect form. --- perllib/FixMyStreet/App/Controller/Report.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 81d5b18b5..98c4aba17 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -413,7 +413,8 @@ sub inspect : Private { if ($c->cobrand->can('body')) { my $priorities_by_category = FixMyStreet::App->model('DB::ResponsePriority')->by_categories( $c->stash->{contacts}, - body_id => $c->cobrand->body->id + body_id => $c->cobrand->body->id, + problem => $problem, ); $c->stash->{priorities_by_category} = $priorities_by_category; my $templates_by_category = FixMyStreet::App->model('DB::ResponseTemplate')->by_categories( -- cgit v1.2.3 From 19deaf332d2843e3b4337f3e2047bce47e4a7cd1 Mon Sep 17 00:00:00 2001 From: Chris Mytton Date: Fri, 15 May 2020 17:42:06 +0100 Subject: [Oxfordshire] Add instruct defect functionality back in In the past Oxfordshire had a way for inspectors to "instruct a defect", which generated a CSV which got emailed to Oxfordshire with a list of defects. They now want to bring this functionality back, but instead of emailing a CSV they want it to call an API. As a first step towards that goal, this change adds back some of the instruct defect functionality that was removed in 68e18ff. --- perllib/FixMyStreet/App/Controller/Report.pm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'perllib/FixMyStreet/App/Controller/Report.pm') diff --git a/perllib/FixMyStreet/App/Controller/Report.pm b/perllib/FixMyStreet/App/Controller/Report.pm index 98c4aba17..1e5751588 100644 --- a/perllib/FixMyStreet/App/Controller/Report.pm +++ b/perllib/FixMyStreet/App/Controller/Report.pm @@ -467,7 +467,7 @@ sub inspect : Private { } } - if ( $c->get_param('include_update') ) { + if ( $c->get_param('include_update') or $c->get_param('raise_defect') ) { $update_text = Utils::cleanup_text( $c->get_param('public_update'), { allow_multiline => 1 } ); if (!$update_text) { $valid = 0; @@ -512,6 +512,14 @@ sub inspect : Private { }; $c->user->create_alert($problem->id, $options); } + + # If the state has been changed to action scheduled and they've said + # they want to raise a defect, consider the report to be inspected. + if ($problem->state eq 'action scheduled' && $c->get_param('raise_defect') && !$problem->get_extra_metadata('inspected')) { + $update_params{extra} = { 'defect_raised' => 1 }; + $problem->set_extra_metadata( inspected => 1 ); + $c->forward( '/admin/log_edit', [ $problem->id, 'problem', 'inspected' ] ); + } } $problem->non_public($c->get_param('non_public') ? 1 : 0); -- cgit v1.2.3