---
title: "Priradenia v rozsahu a s časovým oknom — Permissions | Roundly"
description: "Udeľujte roly a oprávnenia len v rámci jedného projektu, tímu či tenanta alebo len na čas — kontroly naprieč rozsahmi vrátane Gate a middleware."
url: https://roundly-consulting.com/sk/open-source/navody/permissions-for-laravel/priradenia-v-rozsahu
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Permissions for Laravel](https://roundly-consulting.com/sk/open-source/navody/permissions-for-laravel.md)

# Priradenia v rozsahu a s časovým oknom

Od verzie 2.1 môže rola alebo priame oprávnenie platiť len v rámci rozsahu — ľubovoľného Eloquent modelu: projektu, tímu, tenanta — a len medzi dvoma okamihmi. Funkciu zapína permissions.assignments.enabled; pri vypnutej posiela balík presne tie isté dopyty ako 2.0. Rozsah aj okno určíte na tom istom handli Permissions::for():

```php
use RoundlyConsulting\Permissions\Facades\Permissions;

// Writes — exactly one scope, an optional window
Permissions::for($user)->in($project)->assignRole('editor', 'reviewer');
Permissions::for($user)->in($tenant)->until(now()->addWeek())->assignRole('admin');
Permissions::for($user)->between($from, $until)->givePermissionTo('reports.export'); // unscoped, time-boxed

// Checks — one scope or several (any of them)
Permissions::for($user)->in($project)->hasPermissionTo('posts.edit');   // bool
Permissions::for($user)->in([$team, $parentTeam])->hasRole('editor');   // bool
$user->can('posts.edit', Permissions::scope($project));                  // through the Gate
```

## Zapnutie

Publikujte a spustite tri migrácie z verzie 2.1 a potom zapnite prepínač — postup prechodu nájdete v Inštalácii, scope\_key\_type a global\_applies\_in\_scope v Konfigurácii:

```bash
php artisan vendor:publish --tag="permissions-migrations"
php artisan migrate
```

```bash
# Only when your scope models key differently from your holders — before migrating
PERMISSIONS_SCOPE_KEY_TYPE=ulid

# After the 2.1 migrations ran
PERMISSIONS_ASSIGNMENTS=true
```

php artisan about potom zobrazí Assignments … ON s typom kľúča rozsahov a s tým, či globálne priradenia platia v rozsahoch. Kým je prepínač vypnutý, každé volanie in(), from(), until(), between(), at(), scope(), owner(), forgetScope() a pruneExpired() vyhodí PermissionException.

## Pravidlá

- Rozsah — priradenie v rozsahu platí len pre kontrolu v tom istom rozsahu, porovnáva sa morph trieda aj kľúč: Team #1 a Project #1 sú rôzne rozsahy. Nikdy nesplní kontrolu bez rozsahu, ako je $user->hasPermissionTo() či $user->can('x').
- Globálne v rozsahu — priradenie bez rozsahu, či už z 2.0, alebo časovo obmedzené bez rozsahu, platí v každom rozsahu, kým je global\_applies\_in\_scope zapnuté.
- Okno — valid\_from platí vrátane, valid\_until bez neho, obe v UTC na sekundy. Teraz znamená Date::now()->utc(), takže travelTo() a Date::setTestNow() ho v testoch posunú.
- Viac okien — tá istá rola v tom istom rozsahu s iným oknom je samostatný riadok a držiteľ rolu má, kedykoľvek je otvorené ktorékoľvek z nich. To isté priradenie dvakrát je jeden riadok.
- Kontroly prijmú viac rozsahov a stačí ktorýkoľvek z nich — napríklad tím a jeho nadradené tímy. Zápisy prijmú práve jeden. Prázdny zoznam vyhodí výnimku, nikdy sa nečíta ako „bez rozsahu“; na to slúži in(null).
- Držitelia — priradenia majú len modely s HasRoles; Permissions::for($role)->in() vyhodí výnimku, pretože Role drží len oprávnenia.

## Čítanie v rozsahu

Čítacie metódy handlu odpovedajú v jeho rozsahoch k jeho času kontroly — at() tento okamih posunie. Bez in() čítajú bez rozsahu a fungujú aj pri vypnutom prepínači, vtedy len nad priradeniami z 2.0:

```php
$grants = Permissions::for($user)->in($project);

$grants->hasRole('editor');                  // any of the given roles
$grants->hasAnyRole('editor', 'reviewer');   // the same, variadic
$grants->hasPermissionTo('posts.edit');      // directly or through a role
$grants->roleNames();                        // Collection<int, string>
$grants->permissionNames();                  // Collection<int, string>
$grants->assignments();                      // Collection<int, Assignment>

$grants->at(now()->addWeek())->hasRole('editor'); // as of next week
```

assignments() vypíše všetko ako objekty Assignment — na handli bez rozsahu priradenia z 2.0 (ako trvalé, bez rozsahu) aj všetky rozsahy, s in() len tieto rozsahy. Je to živý dopyt s načítaným rozsahom pri každom riadku a jeho serializácia nenesie žiadny názov triedy:

```php
foreach (Permissions::for($user)->assignments() as $assignment) {
    $assignment->kind;        // AssignmentKind::Role or AssignmentKind::Permission
    $assignment->name;        // 'editor'
    $assignment->scope;       // ?Model — null when unscoped, or when the scope no longer exists
    $assignment->validFrom;   // ?CarbonImmutable, UTC, inclusive
    $assignment->validUntil;  // ?CarbonImmutable, UTC, exclusive
    $assignment->isActive;    // bool, at the handle's check time
}
```

## Zápis v rozsahu

Slovesá z 2.0 sa riadia tým, čo handle nesie. Bez rozsahu a okna idú cestou 2.0. S oknom a bez rozsahu zapíšu riadky priradení bez rozsahu. S rozsahom zapisujú — či odoberajú — len riadky tohto rozsahu:

```php
// The complete role set of this project — other scopes are untouched
Permissions::for($user)->in($project)->syncRoles(['viewer']);

// Every window of the role in this project
Permissions::for($user)->in($project)->removeRole('editor');

// Everything the holder has in this project
Permissions::for($user)->in($project)->forgetAllAuthorization();
```

- syncRoles() a syncPermissions() v rozsahu spravia zo zadanej množiny úplnú množinu tohto rozsahu: v jednej transakcii so zámkom na riadku držiteľa zmiznú všetky riadky v presne tomto rozsahu, ktoré nie sú cieľom — tá istá rola a okno — a potom sa ciele zapíšu. Súbežné synchronizácie jedného držiteľa idú za sebou a prežije množina práve jedného volajúceho.
- Synchronizácia s oknom bez rozsahu je úplná množina bez rozsahu, preto odpojí aj roly či oprávnenia držiteľa z 2.0.
- removeRole() v rozsahu odstráni všetky okná roly v ňom; názov vyčistí každú rolu, ktorú v tom rozsahu môže znamenať — vlastnú rolu rozsahu aj globálnu. Odoberanie sa riadi len rozsahom: odobratie bez rozsahu vyčistí všetky okná.
- Aditívne zápisy sú upserty podľa odtlačku držiteľa, roly či oprávnenia, rozsahu a okna, takže rovnaké súbežné zápisy nechajú jeden riadok a iné okná pridajú riadky.
- Okno, ktorého koniec nie je po začiatku, alebo ktoré už skončilo, vyhodí PermissionException — úplne minulé okno by neudelilo nič.

## Slovesá z 2.0 pri zapnutých priradeniach

Bez rozsahu siahajú známe slovesá aj na nové riadky, takže držiteľovi nikdy nezostane priradenie, ktoré ste mu chceli odobrať:

- hasRole(), hasPermissionTo() aj Gate započítajú aj časovo obmedzené priradenia bez rozsahu, kým je ich okno otvorené.
- syncRoles() a syncPermissions() zmažú aj riadky priradení držiteľa bez rozsahu; riadky v rozsahu patria synchronizácii svojho rozsahu.
- removeRole() a revokePermissionTo() zmažú aj riadky priradení držiteľa bez rozsahu s týmito názvami, všetky okná.
- forgetAllAuthorization() zmaže aj všetky priradenia držiteľa vo všetkých rozsahoch — je to sloveso na úplné odstránenie. Pre jeden rozsah ho zavolajte na Permissions::for($holder)->in($scope).
- Relácie roles a permissions, getRoleNames(), getDirectPermissions() aj getAllPermissions() naďalej vypisujú len priradenia z 2.0 — úplný obraz dajú assignments(), roleNames() a permissionNames() na handli.

## Na modeli

HasRoles pridáva skratky pre rozsahy. roleIn() započíta aj riadky bez rozsahu a roly z 2.0, kým je global\_applies\_in\_scope zapnuté:

```php
$user->hasRoleIn($project, 'editor');                    // = Permissions::for($user)->in($project)->hasRole('editor')
$user->hasPermissionIn([$team, $parent], 'posts.edit');  // any of the scopes
User::query()->roleIn($project, 'editor')->get();        // query scope, window checked at the current UTC time
```

## Keď sa rozsah zmaže

Rozsahy sú polymorfné, preto sa ich riadky nemôžu kaskádovo zmazať. Volajte Permissions::forgetScope() z hooku deleting každého modelu rozsahu — zmaže všetky priradenia v rozsahu aj všetky roly, ktoré vlastní, a vráti ich počet:

```php
use Illuminate\Database\Eloquent\Model;
use RoundlyConsulting\Permissions\Facades\Permissions;

class Project extends Model
{
    protected static function booted(): void
    {
        static::deleting(fn (self $project) => Permissions::forgetScope($project));
    }
}
```

## Prečistenie skončených okien

Skončené okno neudeľuje nič, takže prečistenie je len hygiena tabuliek, nikdy otázka správnosti. Permissions::pruneExpired() zmaže riadky, ktorých okno skončilo do zadaného okamihu — predvolene teraz:

```php
use RoundlyConsulting\Permissions\Facades\Permissions;

Permissions::pruneExpired();                     // int — rows whose window ended by now
Permissions::pruneExpired(now()->subDays(30));   // keep 30 days of history
```

```bash
php artisan permissions:prune-expired                    # every row whose window has ended
php artisan permissions:prune-expired --after="30 days"  # keep rows that ended less than 30 days ago
```

Hodnota --after, ktorá nie je kladná dĺžka trvania, skončí kódom 2. Udalosti o blížiacej sa expirácii balík nemá — potrebovali by vlastné pravidelné prehľadávanie.

## Cache

Riadky priradení si drží memo každého procesu podľa držiteľa, a to aj s oknami — nikdy ako áno či nie —, takže každá kontrola filtruje podľa hodín a dlho bežiaci worker nikdy nepoužije expirované priradenie. Memo sa vyprázdni pre držiteľa pri každom zápise a celé pri každom requeste, úlohe a ticku v Octane, pri každom jobe vo fronte, pri Permissions::cache()->flushMemo() a pri každom rollbacku transakcie. Medzi procesmi sa nič nezdieľa: priradenie zapísané iným procesom sa prejaví od nasledujúceho requestu či jobu. Zdieľaná cache katalógu sa nemení a roly — s vlastníkom či bez — do nej nikdy nevstupujú.

## Stavanie nad touto funkciou

Pre balík či modul, ktorý overuje priradenia pre tím alebo projekt, je stabilné toto API: Permissions::for($member)->in($scopes)->hasPermissionTo() a hasRole() s viacerými rozsahmi, resolveScopeUsing() pre implicitný rozsah, in($scope)->forgetAllAuthorization() pri skončení členstva, forgetScope() pri zmazaní rozsahu, owner() pre roly definované rozsahom a Permissions::scope() pre volania Gate. Najprv overte PermissionRegistrar::assignmentsEnabled() — pri vypnutom prepínači tieto volania vyhodia výnimku. Presne takto je postavený most k permissions v [teams-for-laravel](https://roundly-consulting.com/sk/open-source/navody/teams-for-laravel.md).

## 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 kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## 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.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/permissions-for-laravel.md)
