From 5ea2de7ef01b8aa2e4f2f12537c86dc68272266e Mon Sep 17 00:00:00 2001 From: smarcet Date: Thu, 1 Oct 2026 21:47:49 -0300 Subject: [PATCH] fix(oauth2): return 412 instead of 500 on duplicate api scope group name ApiScopeGroupService threw InvalidApiScopeGroup on a name collision, which ApiScopeGroupController does not catch, so PUT /admin/api/v1/api-scope-groups/{id} and POST /admin/api/v1/api-scope-groups answered 500. Throw ValidationException, which the controller already maps to 412. --- app/Services/OAuth2/ApiScopeGroupService.php | 5 +- tests/unit/ApiScopeGroupServiceTest.php | 67 ++++++++++++++++++++ 2 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 tests/unit/ApiScopeGroupServiceTest.php diff --git a/app/Services/OAuth2/ApiScopeGroupService.php b/app/Services/OAuth2/ApiScopeGroupService.php index 66b8ac65..e757a72c 100644 --- a/app/Services/OAuth2/ApiScopeGroupService.php +++ b/app/Services/OAuth2/ApiScopeGroupService.php @@ -14,6 +14,7 @@ use App\Models\OAuth2\Factories\ApiScopeGroupFactory; use Auth\Repositories\IUserRepository; use models\exceptions\EntityNotFoundException; +use models\exceptions\ValidationException; use models\utils\IEntity; use OAuth2\Exceptions\InvalidApiScopeGroup; use OAuth2\Repositories\IApiScopeRepository; @@ -100,7 +101,7 @@ public function update(int $id, array $payload):IEntity $former_group = $this->repository->getByName($payload['name']); if(!is_null($former_group) && $former_group->getId() != $id) { - throw new InvalidApiScopeGroup(sprintf('there is already another api scope group name (%s).', $payload['name'])); + throw new ValidationException(sprintf('there is already another api scope group name (%s).', $payload['name'])); } } @@ -144,7 +145,7 @@ public function create(array $payload):IEntity if(!is_null($former_group)) { - throw new InvalidApiScopeGroup(sprintf('there is already another api scope group name (%s).', $name)); + throw new ValidationException(sprintf('there is already another api scope group name (%s).', $name)); } $group = ApiScopeGroupFactory::build($payload); $scopes = $payload['scopes']; diff --git a/tests/unit/ApiScopeGroupServiceTest.php b/tests/unit/ApiScopeGroupServiceTest.php new file mode 100644 index 00000000..43968fa1 --- /dev/null +++ b/tests/unit/ApiScopeGroupServiceTest.php @@ -0,0 +1,67 @@ +setName($name); + $group->setActive(true); + $group->setDescription('test description'); + EntityManager::persist($group); + EntityManager::flush(); + return $group; + } + + public function testUpdateWithNameUsedByAnotherGroupThrowsValidationException() + { + $suffix = uniqid(); + $this->persistGroup("group_a_$suffix"); + $group_b = $this->persistGroup("group_b_$suffix"); + + $this->expectException(ValidationException::class); + $this->expectExceptionMessage("group_a_$suffix"); + + app(IApiScopeGroupService::class)->update($group_b->getId(), ['name' => "group_a_$suffix"]); + } + + public function testCreateWithExistingNameThrowsValidationException() + { + $name = 'group_dup_' . uniqid(); + $this->persistGroup($name); + + $this->expectException(ValidationException::class); + $this->expectExceptionMessage($name); + + app(IApiScopeGroupService::class)->create([ + 'name' => $name, + 'scopes' => '', + 'users' => '', + ]); + } +}