diff --git a/app/Http/Controllers/Api/LocationsController.php b/app/Http/Controllers/Api/LocationsController.php index 9037d3fc5b..87bc266217 100644 --- a/app/Http/Controllers/Api/LocationsController.php +++ b/app/Http/Controllers/Api/LocationsController.php @@ -253,8 +253,12 @@ class LocationsController extends Controller */ public function selectlist(Request $request) { - - $this->authorize('view.selectlists'); + // If a user is in the process of editing their profile, as determined by the referrer, + // then we check that they have permission to edit their own location. + // Otherwise, we do our normal check that they can view select lists. + $request->headers->get('referer') === route('profile') + ? $this->authorize('self.edit_location') + : $this->authorize('view.selectlists'); $locations = Location::select([ 'locations.id', diff --git a/database/factories/UserFactory.php b/database/factories/UserFactory.php index 586cb7186b..2445a351f3 100644 --- a/database/factories/UserFactory.php +++ b/database/factories/UserFactory.php @@ -424,4 +424,12 @@ class UserFactory extends Factory }); } + public function canEditOwnLocation() + { + return $this->state(function () { + return [ + 'permissions' => '{"self.edit_location":"1"}', + ]; + }); + } } diff --git a/tests/Feature/Api/Locations/LocationsForSelectListTest.php b/tests/Feature/Api/Locations/LocationsForSelectListTest.php new file mode 100644 index 0000000000..4170cfc7f7 --- /dev/null +++ b/tests/Feature/Api/Locations/LocationsForSelectListTest.php @@ -0,0 +1,48 @@ +actingAsForApi(User::factory()->create()) + ->getJson(route('api.locations.selectlist')) + ->assertForbidden(); + } + + public function testLocationsReturned() + { + Location::factory()->create(); + + // see the where the "view.selectlists" is defined in the AuthServiceProvider + // for info on why "createUsers()" is used here. + $this->actingAsForApi(User::factory()->createUsers()->create()) + ->getJson(route('api.locations.selectlist')) + ->assertOk() + ->assertJsonStructure([ + 'results', + 'pagination', + 'total_count', + 'page', + 'page_count', + ]) + ->assertJson(fn(AssertableJson $json) => $json->has('results', 1)->etc()); + } + + public function testLocationsAreReturnedWhenUserIsUpdatingTheirProfileAndHasPermissionToUpdateLocation() + { + $this->actingAsForApi(User::factory()->canEditOwnLocation()->create()) + ->withHeader('referer', route('profile')) + ->getJson(route('api.locations.selectlist')) + ->assertOk(); + } +}