belongsTo(NavItem::class); } public function grantedBy(): BelongsTo { return $this->belongsTo(User::class, 'granted_by_user_id'); } /** * True iff $user is allowed to access $navItem under strict allowlist * semantics: * * super-admins (the model-level flag) always pass * * otherwise the user must be a direct grantee, OR be in a group * that is a grantee * * A page with NO grants saved is only visible to super-admins — * the admin must explicitly authorize everyone else via the * Access tab. */ public static function userCanAccess(User $user, NavItem $navItem): bool { if ($user->is_super_admin) return true; $groupIds = $user->groups()->pluck('groups.id'); return static::where('nav_item_id', $navItem->id) ->where(function ($q) use ($user, $groupIds) { $q->where(function ($u) use ($user) { $u->where('grantee_type', 'user')->where('grantee_id', $user->id); })->orWhere(function ($g) use ($groupIds) { $g->where('grantee_type', 'group')->whereIn('grantee_id', $groupIds); }); }) ->exists(); } }