نقشها
`roles.list`، `list_all`، `iterate`، `get`، `create`، `update`، `delete` و `list_permissions`.
همهٔ متدها
page = client.roles.listputs page.items.size role = client.roles.get("role_8b1f4c2e9a7d3b60e5f1a2c4")puts role[:name] support = client.roles.create( name: "Support", description: "Answers the shared inboxes and nothing else.", permissions: ["emails:send", "threads:write", "labels:write"]) p support[:permissions] client.roles.update(support[:id], permissions: [*support[:permissions], "templates:read"]) client.roles.delete(support[:id], reassign_to: role[:id]) vocabulary = client.roles.list_permissionsp vocabulary.map { |permission| permission[:id] }support[:permissions] شش مدخل دارد نه سه: emails:send همراه خود emails:read را میآورد، threads:write همراه خود threads:read را و labels:write همراه خود labels:read را. بهجای فرض کردن، فهرست را دوباره بخوانید.
list یک OpenEmail::Page برمیگرداند، list_all همهٔ نقشها را در یک Array برمیگرداند، و iterate هر نقش را به یک بلاک yield میکند یا بدون بلاک یک Enumerator برمیگرداند. نقش بهصورت یک Hash با کلیدهای Symbol برمیگردد، پس role[:permissions] فهرست را میخواند. create و update فیلدهای بدنه را بهصورت کلیدواژه یا یک Hash میگیرند، در حالی که delete، reassign_to: را میگیرد، کلیدواژهای snake_case که gem نامش را برای API تغییر میدهد.
یک نقش میگوید کسی چه «کاری» میتواند بکند. اینکه روی کدام «نشانیها»، محور دیگری است و روی client.members قرار دارد: grant_address و revoke_address را در صفحهٔ «اعضا» ببینید. «میتواند ایمیل بفرستد» و «میتواند از invoices@ بفرستد» دو جملهٔ متفاوتاند، و فضای کاریای که کارشناس پشتیبانی دومی استخدام میکند دومی را تغییر میدهد بیآنکه به اولی دست بزند. یک مجوز به هر دو پاسخ میدهد: نقشی که addresses:all دارد بدون هیچ اعطایی به همهٔ نشانیها میرسد، از جمله نشانیهایی که بعداً افزوده میشوند، و فقط یک شخص در برنامه میتواند آن را روی یک نقش بگذارد.
بهجای builtin یا نام، روی editable و deletable شاخه بزنید. هر دو تنها برای مالک false هستند، که فهرستش «هر مجوزی، از جمله مجوزهایی که سال آینده ساخته میشوند» است و محاسبه میشود نه ذخیره. هر نقش دیگری به هر دو true پاسخ میدهد، از جمله همان پنج نقشی که فضای کاری با آنها آغاز میشود. نقشی که کسی نامش را عوض کرده همچنان به هر دو درست پاسخ میدهد، و نامش دیگر چیزی به شما نمیگوید.
update فهرست مجوزها را «جایگزین» میکند. فراخوانیای برای اعطای تکی وجود ندارد، پس نقش را بخوانید، مدخلی را که در نظر داشتید تغییر دهید و همه را پس بفرستید، همانطور که [*support[:permissions], "templates:read"] در بالا انجام میدهد. فرستادن یک مجوز، نقش را فقط با همان یک مجوز بهعلاوهٔ هر چه آن را در پی دارد باقی میگذارد.
به محض آنکه کسی نقش را داشته باشد، delete به reassign_to: نیاز دارد. gem آن را بهصورت پارامتر کوئری reassignTo میفرستد، چون بدنه روی DELETE در چندین محیط اجرا و شماری از پراکسیها کنار گذاشته میشود، و وقتی چیزی ندهید این پارامتر را نمیفرستد. نتیجه، reassigned و keysReassigned را جداگانه گزارش میکند، تا یک اسکریپت بتواند آنچه را انجام داده ثبت کند نه آنچه را خواسته.
list_permissions همان GET /roles/permissions است، مسیری ثابت که دقیقاً جایی نشسته که شناسهٔ نقش قرار میگرفت. gem آن مسیر را مستقیماً فراخوانی میکند نه اینکه این واژه را از راه get بفرستد، و یک Array ساده برمیگرداند، نه یک OpenEmail::Page: یک Hash برای هر مجوز، با id، label، group و scope. scope: false مدخلهایی را نشان میدهد که هیچ کلیدی هرگز نمیتواند داشته باشد. خودتان این واژه را به get ندهید. client.roles.get("permissions") همان مسیر را میسازد، پس همان درخواست را میفرستد و بهجای یک نقش یا یک 404، واژگان مجوزها را پس میگیرد.
نقش، سقفِ یک کلید است
کلیدی که برای یک نقش صادر شده، فقط «اشتراکِ» اسکوپهای خودش با مجوزهای آن نقش را میتواند انجام دهد، که در هر درخواست در مرز سیستم محاسبه میشود. پس باریک کردن یک نقش، دسترسی کلیدهایش را در لحظه پس میگیرد، بیآنکه هیچکدام چرخانده شوند. کلیدی که نقشی ندارد اصلاً سقفی ندارد، و همین roleId برابر nil را گستردهترین وضعیتی میکند که یک کلید میتواند داشته باشد، نه باریکترین.
به همین دلیل هم هست که roles.delete اصرار دارد جایی برای انتقال کلیدها وجود داشته باشد. بیسرپرست گذاشتنشان سقفشان را یکسره برمیداشت و هر اعتبارنامهای را که آن نقش محدودش میکرد بیصدا ارتقا میداد.
GET /keys/self و GET /ping مقدارهای roleId و grantedScopes را کنار scopes مؤثر گزارش میکنند. اینگونه است که به «کلید من emails:send دارد و insufficient_scope میگیرم» پاسخ داده میشود: هر چیزی که در grantedScopes هست و در scopes نیست، را نقش گرفته است. client.me.get و client.me.ping هر دو را در Hash خود برمیگردانند، پس key[:grantedScopes] - key[:scopes] آنچه را نقش گرفته فهرست میکند. خودِ رد شدن یک OpenEmail::PermissionError است که scope_missing? آن true است.
پارامترها
nameStringالزامی- نامی که فضای کاری روی نقش میگذارد: 1 تا 48 نویسه، که پیش از ذخیره فاصلههای دو سرش حذف میشود. نامها در هر فضای کاری بدون توجه به بزرگی و کوچکی حروف یکتا هستند، پس «Support» دوم بهجای آنکه کنار اولی ساخته شود با `role_name_taken` (409) رد میشود که بهصورت `OpenEmail::ConflictError` raise میشود.
descriptionString- جملهای که میگوید نقش برای چیست، با حذف فاصلههای دو سر و حداکثر 240 نویسه. Stringی که پس از این حذف خالی باشد بهصورت nil ذخیره میشود، پس توضیحی که فقط از فاصله ساخته شده بهجای آنچه فرستادهاید بهصورت nil برمیگردد. در `create`، بهجای دادن nil آن را ننویسید: gem مقدار nil را همانطور میفرستد، و `create` آن را با یک 422 رد میکند. در `update`، `description: nil` آن را پاک میکند.
permissionsArray<String>الزامی- آنچه نقش اعطا میکند، برگرفته از واژگانی که `list_permissions` ارائه میدهد. Stringی که در آن نباشد بهجای آنکه بیصدا کنار گذاشته شود، یک 422 روی `permissions` است که بهصورت `OpenEmail::ValidationError` با `param` برابر `permissions` raise میشود، پس غلط تایپی گزارش میشود بهجای آنکه یک بعدازظهر از وقت شما را بگیرد. فهرست هنگام ورود «گسترش» مییابد (`templates:write` در کنار خود `templates:read` را هم ذخیره میکند)، تکراریهایش حذف میشوند و به ترتیب متعارف برگردانده میشود، پس فهرست ذخیرهشده را از روی پاسخ بخوانید نه اینکه فرض کنید همانی است که فرستادهاید.
پاسخ
objectString- همیشه `role`. نشانهٔ حذف (tombstone) با همین مقدار، `id` نقش، `deleted: true` و دو شمارندهٔ واگذاری پاسخ میدهد، و هیچیک از فیلدهای دیگرِ زیر را ندارد.
idString- شناسهٔ نقش، که به شکل `role[:id]` خوانده میشود. همان چیزی است که `roleId` یک عضو نام میبرد، همان چیزی که سقف یک کلید API به آن اشاره میکند، و همان چیزی که `reassign_to:` میگیرد وقتی نقش دیگری حذف میشود و دارندگانش به این نقش منتقل میشوند.
nameString- نام فضای کاری برای این نقش، با حذف فاصلههای دو سر و یکتا بدون توجه به بزرگی و کوچکی حروف. هر نقشی جز نقش مالک را میتوان تغییر نام داد، از جمله نقشهای آغازین (`builtin` میگوید یک ردیف از کجا آمده، نه اینکه باید چه نامی بماند)، پس «Admin» را وعدهای دربارهٔ آنچه نقش دارد نخوانید. نامی که نقش دیگری از پیش دارد `role_name_taken` است (409، با `param` برابر `name`). تغییر نام مالک `role_immutable` است (409)، مانند هر ویرایش دیگری روی آن.
descriptionString or nil- جملهای که نقش را توصیف میکند، یا nil وقتی چیزی داده نشده باشد. ورودی خالی هم در create و هم در update بهصورت nil ذخیره میشود، پس این هرگز یک String خالی نیست.
permissionsArray<String>- هر آنچه نقش اعطا میکند، از پیش گسترشیافته و به ترتیب متعارف، نه به ترتیبی که کسی تایپ کرده است. این ترتیب اهمیت اساسی دارد: دو نقش با مجوزهای یکسان Arrayهای برابر دارند، و همین است که به صفحهٔ تنظیمات اجازه میدهد آنها را با `==` مقایسه کند تا تصمیم بگیرد دکمهٔ ذخیره فعال باشد یا نه.
builtinString or nil- اینکه این ردیف از کدامیک از شش نقش آغازین آمده است، `owner`، `admin`، `member`، `viewer`، `developer` یا `billing`، یا nil برای نقشی که خودِ فضای کاری نوشته. این فیلد خاستگاه را ثبت میکند نه یک وضعیت را: یک نقش آغازین هم مثل هر نقش دیگری تغییر نام میدهد، مجوزهایش عوض میشود و حذف میشود. بهجای این، روی `editable` و `deletable` شاخه بزنید. نقشی که کسی «Admin» نامیده لازم نیست همان نقش آغازین باشد، و نقش آغازین ممکن است دیگر این نام را نداشته باشد.
editableBoolean- بهصورت `builtin != "owner"` محاسبه میشود، پس تنها برای نقش مالک false است، و هر `update` روی آن نقش با `role_immutable` (409) رد میشود. هر نقش دیگری بهطور کامل قابل ویرایش است (نام، توضیح و مجوزها)، از جمله همان پنج نقشی که فضای کاری با آنها آغاز میشود.
deletableBoolean- بهصورت `builtin != "owner"` محاسبه میشود: تنها برای نقش مالک false است، که با `role_undeletable` (409) برمیگردد، و برای هر نقش دیگری از جمله نقشهای آغازین true. پیش از نمایش دکمه آن را بررسی کنید نه پس از رد شدن. نقشی که هنوز کسی آن را دارد به `reassign_to:` هم نیاز دارد، وگرنه حذف `role_in_use` (409) است. هر دو رد شدن بهصورت `OpenEmail::ConflictError` raise میشوند، و `code` آنها را از هم جدا میکند.
membersInteger- چند نفر این نقش را دارند، شمردهشده از ردیفهای اعضای فضای کاری. مالک میان آنها نیست: او ردیف عضویت ندارد و نمیتوان به او نقش داد، پس نقش Owner صفر دارنده گزارش میکند، هرچند فهرست اعضا او را نشان میدهد.
apiKeysInteger- چند کلید API فعال زیر سقف این نقش هستند. کلیدهای باطلشده در شمارش نمیآیند، هرچند حذف، هر ردیف کلیدی را که به نقش اشاره میکند، از جمله باطلشدهها، به نقش تازه منتقل میکند. این دومین گروهی است که پیش از رفتن نقش باید منتقل شود، و همانی که کسی متوجهش نمیشود: کلیدها برنامهاند، و برنامه شکایت نمیکند.
createdAtString- زمان نوشته شدن ردیف نقش، بهصورت یک String با قالب ISO 8601. ردیفهای درونساخت در نخستین باری که چیزی به آنها نیاز دارد ساخته میشوند، مانند خواندن فهرست نقشها، ساختن یک نقش یا صفحهٔ کلیدهای API، نه هنگام ساخت فضای کاری. پس مهر زمانی یک نقش درونساخت، زمان رسیدن همان نخستین درخواست است نه زمان ساخته شدن فضای کاری.
updatedAtString- زمان آخرین تغییر نقش، بهصورت یک String با قالب ISO 8601. هر `update` پذیرفتهشده آن را جلو میبرد، حتی آن یکی که فیلدی را به همان مقداری که داشته تنظیم کند.