Save workspace changes
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use Illuminate\Auth\Access\Response;
|
||||
use App\Models\ArtworkAward;
|
||||
use App\Models\Artwork;
|
||||
use App\Models\User;
|
||||
|
||||
class ArtworkAwardPolicy
|
||||
{
|
||||
/**
|
||||
* Admins bypass all checks.
|
||||
*/
|
||||
public function before(User $user, string $ability): ?bool
|
||||
{
|
||||
if (method_exists($user, 'isAdmin') && $user->isAdmin()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any authenticated user with a mature account may award any artwork
|
||||
* that isn't their own.
|
||||
* Returns false (→ 403 or 404 based on caller) when the check fails.
|
||||
*/
|
||||
public function award(User $user, Artwork $artwork): Response
|
||||
{
|
||||
if (! config('artwork_medals.enabled', true)) {
|
||||
return Response::deny('Artwork medals are currently disabled.');
|
||||
}
|
||||
|
||||
if (! $artwork->is_public || ! $artwork->is_approved) {
|
||||
return Response::deny('This artwork is not eligible for medals.');
|
||||
}
|
||||
|
||||
if ($artwork->deleted_at !== null) {
|
||||
return Response::deny('This artwork is no longer available for medals.');
|
||||
}
|
||||
|
||||
if ($artwork->published_at === null || $artwork->published_at->isFuture()) {
|
||||
return Response::deny('This artwork is not published yet.');
|
||||
}
|
||||
|
||||
if ($artwork->user_id === $user->id) {
|
||||
return Response::deny('You cannot medal your own artwork.');
|
||||
}
|
||||
|
||||
return $this->accountIsMature($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* The user may change a medal they already placed.
|
||||
*/
|
||||
public function change(User $user, ArtworkAward $award): bool
|
||||
{
|
||||
return $user->id === $award->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The user may remove a medal they already placed.
|
||||
*/
|
||||
public function remove(User $user, ArtworkAward $award): bool
|
||||
{
|
||||
return $user->id === $award->user_id;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
private function accountIsMature(User $user): Response
|
||||
{
|
||||
if ((bool) config('artwork_medals.require_verified_email', true)) {
|
||||
$isVerified = method_exists($user, 'hasVerifiedEmail')
|
||||
? $user->hasVerifiedEmail()
|
||||
: ! empty($user->email_verified_at);
|
||||
|
||||
if (! $isVerified) {
|
||||
return Response::deny('Verify your email address before giving medals.');
|
||||
}
|
||||
}
|
||||
|
||||
if (! $user->created_at) {
|
||||
return Response::allow(); // cannot verify — allow
|
||||
}
|
||||
|
||||
$minimumAgeHours = (int) config('artwork_medals.minimum_account_age_hours', 24);
|
||||
|
||||
if ($user->created_at->diffInHours(now()) < $minimumAgeHours) {
|
||||
return Response::deny("Your account must be at least {$minimumAgeHours} hours old before giving medals.");
|
||||
}
|
||||
|
||||
return Response::allow();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\ArtworkComment;
|
||||
use App\Models\User;
|
||||
|
||||
class ArtworkCommentPolicy
|
||||
{
|
||||
/**
|
||||
* Users can update their own comments.
|
||||
*/
|
||||
public function update(User $user, ArtworkComment $comment): bool
|
||||
{
|
||||
return $user->id === (int) $comment->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Users can delete their own comments; admins can delete any comment.
|
||||
*/
|
||||
public function delete(User $user, ArtworkComment $comment): bool
|
||||
{
|
||||
return $user->id === (int) $comment->user_id || $user->is_admin;
|
||||
}
|
||||
}
|
||||
137
.deploy/artwork-evolution-release/app/Policies/ArtworkPolicy.php
Normal file
137
.deploy/artwork-evolution-release/app/Policies/ArtworkPolicy.php
Normal file
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Artwork;
|
||||
use App\Models\User;
|
||||
|
||||
class ArtworkPolicy
|
||||
{
|
||||
/**
|
||||
* Global before hook: admins can do everything.
|
||||
* Accepts null $user to allow public checks to continue.
|
||||
*/
|
||||
public function before($user, $ability)
|
||||
{
|
||||
if (! $user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isAdmin($user)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function isAdmin(User $user): bool
|
||||
{
|
||||
if (isset($user->is_admin)) {
|
||||
return (bool) $user->is_admin;
|
||||
}
|
||||
|
||||
if (method_exists($user, 'isAdmin')) {
|
||||
return (bool) $user->isAdmin();
|
||||
}
|
||||
|
||||
if (method_exists($user, 'hasRole')) {
|
||||
return (bool) $user->hasRole('admin');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function isModerator(User $user): bool
|
||||
{
|
||||
foreach (['is_moderator', 'is_mod', 'moderator'] as $prop) {
|
||||
if (isset($user->{$prop})) {
|
||||
return (bool) $user->{$prop};
|
||||
}
|
||||
}
|
||||
|
||||
if (method_exists($user, 'hasRole')) {
|
||||
return (bool) ($user->hasRole('moderator') || $user->hasRole('mod'));
|
||||
}
|
||||
|
||||
if (method_exists($user, 'isModerator')) {
|
||||
return (bool) $user->isModerator();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public view: only approved + public + not-deleted artworks.
|
||||
*/
|
||||
public function view(?User $user, Artwork $artwork): bool
|
||||
{
|
||||
return $artwork->is_public && $artwork->is_approved && ! $artwork->trashed();
|
||||
}
|
||||
|
||||
/**
|
||||
* Any authenticated user can create artworks.
|
||||
*/
|
||||
public function create(?User $user): bool
|
||||
{
|
||||
return (bool) $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Owner can update their own artwork.
|
||||
*/
|
||||
public function update(User $user, Artwork $artwork): bool
|
||||
{
|
||||
if ((int) ($artwork->group_id ?? 0) > 0) {
|
||||
if ((int) $artwork->user_id === (int) $user->id && (string) ($artwork->artwork_status ?? '') === 'draft') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $artwork->group?->canPublishArtworks($user) ?? false;
|
||||
}
|
||||
|
||||
return $user->id === $artwork->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag edits: owner or moderator or admin (admin handled by before()).
|
||||
*/
|
||||
public function updateTags(User $user, Artwork $artwork): bool
|
||||
{
|
||||
return $user->id === $artwork->user_id || $this->isModerator($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Owner can delete their own artwork (soft delete).
|
||||
*/
|
||||
public function delete(User $user, Artwork $artwork): bool
|
||||
{
|
||||
if ((int) ($artwork->group_id ?? 0) > 0) {
|
||||
if ((int) $artwork->user_id === (int) $user->id && (string) ($artwork->artwork_status ?? '') === 'draft') {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $artwork->group?->canPublishArtworks($user) ?? false;
|
||||
}
|
||||
|
||||
return $user->id === $artwork->user_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore: owner or admin can restore soft-deleted artwork.
|
||||
*/
|
||||
public function restore(User $user, Artwork $artwork): bool
|
||||
{
|
||||
if ((int) ($artwork->group_id ?? 0) > 0) {
|
||||
return ($artwork->group?->canPublishArtworks($user) ?? false) || $this->isAdmin($user);
|
||||
}
|
||||
|
||||
return $user->id === $artwork->user_id || $this->isAdmin($user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Force delete reserved for admins only.
|
||||
*/
|
||||
public function forceDelete(User $user, Artwork $artwork): bool
|
||||
{
|
||||
return $this->isAdmin($user);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Collection;
|
||||
use App\Models\User;
|
||||
|
||||
class CollectionPolicy
|
||||
{
|
||||
public function before($user, $ability)
|
||||
{
|
||||
if (! $user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isAdmin($user)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function view(?User $user, Collection $collection): bool
|
||||
{
|
||||
if ($user && $collection->isOwnedBy($user)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $collection->isPubliclyAccessible();
|
||||
}
|
||||
|
||||
public function create(?User $user): bool
|
||||
{
|
||||
return (bool) $user;
|
||||
}
|
||||
|
||||
public function update(User $user, Collection $collection): bool
|
||||
{
|
||||
return $collection->canBeManagedBy($user);
|
||||
}
|
||||
|
||||
public function delete(User $user, Collection $collection): bool
|
||||
{
|
||||
if ((int) ($collection->group_id ?? 0) > 0) {
|
||||
return $collection->group?->canManageCollections($user) ?? false;
|
||||
}
|
||||
|
||||
return $collection->isOwnedBy($user);
|
||||
}
|
||||
|
||||
public function manageArtworks(User $user, Collection $collection): bool
|
||||
{
|
||||
return $collection->canManageArtworks($user);
|
||||
}
|
||||
|
||||
public function manageMembers(User $user, Collection $collection): bool
|
||||
{
|
||||
return $collection->canManageMembers($user);
|
||||
}
|
||||
|
||||
public function submit(User $user, Collection $collection): bool
|
||||
{
|
||||
return $collection->canReceiveSubmissionsFrom($user);
|
||||
}
|
||||
|
||||
public function comment(User $user, Collection $collection): bool
|
||||
{
|
||||
return $collection->canReceiveCommentsFrom($user);
|
||||
}
|
||||
|
||||
public function save(User $user, Collection $collection): bool
|
||||
{
|
||||
return $collection->canBeSavedBy($user);
|
||||
}
|
||||
|
||||
private function isAdmin(User $user): bool
|
||||
{
|
||||
if (method_exists($user, 'isAdmin')) {
|
||||
return (bool) $user->isAdmin();
|
||||
}
|
||||
|
||||
if (method_exists($user, 'hasRole')) {
|
||||
return (bool) $user->hasRole('admin');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Conversation;
|
||||
use App\Models\ConversationParticipant;
|
||||
use App\Models\User;
|
||||
|
||||
class ConversationPolicy
|
||||
{
|
||||
public function view(User $user, Conversation $conversation): bool
|
||||
{
|
||||
return $this->participantRecord($user, $conversation) !== null
|
||||
&& (bool) ($conversation->is_active ?? true);
|
||||
}
|
||||
|
||||
public function send(User $user, Conversation $conversation): bool
|
||||
{
|
||||
return $this->view($user, $conversation);
|
||||
}
|
||||
|
||||
public function manageParticipants(User $user, Conversation $conversation): bool
|
||||
{
|
||||
$participant = $this->participantRecord($user, $conversation);
|
||||
|
||||
return $participant !== null && $participant->role === 'admin';
|
||||
}
|
||||
|
||||
public function rename(User $user, Conversation $conversation): bool
|
||||
{
|
||||
return $conversation->isGroup() && $this->manageParticipants($user, $conversation);
|
||||
}
|
||||
|
||||
public function joinPresence(User $user, Conversation $conversation): bool
|
||||
{
|
||||
return $this->view($user, $conversation);
|
||||
}
|
||||
|
||||
private function participantRecord(User $user, Conversation $conversation): ?ConversationParticipant
|
||||
{
|
||||
return ConversationParticipant::query()
|
||||
->where('conversation_id', $conversation->id)
|
||||
->where('user_id', $user->id)
|
||||
->whereNull('left_at')
|
||||
->first();
|
||||
}
|
||||
}
|
||||
242
.deploy/artwork-evolution-release/app/Policies/GroupPolicy.php
Normal file
242
.deploy/artwork-evolution-release/app/Policies/GroupPolicy.php
Normal file
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Group;
|
||||
use App\Models\User;
|
||||
|
||||
class GroupPolicy
|
||||
{
|
||||
public function before($user, $ability)
|
||||
{
|
||||
if (! $user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isAdmin($user)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function view(?User $user, Group $group): bool
|
||||
{
|
||||
return $group->canBeViewedBy($user);
|
||||
}
|
||||
|
||||
public function create(?User $user): bool
|
||||
{
|
||||
return (bool) $user;
|
||||
}
|
||||
|
||||
public function update(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManage($user);
|
||||
}
|
||||
|
||||
public function delete(User $user, Group $group): bool
|
||||
{
|
||||
return $group->isOwnedBy($user);
|
||||
}
|
||||
|
||||
public function manageMembers(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageMembers($user);
|
||||
}
|
||||
|
||||
public function inviteMembers(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageMembers($user);
|
||||
}
|
||||
|
||||
public function changeRoles(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageMembers($user);
|
||||
}
|
||||
|
||||
public function archive(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canArchive($user);
|
||||
}
|
||||
|
||||
public function viewStudio(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canViewStudio($user);
|
||||
}
|
||||
|
||||
public function publishArtworks(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canPublishArtworks($user);
|
||||
}
|
||||
|
||||
public function manageCollections(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageCollections($user);
|
||||
}
|
||||
|
||||
public function requestJoin(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canRequestJoin($user);
|
||||
}
|
||||
|
||||
public function reviewJoinRequests(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canReviewJoinRequests($user);
|
||||
}
|
||||
|
||||
public function submitArtworkForReview(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canSubmitArtworkForReview($user);
|
||||
}
|
||||
|
||||
public function reviewSubmissions(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canReviewSubmissions($user);
|
||||
}
|
||||
|
||||
public function manageRecruitment(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageRecruitment($user);
|
||||
}
|
||||
|
||||
public function managePosts(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManagePosts($user);
|
||||
}
|
||||
|
||||
public function publishPosts(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canPublishPosts($user);
|
||||
}
|
||||
|
||||
public function pinPosts(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canPinPosts($user);
|
||||
}
|
||||
|
||||
public function manageMemberPermissions(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageMemberPermissions($user);
|
||||
}
|
||||
|
||||
public function manageEvents(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageEvents($user);
|
||||
}
|
||||
|
||||
public function manageChallenges(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageChallenges($user);
|
||||
}
|
||||
|
||||
public function manageProjects(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageProjects($user);
|
||||
}
|
||||
|
||||
public function manageReleases(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageReleases($user);
|
||||
}
|
||||
|
||||
public function publishReleases(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canPublishReleases($user);
|
||||
}
|
||||
|
||||
public function moveReleaseStage(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageReleases($user);
|
||||
}
|
||||
|
||||
public function manageMilestones(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageMilestones($user);
|
||||
}
|
||||
|
||||
public function viewReputationDashboard(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canViewReputationDashboard($user);
|
||||
}
|
||||
|
||||
public function manageBadges(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageBadges($user);
|
||||
}
|
||||
|
||||
public function viewInternalTrustMetrics(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canViewInternalTrustMetrics($user);
|
||||
}
|
||||
|
||||
public function featureRelease(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canFeatureReleases($user);
|
||||
}
|
||||
|
||||
public function assignReleaseLead(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canAssignReleaseLead($user);
|
||||
}
|
||||
|
||||
public function manageAssets(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canManageAssets($user);
|
||||
}
|
||||
|
||||
public function viewInternalAssets(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canViewInternalAssets($user);
|
||||
}
|
||||
|
||||
public function featureChallengeEntries(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canFeatureChallengeEntries($user);
|
||||
}
|
||||
|
||||
public function participateInChallenge(User $user, Group $group): bool
|
||||
{
|
||||
return $group->isOperational() && $group->canViewStudio($user);
|
||||
}
|
||||
|
||||
public function publishEventUpdates(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canPublishEventUpdates($user);
|
||||
}
|
||||
|
||||
public function attachAssetsToProjects(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canAttachAssetsToProjects($user);
|
||||
}
|
||||
|
||||
public function viewInternalEvents(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canViewStudio($user);
|
||||
}
|
||||
|
||||
public function viewPrivateProject(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canViewStudio($user);
|
||||
}
|
||||
|
||||
public function pinActivity(User $user, Group $group): bool
|
||||
{
|
||||
return $group->canPinActivity($user);
|
||||
}
|
||||
|
||||
private function isAdmin(User $user): bool
|
||||
{
|
||||
if (method_exists($user, 'isAdmin')) {
|
||||
return (bool) $user->isAdmin();
|
||||
}
|
||||
|
||||
if (method_exists($user, 'hasRole')) {
|
||||
return (bool) $user->hasRole('admin');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\ConversationParticipant;
|
||||
use App\Models\Message;
|
||||
use App\Models\User;
|
||||
|
||||
class MessagePolicy
|
||||
{
|
||||
public function view(User $user, Message $message): bool
|
||||
{
|
||||
return ConversationParticipant::query()
|
||||
->where('conversation_id', $message->conversation_id)
|
||||
->where('user_id', $user->id)
|
||||
->whereNull('left_at')
|
||||
->exists();
|
||||
}
|
||||
|
||||
public function update(User $user, Message $message): bool
|
||||
{
|
||||
return $message->sender_id === $user->id && $message->deleted_at === null;
|
||||
}
|
||||
|
||||
public function delete(User $user, Message $message): bool
|
||||
{
|
||||
return $message->sender_id === $user->id || $user->isAdmin();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\NovaCard;
|
||||
use App\Models\User;
|
||||
|
||||
class NovaCardPolicy
|
||||
{
|
||||
public function before($user, $ability)
|
||||
{
|
||||
if (! $user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->isAdmin($user)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function view(?User $user, NovaCard $card): bool
|
||||
{
|
||||
return $card->canBeViewedBy($user);
|
||||
}
|
||||
|
||||
public function create(?User $user): bool
|
||||
{
|
||||
return (bool) $user;
|
||||
}
|
||||
|
||||
public function update(User $user, NovaCard $card): bool
|
||||
{
|
||||
return $card->isOwnedBy($user) && in_array($card->status, [NovaCard::STATUS_DRAFT, NovaCard::STATUS_PROCESSING, NovaCard::STATUS_PUBLISHED], true);
|
||||
}
|
||||
|
||||
public function delete(User $user, NovaCard $card): bool
|
||||
{
|
||||
return $card->isOwnedBy($user);
|
||||
}
|
||||
|
||||
public function publish(User $user, NovaCard $card): bool
|
||||
{
|
||||
return $card->isOwnedBy($user);
|
||||
}
|
||||
|
||||
public function comment(User $user, NovaCard $card): bool
|
||||
{
|
||||
return $card->canReceiveCommentsFrom($user);
|
||||
}
|
||||
|
||||
public function allowExport(?User $user, NovaCard $card): bool
|
||||
{
|
||||
if ($card->isOwnedBy($user)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (bool) $card->allow_export;
|
||||
}
|
||||
|
||||
public function allowBackgroundReuse(?User $user, NovaCard $card): bool
|
||||
{
|
||||
if ($card->isOwnedBy($user)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (bool) $card->allow_background_reuse;
|
||||
}
|
||||
|
||||
public function moderate(User $user): bool
|
||||
{
|
||||
return $this->isModerator($user);
|
||||
}
|
||||
|
||||
private function isAdmin(User $user): bool
|
||||
{
|
||||
if (method_exists($user, 'isAdmin')) {
|
||||
return (bool) $user->isAdmin();
|
||||
}
|
||||
|
||||
if (method_exists($user, 'hasRole')) {
|
||||
return (bool) $user->hasRole('admin');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function isModerator(User $user): bool
|
||||
{
|
||||
if ($this->isAdmin($user)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (method_exists($user, 'isModerator')) {
|
||||
return (bool) $user->isModerator();
|
||||
}
|
||||
|
||||
if (method_exists($user, 'hasRole')) {
|
||||
return (bool) $user->hasRole('moderator');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\PostComment;
|
||||
use App\Models\User;
|
||||
|
||||
class PostCommentPolicy
|
||||
{
|
||||
public function delete(User $user, PostComment $comment): bool
|
||||
{
|
||||
return $user->id === $comment->user_id
|
||||
|| $user->isAdmin()
|
||||
|| $user->isModerator();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\Post;
|
||||
use App\Models\User;
|
||||
|
||||
class PostPolicy
|
||||
{
|
||||
/** Any authenticated user can create posts */
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Only the post author can update */
|
||||
public function update(User $user, Post $post): bool
|
||||
{
|
||||
return $user->id === $post->user_id;
|
||||
}
|
||||
|
||||
/** Author or admin/moderator can delete */
|
||||
public function delete(User $user, Post $post): bool
|
||||
{
|
||||
return $user->id === $post->user_id
|
||||
|| $user->isAdmin()
|
||||
|| $user->isModerator();
|
||||
}
|
||||
|
||||
/** Anyone can view public posts; followers-only requires following */
|
||||
public function view(?User $user, Post $post): bool
|
||||
{
|
||||
if ($post->visibility === Post::VISIBILITY_PUBLIC) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (! $user) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($user->id === $post->user_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($post->visibility === Post::VISIBILITY_FOLLOWERS) {
|
||||
return $post->user->isFollowedBy($user->id);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Only the author can report their own posts */
|
||||
public function report(User $user, Post $post): bool
|
||||
{
|
||||
return $user->id !== $post->user_id;
|
||||
}
|
||||
|
||||
/** Only the post owner can pin/unpin their own post */
|
||||
public function pin(User $user, Post $post): bool
|
||||
{
|
||||
return $user->id === $post->user_id;
|
||||
}
|
||||
|
||||
/** Any authenticated user can save a post (own or others') */
|
||||
public function save(User $user, Post $post): bool
|
||||
{
|
||||
return $post->status === Post::STATUS_PUBLISHED;
|
||||
}
|
||||
|
||||
/** Only post owner may highlight a comment */
|
||||
public function highlightComment(User $user, Post $post): bool
|
||||
{
|
||||
return $user->id === $post->user_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\World;
|
||||
|
||||
class WorldPolicy
|
||||
{
|
||||
public function view(?User $user, World $world): bool
|
||||
{
|
||||
if ($user && ($user->isAdmin() || $user->isModerator())) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $world->isPubliclyVisible();
|
||||
}
|
||||
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->isAdmin() || $user->isModerator();
|
||||
}
|
||||
|
||||
public function update(User $user, World $world): bool
|
||||
{
|
||||
return $user->isAdmin() || $user->isModerator();
|
||||
}
|
||||
|
||||
public function delete(User $user, World $world): bool
|
||||
{
|
||||
return $user->isAdmin() || $user->isModerator();
|
||||
}
|
||||
|
||||
public function manage(User $user): bool
|
||||
{
|
||||
return $user->isAdmin() || $user->isModerator();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user