Oprávnění a role#
Systém kontroluje u každého požadavku, zda smí daná identita provést danou akci nad daným zdrojem.
Role#
| Role | Kdo |
|---|---|
guest |
nepřihlášený |
registrated |
přihlášený uživatel |
owner |
vlastník konkrétního záznamu — podmíněná role |
receiver |
příjemce konkrétního záznamu — podmíněná role |
admin |
administrátor |
Povolené role aplikace#
Role, které se u volání projeví, nejsou jen věcí uživatele. Administrátor webu vybírá, které
role smí aplikace použít (v Nastavení → Aplikace s přístupem k Api) — je to strop nad
právy uživatele. Klíč sám žádná práva nepřidává. Aplikace bez tokenu jedná jako guest
(viz Autentizace); s tokenem se použijí role uživatele, ale jen z povolené
množiny.
Role guest je povolená vždy — administrátor ji nemůže odebrat. Pro novou aplikaci platí
výchozí volba: guest, registrated a podmíněné role owner
(vlastní záznamy) a receiver (záznamy adresované uživateli). Administrátorské (privilegované)
role jen tehdy, když je administrátor výslovně zaškrtne. Partnerské integrace obvykle dostanou
výchozí role, vlastní mobilní aplikace provozovatele webu může dostat všechny.
Jaké role vaše aplikace má, vám řekne administrátor webu. Zvenčí se zjistit nedají.
Administrátor přes aplikaci bez role admin je běžný uživatel
Přihlásí-li se administrátor přes aplikaci, která roli admin nepovoluje, API s ním
jedná jako s běžným registrovaným uživatelem: akce jen pro administrátory jsou zamítnuté
(403), pole jen pro administrátory a nemaskované osobní údaje ostatních uživatelů se
nevracejí.
Bez role owner nejde upravit ani vlastní záznam
Aplikace, která owner nepovoluje, nemůže upravovat ani záznamy svého přihlášeného
uživatele.
Role guest je vždy povolená
Volání bez tokenu i veřejné akce (přihlášení, obnova tokenu, zapomenuté heslo) se
vyhodnocují rolí guest. Bez ní by se uživatel v aplikaci ani nepřihlásil, proto ji má
každá aplikace povolenou vždy a odebrat ji nejde.
Model je plochý#
Chybějící pravidlo znamená zamítnutí
Neexistuje dědičnost ani záložní pravidlo. Není-li pro kombinaci zdroje a akce záznam, akce se zamítne — i pro administrátora, dokud se pravidlo nedoplní.
Klíč pravidla má tvar:
Například :Api:Eshop:Order:updateColumns.
Co je veřejné#
Nepřihlášeným (volání s klíčem aplikace, ale bez tokenu) je otevřené hlavně čtení: články, stránky, číselníky, kategorie a produkty. Zápis je vždy za přihlášením.
Konkrétní seznam je v datech, ne v kódu
Která pravidla jsou otevřená, je nastavení konkrétní instalace. Zjistíte to
nejrychleji tak, že akci zavoláte jen s klíčem aplikace, bez tokenu — buď projde, nebo dostanete
Permission denied.
Vlastnictví#
Role owner sama o sobě nepovoluje nic. Vlastnictví se ověřuje dotazem do
databáze.
Vlastnictví se nikdy nebere z požadavku
Pošlete-li v datech vlastní identifikátor uživatele, systém ho ignoruje a při vkládání dosadí vlastníka ze serveru.
Příjemce#
Vedle owner („záznam je můj") existuje druhá podmíněná role receiver („záznam přišel
mně"). Je to samostatná role: kde záznam má autora i adresáta, nemusí být adresát
schovaný pod vlastníka.
owner |
receiver |
|
|---|---|---|
| Ptá se | je volající tvůrce nebo odesílatel záznamu? | je volající tím, komu záznam přišel? |
| Příklad | autor hodnocení, odesílatel odpovědi na inzerát | majitel inzerátu u odpovědi na něj; majitel hodnoceného profilu u odpovědi na hodnocení |
Tak jako owner sama nic nepovoluje. Pravidlo s rolí receiver projde, jen když ji
potvrdí kontrola dané oblasti proti databázi. Kdo je příjemce, se nikdy nebere z požadavku.
Nepodmíněné pravidlo vyhrává
Existuje-li pro tentýž klíč nepodmíněné pravidlo (třeba pro registrated), projde
každý přihlášený a podmínka owner ani receiver se vůbec nevyhodnotí. Chcete-li právo
omezit na vlastníka nebo příjemce, nesmí k němu existovat nepodmíněné pravidlo pro jinou
roli.
Kde se receiver dnes používá#
| Zdroj a akce | Příjemce je |
|---|---|
response (inzerce i katalog firem) — get |
majitel inzerátu, držitel hesla k inzerátu, administrátor; autor odpovědi ne |
rating — save-reply |
majitel hodnoceného profilu; autor hodnocení odpovídat nesmí |
Pro odpověď na inzerát (response) platí navíc: save (úprava) a delete zůstávají na
roli owner, kterou splní odesílatel odpovědi i majitel inzerátu. Zápis sloupce read
(označení za přečtenou) dovolí kontrola příjemce, ostatní sloupce update-columns jen
administrátor.
Označení z e-mailu zvenčí neprojde
Tlačítko Označit jako přečtené v e-mailu používá klíč uložený u odpovědi. Ten se ověřuje jen na vnitřní cestě (web volá Api přímo) a v HTTP požadavku se nepředává. Pošlete-li klíč v adrese externího volání, nepomůže — příjemcem vás udělá jen přihlášení (nebo heslo k inzerátu).
Soukromé zprávy mají owner a receiver u vláken, ale bez HTTP
Akce nad jednou konverzací (číst zprávy, odpovědět, označit přečtené, skrýt, seznam
účastníků) používají obě role: owner je ten, kdo ve vlákně napsal aspoň jednu zprávu,
receiver ten, komu nějaká zpráva přišla. Tyto akce jsou vnitřní — nemají HTTP
obal a zvenčí jsou nedostupné. Přes HTTP je celý zdroj jen pro administrátora.
🔴 Vlastnictví nefunguje na kolekcích#
get-all, get-by a hromadné mazání jsou pro vlastníka vždy zamítnuté
Nelze říct „vrať mi moje záznamy“ obecným výpisem. Pro vlastní data existují zvláštní akce — ale řada z nich nemá HTTP obal a je tedy zvenčí nedostupná. Viz CRUD vzor.
Co z cizích záznamů uvidíte#
Oprávnění k akci rozhoduje, jestli se k záznamu dostanete. Které hodnoty v odpovědi
dostanete, rozhoduje ještě pole samo — a to i tehdy, když entita přijde jako vnořená
vazba přes includes.
Osobní údaje cizích uživatelů#
Vlastník záznamu a administrátor vidí všechno. Ostatní dostanou osobní údaje cizích lidí
podle nastavení instalace (security.personalDataExposure, výchozí sanitized):
| Údaj | Výchozí stav pro cizího volajícího |
|---|---|
zamaskovaný (pet***@p***.cz) |
|
| telefon, ulice, PSČ, IČ, DIČ, název firmy, „o mně“ uživatele | prázdný řetězec |
| IP adresy (u inzerátů, odpovědí, příspěvků, hlasů, plateb, objednávek…) | prázdný řetězec |
| kredity, body, sleva a slevová úroveň uživatele | klíč v odpovědi chybí |
Režim full vydá vše, režim empty vyprázdní i e-mail. Které pole je osobním údajem, je
dané v kódu; režim volí provozovatel.
Kontakt na prodejce čtěte z veřejného profilu
Údaje, které má návštěvník vidět, vydává user/public-profile a telefon na kliknutí
user/show-phone (s limitem). Nespoléhejte na includes=user.
Chybějící klíč není chyba
Číselné skryté pole se z řádku vypouští, protože prázdný řetězec by nebyl číslo. Parser s tím musí počítat.
Pole, která neopustí server#
Některé hodnoty potřebuje jen web uvnitř serveru a přes HTTP je nedostane nikdo, ani
administrátor s tokenem: heslo k inzerátu a k příspěvku, aktivační klíč inzerátu
a odběru novinek, klíč readKey odpovědi na inzerát, klíč košíku, heslo odchozí pošty
a otisky tokenů a API klíčů. Heslo a sůl uživatele a jednorázové tokeny (obnova hesla,
zrušení účtu) nečte ani web.
V odpovědi taková pole chybějí nebo mají výchozí hodnotu.
Filtry a řazení jen nad poli, která smíte číst#
Filtr je stejně dobrý kanál jako odpověď: kdo smí filtrovat podle hesla nebo e-mailu, zjistí
ho po znacích. Proto filters (i vnořené skupiny), orderBys a columns smějí mířit jen na
pole, která byste dostali i v odpovědi.
| Cesta | Výsledek pro běžného uživatele |
|---|---|
user.id, orderBys[user.username] |
projde |
user.password, user.salt, activationKey |
HTTP 400 |
user.email, insertIp, user.phone (osobní údaje) |
HTTP 400 |
| neexistující pole (překlep) | HTTP 400 |
{"success":false,"message":"Field path \"user.email\" is not allowed in filters, orderBys or columns.","data":null,"code":2}
Administrátor filtruje bez omezení.
Pole, která smíte zapsat#
Zápis má stejnou logiku jako čtení: kromě práva na akci rozhoduje i pole. Pole, které váš
účet zapsat nesmí, se z data tiše vynechá a v databázi zůstane původní hodnota (u
vložení výchozí). Vlastník tak nezmění kredity, slevu ani e-mail svého účtu a nepřesune svůj
komentář nebo odpověď k cizímu záznamu. Seznam pro vlastní účet je v
CRUD vzoru.
Režimy#
| Režim | Chování |
|---|---|
off |
nekontroluje se |
log |
vyhodnotí a zapíše, nezamítá |
enforce |
zamítá — současný stav |
Vypínač platí pro celou větev API najednou
Neexistuje přepínač po modulech. Počítejte s tím, že se chování oprávnění může skokově změnit.
Zamítnutí#
s kódem HTTP 403.
Kód 400 znamená zamítnuté oprávnění, ne „chybný požadavek“
Číselné kódy se nápadně podobají stavovým kódům HTTP, ale neodpovídají jim. Viz Chybové kódy.
Volání zevnitř systému#
Web a administrace volají tytéž zdroje vnitřní cestou — bez HTTP, přímým sestavením požadavku, a proto nepotřebují klíč aplikace. Kontrolu oprávnění to ale neobchází: obě cesty procházejí týmž guardem a mají jen samostatný přepínač.
Pro vás jako externího klienta z toho plyne jedno
Chování, které vidíte na webu, nemusí být přes API dostupné — ne proto, že by web kontrolu obcházel, ale proto, že řada akcí nemá HTTP obal. Viz CRUD vzor.
Rozdíl mezi webem a API tedy není v oprávněních, ale v dostupnosti akcí
Nefunguje-li přes API něco, co web umí, hledejte chybějící endpoint nebo chybějící pravidlo — ne „výjimku pro web“.