Role
`roles.list`, `get`, `create`, `update`, `delete` i `listPermissions`.
Wszystkie metody
const roles = await openemail.roles.list()const role = await openemail.roles.get('role_…') const support = await openemail.roles.create({ name: 'Support', description: 'Answers the shared inboxes and nothing else.', permissions: ['emails:send', 'threads:write', 'labels:write'],}) console.log(support.permissions) await openemail.roles.update(support.id, { permissions: [...support.permissions, 'templates:read'],}) await openemail.roles.delete(support.id, { reassignTo: 'role_…' }) const vocabulary = await openemail.roles.listPermissions()support.permissions zawiera sześć pozycji, nie trzy: emails:send pociąga emails:read, threads:write pociąga threads:read, a labels:write pociąga labels:read. Odczytaj tę listę z odpowiedzi, zamiast ją zakładać.
Rola mówi, co ktoś może ROBIĆ. To, na jakich ADRESACH może to robić, jest drugą osią i mieszka w openemail.members — patrz tamtejsze grantAddress i revokeAddress. „Może wysyłać pocztę” i „może wysyłać jako invoices@” to różne zdania, a przestrzeń robocza, która zatrudnia drugą osobę do wsparcia, zmienia to drugie, nie ruszając pierwszego.
Rozgałęziaj kod na editable i deletable, a nie na nazwie z builtin. Oba są false wyłącznie dla roli właściciela, której lista brzmi „każde uprawnienie, łącznie z tymi wymyślonymi za rok” i jest wyliczana, a nie przechowywana; każda inna rola odpowiada true na oba, wliczając pięć ról, którymi zaszczepiana jest przestrzeń robocza. Rola, którą ktoś przemianował, nadal odpowiada poprawnie na oba, a jej nazwa nie mówi ci już nic.
update ZASTĘPUJE listę uprawnień. Nie ma wywołania przyznającego pojedyncze uprawnienie, więc odczytaj rolę, zmień wpis, o który ci chodziło, i odeślij wszystkie z powrotem. Wysłanie jednego uprawnienia zostawia rolę dokładnie z tym jednym, plus tym, co ono pociąga.
delete wymaga reassignTo w chwili, gdy ktokolwiek ma tę rolę, a parametr ten podróżuje jako parametr zapytania, bo treść żądania przy DELETE jest porzucana przez kilka środowisk uruchomieniowych i sporo proxy. Wynik raportuje reassigned i keysReassigned osobno, więc skrypt może zalogować to, co zrobił, a nie to, o co poprosił.
listPermissions() to GET /roles/permissions — stała ścieżka siedząca dokładnie tam, gdzie trafiłoby id roli. Klient ma ją zapisaną na sztywno, zamiast przepuszczać ten ciąg przez get, więc pytanie o rolę naprawdę nazwaną „permissions” jest pytaniem o rolę i kończy się 404, co jest uczciwą odpowiedzią na to, co wpisano. scope: false oznacza wpisy, których żaden klucz nigdy nie może mieć.
Rola jest pułapem klucza
Klucz wydany pod rolą może robić to, co wynika z PRZECIĘCIA jego własnych scope'ów z uprawnieniami tej roli, rozstrzyganego osobno dla każdego żądania na granicy API. Zawężenie roli odbiera więc jej kluczom uprawnienia na żywo, bez rotowania któregokolwiek z nich, a klucz bez roli nie ma żadnego pułapu — co czyni pustą rolę najszerszym, a nie najwęższym stanem, w jakim klucz może się znaleźć.
To również powód, dla którego roles.delete nalega na wskazanie miejsca, do którego trafią klucze. Osierocenie ich zdjęłoby ich pułap całkowicie, po cichu awansując każde poświadczenie, które rola ograniczała.
GET /keys/self i GET /ping podają roleId i grantedScopes obok efektywnych scopes — i tak właśnie odpowiada się na „mój klucz ma emails:send, a dostaję insufficient_scope”: wszystko, co jest w grantedScopes, a czego brakuje w scopes, zabrała rola. openemail.me.get() i openemail.me.ping() zwracają oba, otypowane.
Parametry
namestringwymagane- Nazwa, jaką przestrzeń robocza nadaje roli: od 1 do 48 znaków, przycinana przed zapisem. Nazwy są unikalne w obrębie przestrzeni roboczej bez rozróżniania wielkości liter, więc drugi „Support” zostaje odrzucony z `role_name_taken` (409), a nie utworzony obok pierwszego.
descriptionstring- Zdanie mówiące, do czego rola służy, przycinane i najwyżej 240 znaków. Ciąg, który po przycięciu jest pusty, zapisywany jest jako null, więc opis złożony ze spacji wraca jako null, a nie jako to, co wysłano.
permissionsPermission[]wymagane- To, co rola przyznaje, zaczerpnięte ze słownika serwowanego przez `listPermissions()`; ciąg, którego w nim nie ma, daje 422 na `permissions`, zamiast zostać po cichu pominięty, więc literówka jest zgłaszana, a nie kosztuje cię popołudnia. Lista jest ROZWIJANA przy zapisie (`templates:write` zapisuje obok siebie `templates:read`), pozbawiana duplikatów i układana w kanonicznej kolejności, więc odczytuj zapisaną listę z odpowiedzi, zamiast zakładać, że jest to ta, którą wysłałeś.
Odpowiedź
object'role'- Zawsze `role`. Nagrobek po usunięciu odpowiada tą samą wartością, `id` roli, `deleted: true` i dwoma licznikami przepisania — i żadnym z pozostałych pól poniżej.
idstring- Id roli. To je wskazuje `roleId` członka, na nie wskazuje pułap klucza API i to je przyjmuje `reassignTo` przy usuwaniu tej roli.
namestring- Nazwa roli nadana przez przestrzeń roboczą, przycięta i unikalna bez rozróżniania wielkości liter. Przemianować można każdą rolę poza rolą właściciela, w tym te zaszczepione (`builtin` mówi, skąd wziął się wiersz, a nie jak musi się dalej nazywać), więc nie czytaj „Admin” jako obietnicy tego, co rola zawiera. Nazwa, na którą odpowiada już inna rola, to `role_name_taken` (409, `param: "name"`); przemianowanie właściciela to `role_immutable` (409), jak każda inna jego edycja.
descriptionstring | null- Zdanie opisujące rolę albo null, gdy żadnego nie podano. Puste wejście zapisywane jest jako null zarówno przy tworzeniu, jak i przy aktualizacji, więc nigdy nie jest to pusty ciąg.
permissionsPermission[]- Wszystko, co rola przyznaje, już rozwinięte i w kanonicznej kolejności, a nie w tej, w której ktoś to wpisał. Ta kolejność jest nośna: dwie role mające te same uprawnienia porównują się jako JSON na równe, co pozwala ekranowi ustawień zrobić między nimi diff i zdecydować, czy przycisk zapisu jest aktywny.
builtin'owner' | 'admin' | 'member' | 'viewer' | 'developer' | 'billing' | null- Z której z sześciu zaszczepionych ról pochodzi ten wiersz, albo null dla roli, którą przestrzeń robocza napisała sama. Pole zapisuje pochodzenie, a nie status: zaszczepioną rolę przemianowuje się, zmienia jej uprawnienia i usuwa tak jak każdą inną. Rozgałęziaj kod na `editable` i `deletable`, a nie na tym polu. Rola, którą ktoś nazwał „Admin”, nie musi być tą zaszczepioną, a zaszczepiona może już tak się nie nazywać.
editableboolean- Wyliczane jako `builtin !== 'owner'`, więc jest false wyłącznie dla roli właściciela, a każdy PATCH tej roli jest odrzucany z `role_immutable` (409). Każda inna rola jest w pełni edytowalna (nazwa, opis i uprawnienia), wliczając pięć ról, którymi zaszczepiana jest przestrzeń robocza.
deletableboolean- Wyliczane jako `builtin !== 'owner'`: false wyłącznie dla roli właściciela, która wraca z `role_undeletable` (409), i true dla każdej innej roli, w tym zaszczepionych. Sprawdź je, zanim pokażesz przycisk, a nie po odmowie — przy czym rola, którą ktoś wciąż ma, wymaga jeszcze `reassignTo`, inaczej usunięcie kończy się `role_in_use` (409).
membersnumber- Ile osób ma tę rolę, policzone z wierszy członków przestrzeni roboczej. Właściciela wśród nich nie ma: nie ma wiersza członka i nie można mu nadać roli, więc rola właściciela raportuje zero posiadaczy, mimo że lista członków go pokazuje.
apiKeysnumber- Ile żywych kluczy API jest ograniczonych tą rolą; klucze unieważnione są pomijane w liczniku, choć usunięcie przepina każdy wiersz klucza wskazujący na tę rolę, unieważnione również. To druga populacja, którą trzeba przenieść, zanim rola zniknie — i ta, której nikt nie zauważa: klucze to programy, a program się nie skarży.
createdAtstring- Kiedy zapisano wiersz roli, ISO-8601. Wiersze wbudowane są zaszczepiane leniwie, przy pierwszej sytuacji, w której są potrzebne — odczycie listy ról, utworzeniu roli czy na ekranie kluczy API — a nie przy tworzeniu przestrzeni roboczej, więc znacznik czasu roli wbudowanej mówi, kiedy dotarło tamto pierwsze żądanie, a nie kiedy powstała przestrzeń robocza.
updatedAtstring- Kiedy rola zmieniła się po raz ostatni, ISO-8601. Przesuwa go każdy przyjęty PATCH, również taki, który ustawia pole na wartość, którą już miało.