diff options
-rw-r--r-- | perllib/FixMyStreet/App/Controller/Admin.pm | 12 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/Default.pm | 24 | ||||
-rw-r--r-- | perllib/FixMyStreet/Cobrand/UKCouncils.pm | 27 | ||||
-rw-r--r-- | t/app/controller/admin.t | 24 |
4 files changed, 84 insertions, 3 deletions
diff --git a/perllib/FixMyStreet/App/Controller/Admin.pm b/perllib/FixMyStreet/App/Controller/Admin.pm index fbd855333..91af480a8 100644 --- a/perllib/FixMyStreet/App/Controller/Admin.pm +++ b/perllib/FixMyStreet/App/Controller/Admin.pm @@ -920,7 +920,7 @@ sub users: Path('users') : Args(0) { my $search_n = 0; $search_n = int($search) if $search =~ /^\d+$/; - my $users = $c->model('DB::User')->search( + my $users = $c->cobrand->users->search( { -or => [ email => { ilike => $isearch }, @@ -952,7 +952,7 @@ sub users: Path('users') : Args(0) { $c->forward('fetch_all_bodies'); # Admin users by default - my $users = $c->model('DB::User')->search( + my $users = $c->cobrand->users->search( { from_body => { '!=', undef } }, { order_by => 'name' } ); @@ -1120,7 +1120,13 @@ sub user_edit : Path('user_edit') : Args(1) { $c->forward('/auth/get_csrf_token'); - my $user = $c->model('DB::User')->find( { id => $id } ); + my $user = $c->cobrand->users->find( { id => $id } ); + $c->detach( '/page_error_404_not_found' ) unless $user; + + unless ( $c->user->is_superuser || ( $c->user->has_permission_to('user_edit', $c->user->from_body->id) ) ) { + $c->detach('/page_error_403_access_denied', []); + } + $c->stash->{user} = $user; $c->forward('fetch_all_bodies'); diff --git a/perllib/FixMyStreet/Cobrand/Default.pm b/perllib/FixMyStreet/Cobrand/Default.pm index 686684a05..8c75a1234 100644 --- a/perllib/FixMyStreet/Cobrand/Default.pm +++ b/perllib/FixMyStreet/Cobrand/Default.pm @@ -140,6 +140,30 @@ sub problems_on_map_restriction { return $rs; } +=head1 users + +Returns a ResultSet of Users, potentially restricted to a subset if we're on +a cobrand that only wants some of the data. + +=cut + +sub users { + my $self = shift; + return $self->users_restriction($self->{c}->model('DB::User')); +} + +=head1 users_restriction + +Used to restricts users in the admin in a cobrand in a particular way. Do +nothing by default. + +=cut + +sub users_restriction { + my ($self, $rs) = @_; + return $rs; +} + sub site_key { return 0; } =head2 restriction diff --git a/perllib/FixMyStreet/Cobrand/UKCouncils.pm b/perllib/FixMyStreet/Cobrand/UKCouncils.pm index 43f10130a..701a4ca1c 100644 --- a/perllib/FixMyStreet/Cobrand/UKCouncils.pm +++ b/perllib/FixMyStreet/Cobrand/UKCouncils.pm @@ -50,6 +50,33 @@ sub updates_restriction { return $rs->to_body($self->council_id); } +sub users_restriction { + my ($self, $rs) = @_; + + # Council admins can only see users who are members of the same council or + # users who have sent a report or update to that council. + + my $problem_user_ids = $self->problems->search( + undef, + { + columns => [ 'user_id' ], + distinct => 1 + } + )->as_query; + my $update_user_ids = $self->updates->search( + undef, + { + columns => [ 'user_id' ], + distinct => 1 + } + )->as_query; + + return $rs->search([ + from_body => $self->council_id, + id => [ { -in => $problem_user_ids }, { -in => $update_user_ids } ], + ]); +} + sub base_url { my $self = shift; my $base_url = FixMyStreet->config('BASE_URL'); diff --git a/t/app/controller/admin.t b/t/app/controller/admin.t index aceaf2981..531fa7726 100644 --- a/t/app/controller/admin.t +++ b/t/app/controller/admin.t @@ -1102,6 +1102,30 @@ subtest 'user search' => sub { $mech->content_contains('Haringey'); }; +subtest 'search does not show user from another council' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshire' ], + }, sub { + $mech->get_ok('/admin/users'); + $mech->get_ok('/admin/users?search=' . $user->name); + + $mech->content_contains( "Searching found no users." ); + + $mech->get_ok('/admin/users?search=' . $user->email); + $mech->content_contains( "Searching found no users." ); + }; +}; + +subtest 'user_edit does not show user from another council' => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => [ 'oxfordshire' ], + }, sub { + $mech->get('/admin/user_edit/' . $user->id); + ok !$mech->res->is_success(), "want a bad response"; + is $mech->res->code, 404, "got 404"; + }; +}; + $log_entries = FixMyStreet::App->model('DB::AdminLog')->search( { object_type => 'user', |