From 660e744cbe1557fd13a6f1a4f80da2e7176d61e2 Mon Sep 17 00:00:00 2001 From: Otavio G Date: Sat, 22 Jun 2024 17:18:37 -0300 Subject: [PATCH] refactor: use policies for authorization --- app/Enums/Role.php | 6 ++--- app/Models/Guild.php | 9 +++++++ app/Services/ChannelService.php | 18 ++++---------- app/Services/GuildService.php | 43 +++++++-------------------------- 4 files changed, 26 insertions(+), 50 deletions(-) diff --git a/app/Enums/Role.php b/app/Enums/Role.php index 05a3d09..9d0172c 100644 --- a/app/Enums/Role.php +++ b/app/Enums/Role.php @@ -4,9 +4,9 @@ enum Role: string { - case Admin = 'Admin'; - case Member = 'Member'; - case Moderator = 'Moderator'; + case Admin = 'admin'; + case Member = 'member'; + case Moderator = 'moderator'; public static function values(): array { diff --git a/app/Models/Guild.php b/app/Models/Guild.php index 9038f99..ceb50e8 100644 --- a/app/Models/Guild.php +++ b/app/Models/Guild.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Enums\Role; use Database\Factories\GuildFactory; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; @@ -70,4 +71,12 @@ public function members(): BelongsToMany ->using(GuildMember::class) ->withPivot('role'); } + + public function isUserAdminInGuild(int $user_id): bool + { + return $this->members() + ->where('user_id', $user_id) + ->where('role', Role::Admin) + ->exists(); + } } diff --git a/app/Services/ChannelService.php b/app/Services/ChannelService.php index 105392d..0850ecb 100644 --- a/app/Services/ChannelService.php +++ b/app/Services/ChannelService.php @@ -12,6 +12,7 @@ use App\Models\Guild; use App\Models\GuildMember; use App\Models\User; +use Illuminate\Support\Facades\Gate; class ChannelService implements IChannelService { @@ -20,7 +21,8 @@ class ChannelService implements IChannelService */ public function upsertChannel(array $data, Guild $guild, Channel $channel = null): ChannelResource { - $this->checkPermissions($guild->id, auth()->id()); + if(!Gate::authorize('manageChannels', $guild)) + throw ChannelException::dontHaveManagerPermission(); $channel = Channel::updateOrCreate([ 'id' => $channel?->id, @@ -35,7 +37,8 @@ public function upsertChannel(array $data, Guild $guild, Channel $channel = null */ public function deleteChannel(Guild $guild, Channel $channel): void { - $this->checkPermissions($guild->id, auth()->id()); + if(!Gate::authorize('manageChannels', $guild)) + throw ChannelException::dontHaveManagerPermission(); $channel->delete(); } @@ -59,15 +62,4 @@ public function joinChannel(Guild $guild, Channel $channel): void event(new UserJoinedChannel($channel->id, $user)); } - - /** - * @throws ChannelException - */ - private function checkPermissions(int $guild_id, int $user_id): void - { - $guild_member = GuildMember::where('user_id', $user_id)->where('guild_id', $guild_id)->first(); - if (! $guild_member || ($guild_member->role !== Role::Admin->value && $guild_member->role !== Role::Moderator->value)) { - throw ChannelException::dontHaveManagerPermission(); - } - } } diff --git a/app/Services/GuildService.php b/app/Services/GuildService.php index d7cb123..01147c7 100644 --- a/app/Services/GuildService.php +++ b/app/Services/GuildService.php @@ -8,8 +8,8 @@ use App\Http\Resources\GuildResource; use App\Interfaces\Services\IGuildService; use App\Models\Guild; -use App\Models\GuildMember; use Illuminate\Http\Resources\Json\AnonymousResourceCollection; +use Illuminate\Support\Facades\Gate; use Throwable; use Illuminate\Support\Str; @@ -41,11 +41,7 @@ public function getUserGuilds(): AnonymousResourceCollection */ public function getGuild(Guild $guild): GuildDetailedResource { - $guild = Guild::where('id', $guild->id)->whereHas('members', function ($query) { - $query->where('user_id', auth()->id()); - })->first(); - - if (! $guild) { + if (!Gate::authorize('view', $guild)) { throw GuildException::notAGuildMemberException(); } @@ -69,11 +65,7 @@ public function upsertGuild(array $data, Guild $guild = null): GuildResource */ public function getInviteCode(Guild $guild): string { - $guild_member = GuildMember::where('user_id', auth()->id()) - ->where('guild_id', $guild->id) - ->first(); - - if (! $guild_member) { + if (!Gate::authorize('view', $guild)) { throw GuildException::notAGuildMemberException(); } @@ -111,7 +103,8 @@ private function create(array $data): GuildResource */ private function update(Guild $guild, array $data): GuildResource { - $this->checkManagerPermission($guild->id, auth()->id()); + if(!Gate::authorize('updateOrDelete', $guild)) + throw GuildException::dontHaveManagerPermission(); $guild->update($data); @@ -123,7 +116,8 @@ private function update(Guild $guild, array $data): GuildResource */ public function delete(Guild $guild): void { - $this->checkManagerPermission($guild->id, auth()->id()); + if(!Gate::authorize('updateOrDelete', $guild)) + throw GuildException::dontHaveManagerPermission(); $guild->delete(); } @@ -133,33 +127,14 @@ public function delete(Guild $guild): void */ public function leaveGuild(Guild $guild): void { - if (! $guild->members()->wherePivot('user_id', auth()->id())->exists()) { + if (!$guild->members()->wherePivot('user_id', auth()->id())->exists()) { throw GuildException::notAGuildMemberException(); } - if ($this->checkRequestUserIsAdmin($guild)) { + if ($guild->isUserAdminInGuild(auth()->id())) { throw GuildException::adminCannotLeave(); } $guild->members()->detach(auth()->id()); } - - /** - * @throws GuildException - */ - private function checkManagerPermission(int $guild_id, int $user_id): void - { - $guild_member = GuildMember::where('user_id', $user_id)->where('guild_id', $guild_id)->first(); - - if (! $guild_member || $guild_member->role !== Role::Admin->value) { - throw GuildException::dontHaveManagerPermission(); - } - } - - private function checkRequestUserIsAdmin(Guild $guild): bool - { - $guildMember = $guild->members()->wherePivot('user_id', auth()->id())->first(); - - return $guildMember && $guildMember->pivot->role === Role::Admin->value; - } }