* UnifiPageGrant::userCanAccess no longer falls back to "open" when a page has no grants saved. Pages now require an explicit grant for every non-super-admin user — either a direct user grant or via a group they belong to. Matches the new dashboard-wide access model. * Route enforcement returns 404 (was 403) so ungranted users can't even confirm the page exists. * New /settings/pages-access/groups/search endpoint mirrors the user typeahead. Groups are no longer all listed by default — only super-admin groups (locked-on) and groups with at least one existing grant show up in the matrix. Operators add more via search. v1.7.1. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
59 lines
1.7 KiB
PHP
59 lines
1.7 KiB
PHP
<?php
|
|
|
|
namespace Dashboard\Unifi\Models;
|
|
|
|
use App\Models\NavItem;
|
|
use App\Models\User;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
class UnifiPageGrant extends Model
|
|
{
|
|
protected $table = 'unifi_page_grants';
|
|
|
|
protected $fillable = [
|
|
'nav_item_id',
|
|
'grantee_type',
|
|
'grantee_id',
|
|
'granted_by_user_id',
|
|
];
|
|
|
|
public function navItem(): BelongsTo
|
|
{
|
|
return $this->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();
|
|
}
|
|
}
|