diff options
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 33 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Default.pm | 6 | ||||
-rw-r--r-- | perllib/FixMyStreet/DB/Result/User.pm | 16 | ||||
-rw-r--r-- | perllib/FixMyStreet/Script/Reports.pm | 11 | ||||
-rw-r--r-- | t/app/controller/admin.t | 1 | ||||
-rw-r--r-- | t/app/sendreport/inspection_required.t | 20 | ||||
-rw-r--r-- | templates/web/base/admin/user-form.html | 25 |
7 files changed, 106 insertions, 6 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index 63ed9f3c6..46ac10d36 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -1276,14 +1276,14 @@ sub user_edit : Path('user_edit') : Args(1) { if (!$user->from_body) { # Non-staff users aren't allowed any permissions or to be in an area - $user->user_body_permissions->delete_all; + $user->admin_user_body_permissions->delete; $user->area_id(undef); delete $c->stash->{areas}; delete $c->stash->{fetched_areas_body_id}; } elsif ($c->stash->{available_permissions}) { my @all_permissions = map { keys %$_ } values %{ $c->stash->{available_permissions} }; my @user_permissions = grep { $c->get_param("permissions[$_]") ? 1 : undef } @all_permissions; - $user->user_body_permissions->search({ + $user->admin_user_body_permissions->search({ body_id => $user->from_body->id, permission_type => { '!=' => \@user_permissions }, })->delete; @@ -1301,6 +1301,35 @@ sub user_edit : Path('user_edit') : Args(1) { $user->area_id( $valid_areas{$new_area} ? $new_area : undef ); } + # Handle 'trusted' flag(s) + my @trusted_bodies = $c->get_param_list('trusted_bodies'); + if ( $c->user->is_superuser ) { + $user->user_body_permissions->search({ + body_id => { '!=' => \@trusted_bodies }, + permission_type => 'trusted', + })->delete; + foreach my $body_id (@trusted_bodies) { + $user->user_body_permissions->find_or_create({ + body_id => $body_id, + permission_type => 'trusted', + }); + } + } elsif ( $c->user->from_body ) { + my %trusted = map { $_ => 1 } @trusted_bodies; + my $body_id = $c->user->from_body->id; + if ( $trusted{$body_id} ) { + $user->user_body_permissions->find_or_create({ + body_id => $body_id, + permission_type => 'trusted', + }); + } else { + $user->user_body_permissions->search({ + body_id => $body_id, + permission_type => 'trusted', + })->delete; + } + } + unless ($user->email) { $c->stash->{field_errors}->{email} = _('Please enter a valid email'); return; diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm index 47e577372..2b27a8891 100644 --- a/perllib/FixMyStreet/Cobrand/Default.pm +++ b/perllib/FixMyStreet/Cobrand/Default.pm @@ -720,6 +720,12 @@ sub available_permissions { planned_reports => _("Manage planned reports list"), contribute_as_another_user => _("Create reports/updates on a user's behalf"), contribute_as_body => _("Create reports/updates as the council"), + + # NB this permission is special in that it can be assigned to users + # without their from_body being set. It's included here for + # reference, but left commented out because it's not assigned in the + # same way as other permissions. + # trusted => _("Trusted to make reports that don't need to be inspected"), }, _("Users") => { user_edit => _("Edit other users' details"), diff --git a/perllib/FixMyStreet/DB/Result/User.pm b/perllib/FixMyStreet/DB/Result/User.pm index 56196c7c0..48b688000 100644 --- a/perllib/FixMyStreet/DB/Result/User.pm +++ b/perllib/FixMyStreet/DB/Result/User.pm @@ -292,6 +292,22 @@ sub has_body_permission_to { return $self->has_permission_to($permission_type, $self->from_body->id); } +=head2 admin_user_body_permissions + +Some permissions aren't managed in the normal way via the admin, e.g. the +'trusted' permission. This method returns a query that excludes such exceptional +permissions. + +=cut + +sub admin_user_body_permissions { + my $self = shift; + + return $self->user_body_permissions->search({ + permission_type => { '!=' => 'trusted' }, + }); +} + sub contributing_as { my ($self, $other, $c, $bodies) = @_; $bodies = [ keys %$bodies ] if ref $bodies eq 'HASH'; diff --git a/perllib/FixMyStreet/Script/Reports.pm b/perllib/FixMyStreet/Script/Reports.pm index ab0d90ba8..8816d0e3a 100644 --- a/perllib/FixMyStreet/Script/Reports.pm +++ b/perllib/FixMyStreet/Script/Reports.pm @@ -144,9 +144,14 @@ sub send(;$) { $reporters{ $sender } ||= $sender->new(); my $inspection_required = $sender_info->{contact}->get_extra_metadata('inspection_required') if $sender_info->{contact}; - if ( $inspection_required && !$row->get_extra_metadata('inspected') ) { - $skip = 1; - debug_print("skipped because not yet inspected", $row->id) if $debug_mode; + if ( $inspection_required ) { + unless ( + $row->get_extra_metadata('inspected') || + $row->user->has_permission_to( trusted => $row->bodies_str ) + ) { + $skip = 1; + debug_print("skipped because not yet inspected", $row->id) if $debug_mode; + } } if ( $reporters{ $sender }->should_skip( $row ) ) { diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t index 8c3cde4b7..7ba84b652 100644 --- a/t/app/controller/admin.t +++ b/t/app/controller/admin.t @@ -1165,6 +1165,7 @@ my %default_perms = ( "permissions[template_edit]" => undef, "permissions[responsepriority_edit]" => undef, "permissions[category_edit]" => undef, + trusted_bodies => undef, ); FixMyStreet::override_config { diff --git a/t/app/sendreport/inspection_required.t b/t/app/sendreport/inspection_required.t index 178fa2a1f..88a48e991 100644 --- a/t/app/sendreport/inspection_required.t +++ b/t/app/sendreport/inspection_required.t @@ -52,8 +52,28 @@ subtest 'Report is sent when inspected' => sub { ok $report->whensent, 'Report marked as sent'; }; +subtest 'Uninspected report is sent when made by trusted user' => sub { + $mech->clear_emails_ok; + $report->unset_extra_metadata('inspected'); + $report->whensent( undef ); + $report->update; + + $user->user_body_permissions->find_or_create({ + body => $body, + permission_type => 'trusted', + }); + ok $user->has_permission_to('trusted', $report->bodies_str_ids), 'User can make trusted reports'; + + FixMyStreet::DB->resultset('Problem')->send_reports(); + + $report->discard_changes; + $mech->email_count_is( 1 ); + ok $report->whensent, 'Report marked as sent'; +}; + done_testing(); END { + $mech->delete_user($user); $mech->delete_body($body); } diff --git a/templates/web/base/admin/user-form.html b/templates/web/base/admin/user-form.html index 38191e095..40e0b510a 100644 --- a/templates/web/base/admin/user-form.html +++ b/templates/web/base/admin/user-form.html @@ -85,10 +85,33 @@ [% loc("You can add an abusive user's email to the abuse list, which automatically hides (and never sends) reports they create.") %] </p> </div> - + [% loc('Flagged:') %] <input type="checkbox" id="flagged" name="flagged"[% user.flagged ? ' checked' : '' %]> </li> + [% UNLESS user.is_superuser %] + <li> + <div class="admin-hint"> + <p> + [% loc("Reports made by trusted users will be sent to the responsible body without being inspected first.") %] + </p> + </div> + [% IF c.user.is_superuser %] + [% loc('Trusted by bodies:') %]<br /> + <select id='body' name='trusted_bodies' multiple> + [% FOR body IN bodies %] + <option value="[% body.id %]"[% ' selected' IF user.has_permission_to('trusted', body.id) %]>[% body.name %]</option> + [% END %] + </select> + [% ELSE %] + <label> + [% loc('Trusted:') %] + <input type="checkbox" id="trusted_bodies" name="trusted_bodies" value="[% c.user.from_body.id %]" [% 'checked' IF user.has_permission_to('trusted', c.user.from_body.id) %]> + </label> + [% END %] + </li> + [% END %] + [% IF c.user.is_superuser %] <li> <div class="admin-hint"> |