Most k permissions
Členstvo nesie jednu rolu. Ak potrebujete viac — niekoľko rolí pre člena v tíme, rolu platnú do piatku, priame oprávnenie pre jedného člena, roly, ktoré si tím definuje sám —, nainštalujte permissions-for-laravel a zapnite most. Teams tento balík len odporúča, nikdy ho nevyžaduje, a kým most nezapnete, nič sa nemení. team_members.role zostáva rolou členstva; ďalšie, jemnejšie a časovo obmedzené priradenia pochádzajú z permissions-for-laravel a platia v rozsahu tímu.
Zapnutie
composer require roundly-consulting/permissions-for-laravel
php artisan vendor:publish --tag="permissions-migrations"
php artisan migratePERMISSIONS_SCOPE_KEY_TYPE=ulid # only when teams key differently from users — before migrating
PERMISSIONS_ASSIGNMENTS=true
TEAMS_PERMISSIONS_BRIDGE=trueMost potrebuje permissions-for-laravel 2.1 alebo novší — so staršími verziami teams deklaruje konflikt — so zapnutými priradeniami v rozsahu. Ak majú vaše tímy iný typ kľúča ako používatelia, najprv nastavte typ kľúča rozsahov. Potom pridajte modelu používateľa trait HasRoles z permissions popri HasTeams:
use Illuminate\Foundation\Auth\User as Authenticatable;
use RoundlyConsulting\Permissions\Concerns\HasRoles;
use RoundlyConsulting\Teams\Traits\HasTeams;
class User extends Authenticatable
{
use HasRoles; // permissions-for-laravel
use HasTeams;
}Ak je prepínač zapnutý, no balík chýba alebo je permissions.assignments.enabled vypnuté, aplikácia pri štarte zlyhá s InvalidConfigurationException, ktorá pomenuje, čo chýba — zapnutý prepínač, ktorý potichu nerobí nič, by bol horší. php artisan about zobrazí Permissions bridge ON alebo OFF.
Priradenia v rámci tímu
members()->grant($member) je skratka pre Permissions::for($member)->in($team) s dvoma pravidlami tímu:
use RoundlyConsulting\Teams\Facades\Teams;
Teams::for($team)->members()->grant($user)->assignRole('reviewer');
Teams::for($team)->members()->grant($user)->until($friday)->givePermissionTo('reports.export');
Teams::for($team)->members()->grant($user)->syncRoles(['reviewer', 'editor']); // the complete set in this team
Teams::for($team)->members()->grant($user)->removeRole('editor');
Teams::for($team)->members()->grant($user)->forgetAllAuthorization(); // everything in this team
Teams::for($team)->members()->grant($user)->hasPermissionTo('reports.export'); // bool
Teams::for($team)->members()->grant($user)->assignments(); // the member's rows in this team- Len členovia — pridanie (assignRole, givePermissionTo, syncRoles, syncPermissions) potrebuje aktuálne alebo naplánované členstvo v tomto tíme; nečlen, člen iného tímu či člen s vypršaným členstvom vyhodí MemberNotFoundException. Odoberanie funguje pre kohokoľvek, takže vyčistiť priradenia toho, kto odchádza, je vždy bezpečné.
- Predvoleným koncom je expirácia členstva — bez until() sa pridanie skončí spolu s členstvom. until($date) nastaví iný koniec, until(null) žiadny; from() a between() nastavia začiatok.
- syncRoles() a syncPermissions() nastavia úplnú množinu v tomto tíme; odobratie vyčistí všetky okná.
- Prijme názvy, backed enumy, modely Role a Permission aj zoznamy — čokoľvek, čo prijme permissions-for-laravel. Zápis priamo cez Permissions::for($user)->in($team) funguje tiež: most číta, čo tam je, a grant() pridáva len pravidlá členstva a záznam pre Teams::fake().
Kým je most vypnutý, grant() vyhodí TeamsException. Cez injektovaný manager alebo priamo akciou vyzerá ten istý zápis takto:
use RoundlyConsulting\Teams\Bridges\Permissions\Actions\GrantMemberAuthorizationAction;
use RoundlyConsulting\Teams\Bridges\Permissions\DataTransferObjects\GrantMemberAuthorizationData;
use RoundlyConsulting\Teams\Bridges\Permissions\Enums\MemberGrant;
// Injected manager — the same API as the facade
$this->teams->for($team)->members()->grant($user)->assignRole('reviewer');
// The raw action
app(GrantMemberAuthorizationAction::class)->execute($team, new GrantMemberAuthorizationData(
member: $user,
verb: MemberGrant::AssignRole,
items: ['reviewer'],
));Čo vidia kontroly
Pri zapnutom moste odpovedia memberHasPermission() a memberHasRole() true, ak to udeľuje rola členstva — ako doteraz —, alebo ak to v tíme udeľuje permissions-for-laravel. Zjednotenie zdedí všetko, čo na nich stavia: hasTeamPermission() a hasTeamRole(), ability teams.<oprávnenie> v Gate, @teamPermission a @teamRole aj AbstractTeamPolicy:
$team->memberHasPermission($user, 'reports.export'); // the membership role OR a grant in the team
$user->can('teams.reports.export', $team); // the same, through the Gate
Route::middleware(['auth', 'teams.context', 'can:posts.edit'])
->put('/teams/{team}/posts/{post}', UpdatePost::class); // resolved in the current team- Overuje sa v čase kontroly — expirované, ešte nezačaté či odobraté členstvo okamžite znefunkční priradenia svojho tímu, ešte pred akýmkoľvek upratovaním.
- Názvy sa zhodujú — teams.posts.edit sa pýta na oprávnenie posts.edit a memberHasRole($u, 'reviewer') na rolu reviewer. Katalógy oboch balíkov sú oddelené; názvy registrujte tam, kde ich udeľujete.
- Globálne priradenia — priradenie z permissions-for-laravel bez rozsahu platí v každom tíme, kde je používateľ aktívnym členom, kým je permissions.assignments.global_applies_in_scope zapnuté (predvolene áno). Prísne multi-tenant aplikácie ho vypnú.
- Vnorené tímy — pri inherit_roles_down platí priradenie v nadradenom tíme aj v tímoch pod ním, a to pre člena toho nadradeného tímu. Smerom nahor sa priradenie nikdy nešíri.
- Priradenie v tíme nikdy nesplní kontrolu bez rozsahu, ako je $user->can('posts.edit') bez tímu — okrem implicitného rozsahu nižšie. Používatelia bez HasRoles dostanú len odpoveď podľa roly členstva a teamsWithRole() aj teamRole() naďalej čítajú len rolu členstva.
Aktuálny tím ako implicitný rozsah
Most zaregistruje Permissions::resolveScopeUsing(), takže kontroly cez Gate bez rozsahu — middleware can:, @can('posts.edit'), $user->can('posts.edit') — sa vyhodnotia v aktuálnom tíme (nastavenom middlewarom teams.context alebo cez Teams::switchTo()) a pri dedení rolí aj v tímoch nad ním, a to len pre aktívnych členov. Bez aktuálneho tímu, v režime viacerých tímov alebo pre nečlena zostane kontrola bez rozsahu. Váš vlastný resolveScopeUsing() v service provideri ho nahradí, pretože providery aplikácie štartujú po provideroch balíkov.
Upratovanie
- Člen je odobratý (TeamMemberDeleted) alebo sa odstráni expirované členstvo (MembershipExpired) — priradenia člena v tíme sa zabudnú.
- Vypršané členstvo sa znova pridá — to isté, pretože obnovené členstvo začína odznova a staré priradenia sa nesmú vrátiť. Priradenia urobené pred úplne novým členstvom zostanú.
- Tím sa natrvalo zmaže — Permissions::forgetScope($team) odstráni jeho priradenia aj roly, ktoré vlastní. Mäkko zmazaný tím si ich ponechá, pretože ho možno obnoviť.
Nič z toho nie je potrebné pre správnosť — kontroly neaktívne členstvá ignorujú už samy —, udržiava to však tabuľky čisté a vracajúci sa člen nezdedí staré priradenia.
Roly definované tímom
Pre roly, ktoré si tím definuje sám, použite roly s vlastníkom z permissions-for-laravel — v rozsahu tímu má vlastná rola tímu prednosť pred globálnou s rovnakým názvom. Je to alternatíva k rolám upraveným pre konkrétny tím; tieto dva mechanizmy sa nezlučujú:
use RoundlyConsulting\Permissions\Facades\Permissions;
Permissions::owner($team)->role('auditor')->givePermissionTo('reports.view');
Teams::for($team)->members()->grant($user)->assignRole('auditor'); // the team's own auditorTestovanie
Teams::fake() zaznamená každý zápis cez grant() ako GrantMemberAuthorization alebo RevokeMemberAuthorization s tímom, členom, slovesom a názvami; Permissions::fake() vidí aj samotný zápis v rozsahu:
$fake = Teams::fake();
Teams::for($team)->members()->grant($user)->assignRole('reviewer');
$fake->assertMemberGranted($team, $user, 'reviewer');
$fake->assertNoGrantRevoked();
// Permissions::fake() sees the underlying scoped write as well:
// assertRoleAssigned($user, 'reviewer', scope: $team, until: $membershipExpiry)Bez mosta
Chcete si to prepojiť sami? Zjednotenie zaberie pár riadkov vo vlastnej gate či policy:
Gate::define('team-permission', fn (User $user, Team $team, string $permission): bool =>
$team->memberHasPermission($user, $permission)
|| ($team->hasActiveMember($user) && Permissions::for($user)->in($team)->hasPermissionTo($permission)));Prejavte lásku k open source
Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.
Ďalšie spôsoby podpory vrátane kryptomienOdoslaním daru súhlasíte s našimi podmienkami prijímania darov.
Chcete to zabudovať do svojho produktu?
Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.