پرش به مستندات
Python

نقش‌ها

`roles.list`، `list_all`، `iterate`، `get`، `create`، `update`، `delete` و `list_permissions`.

همهٔ متدها

roles.py
from openemail import openemail roles = openemail.roles.list()role = openemail.roles.get('role_…') support = openemail.roles.create({    'name': 'Support',    'description': 'Answers the shared inboxes and nothing else.',    'permissions': ['emails:send', 'threads:write', 'labels:write'],}) print(support['permissions']) openemail.roles.update(support['id'], {    'permissions': [*support['permissions'], 'templates:read'],}) openemail.roles.delete(support['id'], reassign_to='role_…') vocabulary = openemail.roles.list_permissions()

support['permissions'] شش مدخل دارد نه سه: emails:send همراه خود emails:read می‌آورد، threads:write همراه خود threads:read و labels:write همراه خود labels:read. به‌جای فرض کردن، فهرست را دوباره بخوانید.

یک نقش می‌گوید کسی چه کاری می‌تواند بکند. اینکه روی کدام آدرس‌ها، محور دیگری است و روی openemail.members زندگی می‌کند. grant_address و revoke_address را آنجا ببینید. «می‌تواند ایمیل بفرستد» و «می‌تواند از invoices@ بفرستد» دو جملهٔ متفاوت‌اند، و فضای کاری‌ای که کارشناس پشتیبانی دومی استخدام می‌کند دومی را تغییر می‌دهد بی‌آنکه به اولی دست بزند. یک مجوز به هر دو پاسخ می‌دهد: نقشی که addresses:all را دارد، بدون اعطا به همهٔ آدرس‌ها می‌رسد، از جمله آن‌هایی که بعداً اضافه می‌شوند، و فقط شخصی در برنامه می‌تواند آن را روی یک نقش بگذارد.

به‌جای نام builtin، روی editable و deletable شاخه بزنید. هر دو تنها برای مالک false هستند، که فهرستش «هر مجوزی، از جمله مجوزهایی که سال آینده اختراع می‌شوند» است و محاسبه می‌شود نه ذخیره؛ هر نقش دیگری به هر دو پاسخ true می‌دهد، از جمله همان پنج نقشی که هر فضای کاری با آن‌ها آغاز می‌شود. نقشی که کسی نامش را عوض کرده باشد هم به هر دو درست پاسخ می‌دهد، و نامش دیگر چیزی به شما نمی‌گوید.

update فهرست مجوزها را جایگزین می‌کند. هیچ فراخوانی‌ای برای اعطای تکی وجود ندارد، پس نقش را بخوانید، مدخلی را که در نظر داشتید تغییر دهید و همهٔ آن‌ها را بازبفرستید. فرستادن یک مجوز، نقش را با دقیقاً همان یک مجوز به‌علاوهٔ هر چه آن را در پی دارد باقی می‌گذارد.

به محض آنکه کسی نقش را داشته باشد، delete به reassign_to نیاز دارد، و آن به‌صورت یک پارامتر query می‌رود چون بدنه روی DELETE در چندین محیط اجرا و شماری از پراکسی‌ها کنار گذاشته می‌شود. نتیجه، reassigned و keysReassigned را جداگانه گزارش می‌کند، تا یک اسکریپت بتواند آنچه را انجام داده لاگ کند نه آنچه را خواسته است.

list_permissions() همان GET /roles/permissions است، مسیری ثابت که دقیقاً جایی نشسته که شناسهٔ یک نقش می‌نشیند، پس get('permissions') به همان اندپوینت می‌رسد و به‌جای یک نقش، فهرست مجوزها را پاسخ می‌دهد. 'scope': False مدخل‌هایی را نشانه می‌زند که هیچ کلیدی هرگز نمی‌تواند داشته باشد.

نقش، سقفِ یک کلید است

کلیدی که در برابر یک نقش صادر شده باشد، می‌تواند اشتراک اسکوپ‌های خودش با مجوزهای آن نقش را انجام دهد، که در هر درخواست روی مرز محاسبه می‌شود. پس باریک کردن یک نقش، کلیدهایش را زنده باطل می‌کند بدون آنکه هیچ‌کدام چرخانده شوند، و کلیدی که نقشی ندارد اصلاً سقفی ندارد، و همین باعث می‌شود نقشِ null گسترده‌ترین حالتی باشد که یک کلید می‌تواند در آن باشد، نه باریک‌ترین.

به همین دلیل هم هست که roles.delete اصرار دارد جایی برای انتقال کلیدها وجود داشته باشد. بی‌سرپرست گذاشتنشان سقفشان را یکسره برمی‌داشت و هر اعتبارنامه‌ای را که آن نقش محدودش می‌کرد بی‌صدا ارتقا می‌داد.

GET /keys/self و GET /ping مقادیر roleId و grantedScopes را کنار scopes مؤثر گزارش می‌کنند، و این‌گونه است که به «کلید من emails:send دارد و insufficient_scope می‌گیرم» پاسخ داده می‌شود: هر چیزی که در grantedScopes هست و در scopes نیست، به دست نقش گرفته شده است. openemail.me.get() و openemail.me.ping() هر دو را، تایپ‌شده، برمی‌گردانند.

پارامترها

namestrالزامی
فضای کاری نقش را چه می‌نامد: 1 تا 48 نویسه، که پیش از ذخیره trim می‌شود. نام‌ها در هر فضای کاری بدون حساسیت به بزرگی حروف یکتا هستند، پس «Support» دوم با `role_name_taken` (409 Conflict) رد می‌شود نه اینکه کنار اولی ساخته شود.
descriptionstr
جمله‌ای که می‌گوید نقش برای چیست، trim‌شده و حداکثر 240 نویسه. رشته‌ای که پس از trim خالی باشد به‌صورت null ذخیره می‌شود، پس توضیحی که از فاصله ساخته شده باشد به‌جای آنچه فرستاده‌اید به‌صورت null بازمی‌گردد.
permissionslist[Permission]الزامی
آنچه نقش اعطا می‌کند، برگرفته از واژگانی که `list_permissions()` سرو می‌کند؛ رشته‌ای که در آن نباشد روی `permissions` یک 422 است نه اینکه بی‌صدا کنار گذاشته شود، پس یک اشتباه تایپی گزارش می‌شود به‌جای آنکه یک بعدازظهر را از شما بگیرد. فهرست هنگام ورود گسترده می‌شود (`templates:write` کنار خود `templates:read` را ذخیره می‌کند)، یکتاسازی و به ترتیب متعارف بازچیده می‌شود، پس فهرست ذخیره‌شده را از پاسخ بخوانید به‌جای آنکه فرض کنید همان است که فرستاده‌اید.

پاسخ

objectLiteral['role']
همیشه `role`. سنگ‌قبرِ حذف با همین مقدار، `id` نقش، `'deleted': True` و دو شمارندهٔ واگذاری پاسخ می‌دهد، و هیچ‌یک از فیلدهای دیگرِ زیر.
idstr
شناسهٔ نقش. همان چیزی است که `roleId` یک عضو نام می‌برد، همان چیزی که سقف یک API key به آن اشاره می‌کند، و همان چیزی که هنگام حذف این نقش `reassign_to` می‌گیرد.
namestr
نام فضای کاری برای این نقش، trim‌شده و بدون حساسیت به بزرگی حروف یکتا. هر نقشی جز نقش مالک را می‌توان تغییر نام داد، از جمله نقش‌های seed‌شده (`builtin` می‌گوید یک ردیف از کجا آمده، نه اینکه باید چه نامی بماند)، پس «Admin» را وعده‌ای دربارهٔ آنچه نقش دارد نخوانید. نامی که نقشی دیگر از پیش به آن پاسخ می‌دهد `role_name_taken` است (409 Conflict، با `param: "name"`)؛ تغییر نام مالک `role_immutable` (409 Conflict) است، مثل هر ویرایش دیگری روی آن.
descriptionstr | None
جمله‌ای که نقش را توصیف می‌کند، یا وقتی چیزی داده نشده باشد null. ورودی خالی در هر دو create و update به‌صورت null ذخیره می‌شود، پس این هرگز رشتهٔ خالی نیست.
permissionslist[Permission]
هر آنچه نقش اعطا می‌کند، از پیش گسترده‌شده و به ترتیب متعارف، نه به ترتیبی که کسی تایپ کرده است. آن ترتیب باربر است: دو نقش با مجوزهای یکسان به‌صورت JSON برابر مقایسه می‌شوند، و همین است که به صفحهٔ تنظیمات اجازه می‌دهد آن‌ها را diff کند تا تصمیم بگیرد دکمهٔ ذخیره فعال باشد یا نه.
builtinLiteral['owner', 'admin', 'member', 'viewer', 'developer', 'billing'] | None
اینکه این ردیف از کدام‌یک از شش نقش seed‌شده آمده است، یا برای نقشی که خودِ فضای کاری نوشته null. این فیلد خاستگاه seed را ثبت می‌کند نه یک وضعیت را: یک نقش seed‌شده هم مثل هر نقش دیگری تغییر نام می‌دهد، مجوزهایش عوض می‌شود و حذف می‌شود. به‌جای این، روی `editable` و `deletable` شاخه بزنید. نقشی که کسی «Admin» نامیده لازم نیست همان نقش seed‌شده باشد، و آن نقش seed‌شده هم شاید دیگر چنین نامی نداشته باشد.
editablebool
به‌صورت `builtin != 'owner'` محاسبه می‌شود، پس تنها برای نقش مالک false است و هر PATCH روی آن نقش با `role_immutable` (409 Conflict) رد می‌شود. هر نقش دیگری به‌طور کامل قابل ویرایش است (نام، توضیح و مجوزها)، از جمله همان پنج نقشی که فضای کاری با آن‌ها seed می‌شود.
deletablebool
به‌صورت `builtin != 'owner'` محاسبه می‌شود: تنها برای نقش مالک false است، که با `role_undeletable` (409 Conflict) بازمی‌گردد، و برای هر نقش دیگری از جمله نقش‌های seed‌شده true. پیش از نمایش دکمه آن را بررسی کنید نه پس از رد شدن، هرچند نقشی که هنوز کسی آن را دارد به `reassign_to` هم نیاز دارد وگرنه حذف `role_in_use` (409 Conflict) می‌شود.
membersint
چند نفر این نقش را دارند، شمرده‌شده از ردیف‌های عضویت فضای کاری. مالک میان آن‌ها نیست: او ردیف عضویت ندارد و نمی‌توان به او نقش داد، پس نقش Owner صفر دارنده گزارش می‌کند هرچند فهرست اعضا او را نشان می‌دهد.
apiKeysint
چند API key زندهٔ فعال زیر سقف این نقش هستند؛ کلیدهای باطل‌شده در شمارش نمی‌آیند، هرچند یک حذف، هر ردیف کلیدی را که به نقش اشاره می‌کند، از جمله باطل‌شده‌ها، بازنشانه می‌کند. این جمعیت دومی است که پیش از رفتن نقش باید منتقل شود، و همان که کسی متوجهش نمی‌شود: کلیدها برنامه‌اند و برنامه شکایت نمی‌کند.
createdAtstr
زمان نوشته شدن ردیف نقش، ISO-8601. ردیف‌های داخلی به‌صورت تنبل و در نخستین باری که چیزی به آن‌ها نیاز دارد seed می‌شوند، مثل خواندن فهرست نقش‌ها، ساختن یک نقش یا صفحهٔ API key، نه هنگام ساخت فضای کاری؛ پس مهر زمانی یک نقش داخلی، زمان رسیدن همان نخستین درخواست است نه زمان ساخته شدن فضای کاری.
updatedAtstr
زمان آخرین تغییر نقش، ISO-8601. هر PATCH پذیرفته‌شده آن را جلو می‌برد، حتی PATCHی که فیلدی را به همان مقداری که داشته تنظیم کند.

کدهای تأیید هویت

update و delete پیش از آنکه چیزی را تغییر دهند از توکن دسترسی OAuth کد تأیید هویت می‌خواهند، و create نمی‌خواهد. فراخوانی یک OpenEmailApiError را raise می‌کند که is_step_up_required آن True است: با security.begin_step_up() یک کد بخواهید، کدی را که شخص به شما می‌دهد با security.verify_step_up({'code': ...}) بررسی کنید، سپس دوباره فراخوانی کنید. هر تأیید هویت 60 دقیقه اعتبار دارد، و از کلید API هرگز خواسته نمی‌شود.

مرجع