نقشها
`roles->list`، `listAll`، `iterate`، `get`، `create`، `update`، `delete` و `listPermissions`.
همهٔ متدها
use OpenEmail\Constants\ApiScopes; $page = $client->roles->list();echo count($page), PHP_EOL; $role = $client->roles->get('role_8b1f4c2e9a7d3b60e5f1a2c4');echo $role['name'], PHP_EOL; $support = $client->roles->create([ 'name' => 'Support', 'description' => 'Answers the shared inboxes and nothing else.', 'permissions' => [ApiScopes::EMAILS_SEND, ApiScopes::THREADS_WRITE, ApiScopes::LABELS_WRITE],]); echo implode(', ', $support['permissions']), PHP_EOL; $client->roles->update($support['id'], ['permissions' => [...$support['permissions'], ApiScopes::TEMPLATES_READ]]); $client->roles->delete($support['id'], reassignTo: $role['id']); $vocabulary = $client->roles->listPermissions();echo implode(', ', array_column($vocabulary, 'id')), PHP_EOL;$support['permissions'] شش مدخل دارد نه سه: emails:send همراه خود emails:read را میآورد، threads:write همراه خود threads:read را و labels:write همراه خود labels:read را. بهجای فرض کردن، فهرست را دوباره بخوانید.
list یک OpenEmail\Result\Page برمیگرداند، listAll همهٔ نقشها را در یک آرایه برمیگرداند، و iterate یک Generator برمیگرداند که هر بار یک نقش را yield میکند. نقش بهصورت یک آرایه با کلیدهای camelCase برمیگردد، پس $role['permissions'] فهرست را میخواند. create و update بدنه را بهصورت یک آرایه با نامهای API میگیرند، در حالی که delete، reassignTo: را بهصورت آرگومان نامدار میگیرد.
یک نقش میگوید کسی چه «کاری» میتواند بکند. اینکه روی کدام «نشانیها»، محور دیگری است و روی $client->members قرار دارد: members->grantAddress و members->revokeAddress را در صفحهٔ «اعضا» ببینید. «میتواند ایمیل بفرستد» و «میتواند از invoices@ بفرستد» دو جملهٔ متفاوتاند، و فضای کاریای که کارشناس پشتیبانی دومی استخدام میکند دومی را تغییر میدهد بیآنکه به اولی دست بزند. یک مجوز به هر دو پاسخ میدهد: نقشی که addresses:all دارد بدون هیچ اعطایی به همهٔ نشانیها میرسد، از جمله نشانیهایی که بعداً افزوده میشوند، و فقط یک شخص در برنامه میتواند آن را روی یک نقش بگذارد.
بهجای builtin یا نام، روی editable و deletable شاخه بزنید. هر دو تنها برای مالک false هستند، که فهرستش «هر مجوزی، از جمله مجوزهایی که سال آینده ساخته میشوند» است و محاسبه میشود نه ذخیره. هر نقش دیگری به هر دو true پاسخ میدهد، از جمله همان پنج نقشی که فضای کاری با آنها آغاز میشود. نقشی که کسی نامش را عوض کرده همچنان به هر دو درست پاسخ میدهد، و نامش دیگر چیزی به شما نمیگوید.
update فهرست مجوزها را «جایگزین» میکند. فراخوانیای برای اعطای تکی وجود ندارد، پس نقش را بخوانید، مدخلی را که در نظر داشتید تغییر دهید و همه را پس بفرستید، همانطور که [...$support['permissions'], ApiScopes::TEMPLATES_READ] در بالا انجام میدهد. فرستادن یک مجوز، نقش را فقط با همان یک مجوز بهعلاوهٔ هر چه آن را در پی دارد باقی میگذارد.
به محض آنکه کسی نقش را داشته باشد، delete به reassignTo: نیاز دارد. کلاینت آن را بهصورت پارامتر کوئری reassignTo میفرستد، چون بدنه روی DELETE در چندین محیط اجرا و شماری از پراکسیها کنار گذاشته میشود، و وقتی چیزی ندهید این پارامتر را نمیفرستد. نتیجه، reassigned و keysReassigned را جداگانه گزارش میکند، تا یک اسکریپت بتواند آنچه را انجام داده ثبت کند نه آنچه را خواسته.
listPermissions همان GET /roles/permissions است، مسیری ثابت که دقیقاً جایی نشسته که شناسهٔ نقش قرار میگرفت. کلاینت آن مسیر را مستقیماً فراخوانی میکند نه اینکه این واژه را از راه get بفرستد، و یک فهرست ساده برمیگرداند، نه یک OpenEmail\Result\Page: یک آرایه برای هر مجوز، با id، label، group و scope. scope برابر false مدخلهایی را نشان میدهد که هیچ کلیدی هرگز نمیتواند داشته باشد. خودتان این واژه را به get ندهید. $client->roles->get('permissions') همان مسیر را میسازد، پس همان درخواست را میفرستد و بهجای یک نقش یا یک 404، واژگان مجوزها را در پاکت فهرستش پس میگیرد.
نقش، سقفِ یک کلید است
کلیدی که برای یک نقش صادر شده، فقط «اشتراکِ» اسکوپهای خودش با مجوزهای آن نقش را میتواند انجام دهد، که در هر درخواست در مرز سیستم محاسبه میشود. پس باریک کردن یک نقش، دسترسی کلیدهایش را در لحظه پس میگیرد، بیآنکه هیچکدام چرخانده شوند. کلیدی که نقشی ندارد اصلاً سقفی ندارد، و همین roleId برابر null را گستردهترین وضعیتی میکند که یک کلید میتواند داشته باشد، نه باریکترین.
به همین دلیل هم هست که roles->delete اصرار دارد جایی برای انتقال کلیدها وجود داشته باشد. بیسرپرست گذاشتنشان سقفشان را یکسره برمیداشت و هر اعتبارنامهای را که آن نقش محدودش میکرد بیصدا ارتقا میداد.
GET /keys/self و GET /ping مقدارهای roleId و grantedScopes را کنار scopes مؤثر گزارش میکنند. اینگونه است که به «کلید من emails:send دارد و insufficient_scope میگیرم» پاسخ داده میشود: هر چیزی که در grantedScopes هست و در scopes نیست، را نقش گرفته است. $client->me->get() و $client->me->ping() هر دو را در آرایهٔ خود برمیگردانند، پس array_diff($key['grantedScopes'], $key['scopes']) آنچه را نقش گرفته فهرست میکند. خودِ رد شدن یک PermissionException است که isScopeMissing() آن true است.
پارامترها
namestringالزامی- نامی که فضای کاری روی نقش میگذارد: 1 تا 48 نویسه، که پیش از ذخیره فاصلههای دو سرش حذف میشود. نامها در هر فضای کاری بدون توجه به بزرگی و کوچکی حروف یکتا هستند، پس «Support» دوم بهجای آنکه کنار اولی ساخته شود با `role_name_taken` (409) رد میشود که بهصورت `ConflictException` پرتاب میشود.
descriptionstring- جملهای که میگوید نقش برای چیست، با حذف فاصلههای دو سر و حداکثر 240 نویسه. رشتهای که پس از این حذف خالی باشد بهصورت null ذخیره میشود، پس توضیحی که فقط از فاصله ساخته شده بهجای آنچه فرستادهاید بهصورت null برمیگردد. در `create`، بهجای دادن null این کلید را ننویسید: کلاینت مقدار null را همانطور میفرستد، و `create` آن را با یک 422 رد میکند. در `update`، `'description' => null` آن را پاک میکند.
permissionsarrayالزامی- آنچه نقش اعطا میکند، برگرفته از واژگانی که `listPermissions` ارائه میدهد. Stringی که در آن نباشد بهجای آنکه بیصدا کنار گذاشته شود، یک 422 روی `permissions` است که بهصورت `ValidationException` با `param` برابر `permissions` پرتاب میشود، پس غلط تایپی گزارش میشود بهجای آنکه یک بعدازظهر از وقت شما را بگیرد. فهرست هنگام ورود «گسترش» مییابد (`templates:write` در کنار خود `templates:read` را هم ذخیره میکند)، تکراریهایش حذف میشوند و به ترتیب متعارف برگردانده میشود، پس فهرست ذخیرهشده را از روی پاسخ بخوانید نه اینکه فرض کنید همانی است که فرستادهاید.
پاسخ
objectstring- همیشه `role`. نشانهٔ حذف (tombstone) با همین مقدار، `id` نقش، `deleted` برابر true و دو شمارندهٔ واگذاری پاسخ میدهد، و هیچیک از فیلدهای دیگرِ زیر را ندارد.
idstring- شناسهٔ نقش، که به شکل `$role['id']` خوانده میشود. همان چیزی است که `roleId` یک عضو نام میبرد، همان چیزی که سقف یک کلید API به آن اشاره میکند، و همان چیزی که `reassignTo:` میگیرد وقتی نقش دیگری حذف میشود و دارندگانش به این نقش منتقل میشوند.
namestring- نام فضای کاری برای این نقش، با حذف فاصلههای دو سر و یکتا بدون توجه به بزرگی و کوچکی حروف. هر نقشی جز نقش مالک را میتوان تغییر نام داد، از جمله نقشهای آغازین (`builtin` میگوید یک ردیف از کجا آمده، نه اینکه باید چه نامی بماند)، پس نقشی به نام «Admin» چیز قطعیای دربارهٔ آنچه دارد نمیگوید. نامی که نقش دیگری از پیش دارد `role_name_taken` است (409، با `param` برابر `name`). تغییر نام مالک `role_immutable` است (409)، مانند هر ویرایش دیگری روی آن.
descriptionstring or null- جملهای که نقش را توصیف میکند، یا وقتی چیزی داده نشده باشد null. ورودی خالی در هر دو create و update بهصورت null ذخیره میشود، پس این هرگز رشتهٔ خالی نیست.
permissionsarray- هر آنچه نقش اعطا میکند، از پیش گسترشیافته و به ترتیب متعارف، نه به ترتیبی که کسی تایپ کرده است. این ترتیب اهمیت اساسی دارد: دو نقش با مجوزهای یکسان آرایههای برابر دارند، و همین است که به صفحهٔ تنظیمات اجازه میدهد آنها را با `===` مقایسه کند تا تصمیم بگیرد دکمهٔ ذخیره فعال باشد یا نه.
builtinstring or null- اینکه این ردیف از کدامیک از شش نقش آغازین آمده است، `owner`، `admin`، `member`، `viewer`، `developer` یا `billing`، یا null برای نقشی که خودِ فضای کاری نوشته. این فیلد خاستگاه را ثبت میکند نه یک وضعیت را: یک نقش آغازین هم مثل هر نقش دیگری تغییر نام میدهد، مجوزهایش عوض میشود و حذف میشود. بهجای این، روی `editable` و `deletable` شاخه بزنید. نقشی که کسی «Admin» نامیده لازم نیست همان نقش آغازین باشد، و نقش آغازین ممکن است دیگر این نام را نداشته باشد.
editablebool- بهصورت `builtin !== 'owner'` محاسبه میشود، پس تنها برای نقش مالک false است، و هر `update` روی آن نقش با `role_immutable` (409) رد میشود. هر نقش دیگری بهطور کامل قابل ویرایش است (نام، توضیح و مجوزها)، از جمله همان پنج نقشی که فضای کاری با آنها آغاز میشود.
deletablebool- بهصورت `builtin !== 'owner'` محاسبه میشود: تنها برای نقش مالک false است، که با `role_undeletable` (409) برمیگردد، و برای هر نقش دیگری از جمله نقشهای آغازین true. پیش از نمایش دکمه آن را بررسی کنید نه پس از رد شدن. نقشی که هنوز کسی آن را دارد به `reassignTo:` هم نیاز دارد، وگرنه حذف `role_in_use` (409) است. هر دو رد شدن بهصورت `ConflictException` پرتاب میشوند، و `errorCode` آنها را از هم جدا میکند.
membersint- چند نفر این نقش را دارند، شمردهشده از ردیفهای اعضای فضای کاری. مالک میان آنها نیست: او ردیف عضویت ندارد و نمیتوان به او نقش داد، پس نقش Owner صفر دارنده گزارش میکند، هرچند فهرست اعضا او را نشان میدهد.
apiKeysint- چند کلید API فعال زیر سقف این نقش هستند. کلیدهای باطلشده در شمارش نمیآیند، هرچند حذف، هر ردیف کلیدی را که به نقش اشاره میکند، از جمله باطلشدهها، به نقش تازه منتقل میکند. این دومین گروهی است که پیش از رفتن نقش باید منتقل شود، و همانی که کسی متوجهش نمیشود: کلیدها برنامهاند، و برنامه شکایت نمیکند.
createdAtstring- زمان نوشته شدن ردیف نقش، بهصورت یک رشته با قالب ISO 8601. ردیفهای درونساخت در نخستین باری که چیزی به آنها نیاز دارد ساخته میشوند، مانند خواندن فهرست نقشها، ساختن یک نقش یا صفحهٔ کلیدهای API، نه هنگام ساخت فضای کاری. پس مهر زمانی یک نقش درونساخت، زمان رسیدن همان نخستین درخواست است نه زمان ساخته شدن فضای کاری.
updatedAtstring- زمان آخرین تغییر نقش، بهصورت یک رشته با قالب ISO 8601. هر `update` پذیرفتهشده آن را جلو میبرد، حتی آن یکی که فیلدی را به همان مقداری که داشته تنظیم کند.