Roly a oprávnenia
Skupinové vlákna nesú roly pre každého účastníka — owner, admin, member (RoundlyConsulting\Messages\Enums\ParticipantRole). Kto vlákno založí, je jeho vlastníkom; každý neskôr pridaný sa stane členom, pokiaľ neodovzdáte rolu. Vlastníci a administrátori smú pridávať a odoberať účastníkov, premenovať a archivovať vlákno a moderovať správy kohokoľvek; členovia spravujú len vlastné správy. Roly mení výlučne vlastník — administrátor môže pridávať členov, no nikoho nepovýši na administrátora a inému administrátorovi rolu nezníži. Odobrať niekoho si vyžaduje rolu vyššiu, než má on: vlastník odoberá administrátorov a členov, administrátor len členov — nikdy iného administrátora ani vlastníka.
use RoundlyConsulting\Messages\Enums\ParticipantRole;
use RoundlyConsulting\Messages\Facades\Messages;
$thread->roleOf($bob); // ParticipantRole::Member|Admin|Owner|null
$thread->canManage($bob); // bool
$participants = Messages::thread($thread)->participants();
$participants->setRole($bob, ParticipantRole::Admin, by: $alice);
$participants->transferOwnership(from: $alice, to: $bob); // $alice is demoted to adminVlastníctvo
Vlastníctvo sa presúva výlučne cez transferOwnership() a len od vlastníka; doterajší vlastník sa zníži na administrátora, takže mu zostanú práva na správu. Platí to pre každého volajúceho, aj dôveryhodného, a aj pri vypnutých rolách. Každé odmietnutie vyhodí ParticipationException:
- setRole() nikdy neudelí rolu vlastníka ani nezmení rolu vlastníka a add() nikdy nevytvorí druhého vlastníka — ownershipOnlyByTransfer().
- transferOwnership(from: …) odmietne from, ktorý nie je vlastníkom — notTheOwner().
- Vlastník nemôže odísť ani byť odobratý, kým je vo vlákne ešte niekto iný — ownerMustTransferFirst(). Najprv odovzdajte vlastníctvo; posledný účastník môže jednoducho odísť.
- Skupinové vlákno nikdy nezostane bez vlastníka: keď vlastník odíde ako posledný — alebo vlákno vzniklo bez účastníkov — ďalší účastník, ktorý sa pridá sám alebo ho niekto pridá, sa stane jeho vlastníkom bez ohľadu na požadovanú rolu. Odobratie účastníka berie rovnaký zámok vlákna ako pridanie, takže ani pridanie súbežné s odchodom vlastníka nenechá vlákno bez vlastníka.
Kto smie čo
| Operácia | Kto smie (skupinové vlákna) | Volanie |
|---|---|---|
| Pridať účastníkov | vlastník, administrátor — rola vyššia než člen vyžaduje vlastníka | participants()->add(…, by:) |
| Pridať sa sám | ktokoľvek, len do vlákna otvoreného pre všetkých | joinThread() / participants()->add($x, by: $x) |
| Odobrať niekoho iného | rola vyššia než jeho — vlastník odoberá administrátorov a členov, administrátor len členov | participants()->remove(…, by:) |
| Opustiť vlákno | ktokoľvek sám za seba — vlastník až po odovzdaní vlastníctva (alebo ako posledný vo vlákne) | participants()->leave() |
| Zmeniť roly | len vlastník | participants()->setRole(…, by:) |
| Premenovať | vlastník, administrátor | thread()->rename(…, by:) |
| Archivovať | vlastník, administrátor | thread()->archive(by:) |
| Upraviť správu | len jej autor — bez ohľadu na nastavenie rolí | message()->edit(…, by:) |
| Zrušiť odoslanie správy | jej autor; vlastník alebo administrátor pri cudzej | message()->delete(by:) |
| Previesť vlastníctvo | len vlastník — from: musí byť vlastník, pre každého volajúceho | participants()->transferOwnership() |
| Poslať správu | ktorýkoľvek aktuálny účastník | to()->from()->send() — withoutParticipationCheck() kontrolu vypne |
Správu smie upraviť len jej autor — ani vlastník či administrátor, a to bez ohľadu na messages.permissions.enabled.
Vynucovanie
Vynucovanie rolí je predvolene zapnuté cez messages.permissions.enabled (true) a pri priamych vláknach, ktoré sú vždy bez rolí, sa preskakuje: tam, rovnako ako pri vypnutých rolách, je každý účastník rovnocenný a smie vlákno spravovať. Vypnutím vynucovania sa roly prestanú kontrolovať, nie zaznamenávať — skupinové vlákno stále dostane vlastníka a členov, takže po neskoršom zapnutí má každé vlákno roly a jeho vlastník ho môže spravovať. Priame vlákno nemá roly vôbec: setRole() aj transferOwnership() na ňom vyhodia ParticipationException.
Vykonávateľ (actor) však musí byť vždy účastníkom — bez ohľadu na konfiguráciu a typ vlákna nemôže ten, kto vo vlákne nie je (alebo ho opustil), do vlákna písať, premenovať ho, archivovať, spravovať jeho účastníkov ani v ňom upravovať či mazať správy, ani svoje vlastné.
Kontroly oprávnení nikdy neodpovedajú zo zastaraného vzťahu. Thread::participationOf() pri už načítanom vzťahu participants ignoruje mäkko zmazané záznamy a add(), remove(), setRole() aj transferOwnership() načítaný vzťah z inštancie vlákna zahodia — kto bol práve odobratý, degradovaný alebo už nie je vlastníkom, tak na základe starej odpovede nemôže vlákno premenovať, archivovať ani meniť roly.
Ak je vykonávateľ odmietnutý, volanie vyhodí typovanú RoundlyConsulting\Messages\Exceptions\UnauthorizedMessagingAction. Bez by: sa kontrola rolí preskočí, takže dôveryhodný serverový kód funguje bez zmeny; odosielateľ sa kontroluje vždy, pokiaľ nezavoláte withoutParticipationCheck():
use RoundlyConsulting\Messages\Exceptions\UnauthorizedMessagingAction;
use RoundlyConsulting\Messages\Facades\Messages;
try {
Messages::thread($thread)->rename('Renamed', by: $carol); // $carol is a member
} catch (UnauthorizedMessagingAction $e) {
// "[App\Models\User:3] requires the admin role to rename the thread."
}
// No actor = trusted server-side code: the role check is skipped
Messages::thread($thread)->rename('Renamed by a job');Pri vypnutom vynucovaní canManage() vráti true pre každého účastníka — a false pre každého, kto vo vlákne nie je.
Premenovanie a archivácia
Premenovanie a archivácia idú cez handle vlákna:
use RoundlyConsulting\Messages\Facades\Messages;
Messages::thread($thread)->rename('New name', by: $alice);
Messages::thread($thread)->archive(by: $alice);
$thread->isArchived(); // trueRenameThread spustí ThreadRenamed s pôvodným názvom; ArchiveThread nastaví archived_at a raz spustí ThreadArchived. Archivácia neblokuje nové správy — archivované vlákna filtrujte alebo strážte vo svojej aplikácii.
Pomocníci enumov
ParticipantRole aj MessageType používajú trait Helpers z enums-for-laravel, takže oba ponúkajú čitateľné popisky, zoznamy možností pre selecty a validačné pravidlo, ktoré sa nerozíde s enumom:
use RoundlyConsulting\Messages\Enums\ParticipantRole;
ParticipantRole::labels(); // ['Owner', 'Admin', 'Member']
ParticipantRole::toOptions(); // ['owner' => 'Owner', 'admin' => 'Admin', 'member' => 'Member']
ParticipantRole::options(); // Collection<EnumOption{ value, label, name }> for JS/Inertia selects
ParticipantRole::validationRule(); // 'in:owner,admin,member'
ParticipantRole::Owner->label(); // 'Owner'Enum rolí má aj doménové metódy:
ParticipantRole::Admin->canManage(); // true — owner or admin
ParticipantRole::Owner->isOwner(); // true
ParticipantRole::Owner->outranks(ParticipantRole::Admin); // truePrejavte 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.