भूमिकाएँ
`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 हर भूमिका एक array में लौटाता है, और iterate एक Generator लौटाता है जो एक बार में एक भूमिका yield करता है। भूमिका camelCase कुंजियों वाले array के रूप में लौटती है, इसलिए $role['permissions'] सूची पढ़ता है। create और update बॉडी को API के नामों वाले एक array के रूप में लेते हैं, जबकि delete reassignTo: को named आर्ग्युमेंट के रूप में लेता है।
भूमिका बताती है कि कोई क्या “कर” सकता है। वह किन “पतों” पर कर सकता है, यह दूसरी धुरी है और $client->members पर रहती है: “सदस्य” पेज पर members->grantAddress और members->revokeAddress देखें। “मेल भेज सकता है” और “invoices@ से भेज सकता है” अलग वाक्य हैं, और जो वर्कस्पेस दूसरा सपोर्ट एजेंट रखता है वह पहले को छुए बिना दूसरे को बदलता है। एक अनुमति दोनों का जवाब देती है: addresses:all वाली भूमिका बिना किसी grant के हर पते तक पहुँचती है, बाद में जोड़े गए पतों समेत, और इसे भूमिका पर सिर्फ़ ऐप में मौजूद व्यक्ति ही लगा सकता है।
शाखा builtin या नाम पर नहीं, editable और deletable पर बनाएँ। दोनों सिर्फ़ मालिक के लिए false हैं, जिसकी सूची “हर अनुमति, अगले साल बनने वाली अनुमतियों समेत” है और सहेजी नहीं, गणना की जाती है। हर दूसरी भूमिका दोनों का जवाब true देती है, वर्कस्पेस की शुरुआती पाँच भूमिकाओं समेत। जिस भूमिका का नाम किसी ने बदला हो वह फिर भी दोनों का सही जवाब देती है, और उसका नाम अब आपको कुछ नहीं बताता।
update अनुमति सूची को “बदल” देता है। एक-एक अनुमति देने वाली कोई कॉल नहीं है, इसलिए भूमिका पढ़ें, जिस प्रविष्टि का इरादा था उसे बदलें और सभी को वापस भेजें, जैसा ऊपर [...$support['permissions'], ApiScopes::TEMPLATES_READ] करता है। एक अनुमति भेजने पर भूमिका के पास ठीक वही एक रह जाती है, साथ में वह सब जो उससे निहित है।
जैसे ही किसी के पास भूमिका हो, delete को reassignTo: चाहिए। क्लाइंट इसे reassignTo query पैरामीटर के रूप में भेजता है, क्योंकि DELETE पर बॉडी को कई runtimes और कई proxies छोड़ देते हैं, और कुछ न पास करने पर पैरामीटर छोड़ देता है। नतीजा reassigned और keysReassigned अलग-अलग बताता है, ताकि स्क्रिप्ट वह log कर सके जो उसने किया, न कि जो उसने माँगा।
listPermissions GET /roles/permissions है, एक तय path जो ठीक वहाँ बैठा है जहाँ भूमिका की id आती। क्लाइंट शब्द को get से गुज़ारने के बजाय उस path को सीधे कॉल करता है, और OpenEmail\Result\Page नहीं, बल्कि एक सादी सूची लौटाता है: हर permission के लिए एक array, id, label, group और scope के साथ। scope false उन प्रविष्टियों को चिह्नित करता है जिन्हें कोई कुंजी कभी नहीं रख सकती। शब्द को ख़ुद get में पास न करें। $client->roles->get('permissions') वही path बनाता है, इसलिए वह वही रिक्वेस्ट भेजता है और भूमिका या 404 के बजाय शब्दावली को उसके सूची envelope में वापस पाता है।
role किसी key की छत है
किसी भूमिका के तहत जारी कुंजी अपने scopes और उस भूमिका की permissions के “प्रतिच्छेद” तक ही काम कर सकती है, जो हर रिक्वेस्ट पर सीमा पर तय होता है। इसलिए किसी भूमिका को सीमित करने से उसकी कुंजियाँ तुरंत सीमित हो जाती हैं, उनमें से किसी को rotate किए बिना। बिना भूमिका वाली कुंजी की कोई ऊपरी सीमा नहीं होती, जिससे null roleId कुंजी की सबसे संकीर्ण नहीं, बल्कि सबसे व्यापक स्थिति बन जाती है।
यही वजह है कि roles->delete इस बात पर अड़ता है कि keys को कहीं और ले जाया जाए। उन्हें अनाथ छोड़ना उनकी छत पूरी तरह हटा देता, और role जिन क्रेडेंशियल को सीमित कर रही थी उन सबको चुपचाप पदोन्नत कर देता।
GET /keys/self और GET /ping प्रभावी scopes के साथ roleId और grantedScopes बताते हैं। “मेरी कुंजी में emails:send है और मुझे insufficient_scope मिल रहा है” का जवाब इसी से मिलता है: जो कुछ grantedScopes में है और scopes में नहीं, उसे भूमिका ने ले लिया। $client->me->get() और $client->me->ping() दोनों को अपने array में लौटाते हैं, इसलिए array_diff($key['grantedScopes'], $key['scopes']) बताता है कि भूमिका ने क्या लिया। अस्वीकार ख़ुद एक PermissionException है जिसका isScopeMissing() true होता है।
पैरामीटर
namestringआवश्यक- वर्कस्पेस भूमिका को क्या कहता है: 1 से 48 अक्षर, सहेजने से पहले trim किए गए। नाम हर वर्कस्पेस में case की परवाह किए बिना अनोखे होते हैं, इसलिए दूसरा “Support” पहले वाले के साथ बनाए जाने के बजाय `role_name_taken` (409) के साथ अस्वीकार होता है, जो `ConflictException` के रूप में throw होता है।
descriptionstring- भूमिका किसलिए है यह बताने वाला एक वाक्य, trim किया हुआ और अधिकतम 240 अक्षर। जो स्ट्रिंग trim के बाद ख़ाली हो वह null के रूप में सहेजी जाती है, इसलिए सिर्फ़ खाली जगहों वाला विवरण आपके भेजे हुए के बजाय null के रूप में लौटता है। `create` पर null पास करने के बजाय कुंजी छोड़ दें: क्लाइंट null को वैसे ही भेजता है, और `create` उसे 422 के साथ अस्वीकार करता है। `update` पर `'description' => null` इसे हटा देता है।
permissionsarrayआवश्यक- भूमिका क्या देती है, `listPermissions` द्वारा दी गई शब्दावली से लिया गया। जो स्ट्रिंग उसमें नहीं है वह चुपचाप हटाए जाने के बजाय `permissions` पर 422 है, जो `param` में `permissions` वाले `ValidationException` के रूप में throw होता है, ताकि टाइपो आपकी पूरी दोपहर बर्बाद करने के बजाय रिपोर्ट हो। सूची आते समय “फैलाई” जाती है (`templates:write` अपने साथ `templates:read` भी सहेजता है), दोहराव हटाए जाते हैं और उसे मानक क्रम में वापस रखा जाता है, इसलिए यह मानने के बजाय कि यह वही है जो आपने भेजा, सहेजी गई सूची जवाब से पढ़ें।
प्रतिक्रिया
objectstring- हमेशा `role`। delete का tombstone इसी मान, भूमिका की `id`, true पर सेट `deleted` और दो पुनर्नियुक्ति गिनतियों के साथ जवाब देता है, और नीचे के बाकी फ़ील्ड में से कोई नहीं।
idstring- भूमिका की id, `$role['id']` के रूप में पढ़ी जाती है। यही वह है जिसका नाम सदस्य का `roleId` लेता है, जिसकी ओर API कुंजी की ऊपरी सीमा इशारा करती है, और जिसे `reassignTo:` लेता है जब कोई दूसरी भूमिका हटाई जाती है और उसके धारक इस पर आ जाते हैं।
namestring- भूमिका के लिए वर्कस्पेस का नाम, trim किया हुआ और case की परवाह किए बिना अनोखा। मालिक की भूमिका के अलावा हर भूमिका का नाम बदला जा सकता है, पहले से बनी भूमिकाओं समेत (`builtin` बताता है कि पंक्ति कहाँ से आई, न कि उसे किस नाम से बने रहना है), इसलिए “Admin” नाम की भूमिका पक्के तौर पर कुछ नहीं बताती कि उसके पास क्या है। जो नाम कोई दूसरी भूमिका पहले से रखती है वह `role_name_taken` है (409, `param` में `name`)। मालिक का नाम बदलना, उसके हर दूसरे बदलाव की तरह, `role_immutable` (409) है।
descriptionstring or null- role का वर्णन करने वाला वाक्य, या null जब कोई नहीं दिया गया। खाली इनपुट create और update दोनों पर null के रूप में संग्रहीत होता है, इसलिए यह कभी खाली string नहीं होता।
permissionsarray- भूमिका जो कुछ देती है, पहले से फैलाया हुआ और किसी के टाइप किए क्रम के बजाय मानक क्रम में। यह क्रम अहम है: एक जैसी permissions वाली दो भूमिकाएँ बराबर arrays रखती हैं, जिससे सेटिंग्स स्क्रीन उन्हें `===` से तुलना करके तय कर पाती है कि Save सक्षम हो या नहीं।
builtinstring or null- यह पंक्ति पहले से बनी छह भूमिकाओं में से किससे आई, `owner`, `admin`, `member`, `viewer`, `developer` या `billing`, या वर्कस्पेस द्वारा ख़ुद लिखी भूमिका के लिए null। यह मूल को दर्ज करता है, किसी स्थिति को नहीं: पहले से बनी भूमिका का नाम, permissions और अस्तित्व किसी भी दूसरी भूमिका की तरह बदले जाते हैं। इस पर नहीं, बल्कि `editable` और `deletable` पर branch करें। किसी द्वारा “Admin” नाम दी गई भूमिका ज़रूरी नहीं कि पहले से बनी वाली हो, और पहले से बनी वाली का नाम अब शायद वह न हो।
editablebool- `builtin !== 'owner'` के रूप में गणना की जाती है, इसलिए यह सिर्फ़ मालिक की भूमिका के लिए false है, और उस भूमिका का हर `update` `role_immutable` (409) के साथ अस्वीकार होता है। हर दूसरी भूमिका पूरी तरह संपादन योग्य है (नाम, विवरण और अनुमतियाँ), वर्कस्पेस की शुरुआती पाँच भूमिकाओं समेत।
deletablebool- `builtin !== 'owner'` के रूप में गणना की जाती है: सिर्फ़ मालिक की भूमिका के लिए false, जो `role_undeletable` (409) लौटाती है, और पहले से बनी भूमिकाओं समेत हर दूसरी भूमिका के लिए true। अस्वीकार के बाद नहीं, बल्कि बटन दिखाने से पहले इसे जाँचें। जो भूमिका अब भी किसी के पास है उसे `reassignTo:` भी चाहिए, वरना delete `role_in_use` (409) है। दोनों अस्वीकार `ConflictException` के रूप में throw होते हैं, और `errorCode` उन्हें अलग बताता है।
membersint- कितने लोग यह भूमिका रखते हैं, वर्कस्पेस की सदस्य पंक्तियों से गिना गया। मालिक उनमें नहीं है: उसकी कोई सदस्य पंक्ति नहीं होती और उसे भूमिका नहीं दी जा सकती, इसलिए Owner भूमिका शून्य धारक बताती है, भले ही सदस्य सूची उसे दिखाए।
apiKeysint- कितनी सक्रिय API कुंजियाँ इस भूमिका से सीमित हैं। रद्द की गई कुंजियाँ गिनती से बाहर रहती हैं, हालाँकि delete भूमिका की ओर इशारा करने वाली हर कुंजी पंक्ति को, रद्द की गई समेत, दूसरी ओर मोड़ देता है। यह दूसरी आबादी है जिसे भूमिका हटने से पहले खिसकाना पड़ता है, और जिस पर किसी का ध्यान नहीं जाता: कुंजियाँ प्रोग्राम हैं, और प्रोग्राम शिकायत नहीं करता।
createdAtstring- भूमिका की पंक्ति कब लिखी गई, ISO 8601 स्ट्रिंग के रूप में। built-in पंक्तियाँ वर्कस्पेस बनते समय नहीं, बल्कि पहली बार किसी चीज़ को उनकी ज़रूरत होने पर बनाई जाती हैं, जैसे भूमिकाओं की सूची पढ़ना, भूमिका बनाना या API-key स्क्रीन। इसलिए built-in का timestamp वह समय है जब वह पहली रिक्वेस्ट आई, न कि जब वर्कस्पेस बना।
updatedAtstring- भूमिका आख़िरी बार कब बदली, ISO 8601 स्ट्रिंग के रूप में। हर स्वीकार किया गया `update` इसे आगे बढ़ाता है, उसमें वह भी शामिल है जो किसी फ़ील्ड को उसी मान पर सेट करे जो उसके पास पहले से था।