भूमिकाएँ
`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 हर भूमिका को block में yield करता है या block के बिना एक Enumerator लौटाता है। भूमिका Symbol कुंजियों वाले Hash के रूप में लौटती है, इसलिए role[:permissions] सूची पढ़ता है। create और update बॉडी के फ़ील्ड keywords या एक Hash के रूप में लेते हैं, जबकि delete reassign_to: लेता है, एक snake_case keyword जिसका नाम gem API के लिए बदल देता है।
भूमिका बताती है कि कोई क्या “कर” सकता है। वह किन “पतों” पर कर सकता है, यह दूसरी धुरी है और client.members पर रहती है: “सदस्य” पेज पर grant_address और revoke_address देखें। “मेल भेज सकता है” और “invoices@ से भेज सकता है” अलग वाक्य हैं, और जो वर्कस्पेस दूसरा सपोर्ट एजेंट रखता है वह पहले को छुए बिना दूसरे को बदलता है। एक अनुमति दोनों का जवाब देती है: addresses:all वाली भूमिका बिना किसी grant के हर पते तक पहुँचती है, बाद में जोड़े गए पतों समेत, और इसे भूमिका पर सिर्फ़ ऐप में मौजूद व्यक्ति ही लगा सकता है।
शाखा builtin या नाम पर नहीं, editable और deletable पर बनाएँ। दोनों सिर्फ़ मालिक के लिए false हैं, जिसकी सूची “हर अनुमति, अगले साल बनने वाली अनुमतियों समेत” है और सहेजी नहीं, गणना की जाती है। हर दूसरी भूमिका दोनों का जवाब true देती है, वर्कस्पेस की शुरुआती पाँच भूमिकाओं समेत। जिस भूमिका का नाम किसी ने बदला हो वह फिर भी दोनों का सही जवाब देती है, और उसका नाम अब आपको कुछ नहीं बताता।
update अनुमति सूची को “बदल” देता है। एक-एक अनुमति देने वाली कोई कॉल नहीं है, इसलिए भूमिका पढ़ें, जिस प्रविष्टि का इरादा था उसे बदलें और सभी को वापस भेजें, जैसा ऊपर [*support[:permissions], "templates:read"] करता है। एक अनुमति भेजने पर भूमिका के पास ठीक वही एक रह जाती है, साथ में वह सब जो उससे निहित है।
जैसे ही किसी के पास भूमिका हो, delete को reassign_to: चाहिए। gem इसे reassignTo query पैरामीटर के रूप में भेजता है, क्योंकि DELETE पर बॉडी को कई runtime और कई proxies हटा देते हैं, और कुछ पास न करने पर यह पैरामीटर छोड़ देता है। नतीजा reassigned और keysReassigned अलग-अलग बताता है, ताकि स्क्रिप्ट वह लॉग कर सके जो उसने किया, न कि जो उसने माँगा।
list_permissions GET /roles/permissions है, एक तय path जो ठीक वहाँ बैठा है जहाँ भूमिका की id आती। gem इस शब्द को get से भेजने के बजाय सीधे उस path को कॉल करता है, और OpenEmail::Page नहीं, एक सादी Array लौटाता है: हर अनुमति के लिए id, label, group और scope वाला एक Hash। scope: false उन प्रविष्टियों को चिह्नित करता है जो कोई कुंजी कभी नहीं रख सकती। यह शब्द ख़ुद get को पास न करें। client.roles.get("permissions") वही path बनाता है, इसलिए वही रिक्वेस्ट भेजता है और भूमिका या 404 के बजाय अनुमतियों की शब्दावली वापस पाता है।
role किसी key की छत है
किसी भूमिका के तहत जारी कुंजी अपने scopes और उस भूमिका की अनुमतियों का “प्रतिच्छेद” ही कर सकती है, जो हर रिक्वेस्ट पर सीमा पर तय होता है। इसलिए भूमिका को संकरा करना उसकी कुंजियों की पहुँच तुरंत वापस ले लेता है, बिना किसी को rotate किए। बिना भूमिका वाली कुंजी की कोई ऊपरी सीमा ही नहीं होती, जिससे nil 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 दोनों अपने Hash में लौटाते हैं, इसलिए key[:grantedScopes] - key[:scopes] बताता है कि भूमिका ने क्या लिया। अस्वीकार ख़ुद एक OpenEmail::PermissionError है जिसका scope_missing? true है।
पैरामीटर
nameStringआवश्यक- वर्कस्पेस भूमिका को क्या कहता है: 1 से 48 वर्ण, सहेजने से पहले trim किया गया। नाम हर वर्कस्पेस में case की परवाह किए बिना अनोखे होते हैं, इसलिए दूसरा “Support” पहले के साथ बनाए जाने के बजाय `role_name_taken` (409) के साथ अस्वीकार होता है, जो `OpenEmail::ConflictError` के रूप में raise होता है।
descriptionString- एक वाक्य जो बताता है कि भूमिका किस लिए है, trim किया गया और अधिकतम 240 वर्ण। trim के बाद ख़ाली String nil के रूप में सहेजी जाती है, इसलिए सिर्फ़ ख़ाली जगहों वाला विवरण आपके भेजे के बजाय nil के रूप में लौटता है। `create` पर nil पास करने के बजाय इसे छोड़ दें: gem nil को वैसा ही भेजता है, और `create` उसे 422 के साथ अस्वीकार करता है। `update` पर `description: nil` इसे साफ़ कर देता है।
permissionsArray<String>आवश्यक- भूमिका क्या देती है, उस शब्दावली से जो `list_permissions` देता है। जो String उसमें नहीं है वह चुपचाप हटाए जाने के बजाय `permissions` पर 422 है, जो `param` को `permissions` रखते हुए `OpenEmail::ValidationError` के रूप में raise होता है, इसलिए टाइपो की सूचना मिल जाती है बजाय इसके कि वह आपकी पूरी दोपहर ले ले। सूची अंदर आते समय “विस्तारित” होती है (`templates:write` अपने साथ `templates:read` भी सहेजता है), दोहराव हटाए जाते हैं और मानक क्रम में वापस रखी जाती है, इसलिए यह मानने के बजाय कि यह वही है जो आपने भेजा, सहेजी गई सूची जवाब से पढ़ें।
प्रतिक्रिया
objectString- हमेशा `role`। delete का tombstone इसी मान, भूमिका की `id`, `deleted: true` और दोनों reassignment गिनतियों के साथ जवाब देता है, और नीचे का कोई दूसरा फ़ील्ड नहीं होता।
idString- भूमिका की id, `role[:id]` के रूप में पढ़ी जाती है। यही वह है जिसका नाम सदस्य का `roleId` लेता है, जिसकी ओर API कुंजी की ऊपरी सीमा इशारा करती है, और जिसे `reassign_to:` लेता है जब कोई दूसरी भूमिका हटाई जाती है और उसके धारक इस पर आ जाते हैं।
nameString- भूमिका के लिए वर्कस्पेस का नाम, trim किया गया और case की परवाह किए बिना अनोखा। मालिक की भूमिका को छोड़ हर भूमिका का नाम बदला जा सकता है, शुरुआती भूमिकाओं समेत (`builtin` बताता है कि पंक्ति कहाँ से आई, यह नहीं कि उसका नाम क्या रहना चाहिए), इसलिए “Admin” को इस बात का वादा न समझें कि भूमिका के पास क्या है। जो नाम कोई दूसरी भूमिका पहले से रखती है वह `role_name_taken` है (409, `param` को `name` रखते हुए)। मालिक का नाम बदलना `role_immutable` है (409), उसके हर दूसरे संपादन की तरह।
descriptionString or nil- भूमिका का वर्णन करने वाला वाक्य, या nil अगर कोई न दिया गया हो। ख़ाली इनपुट create और update दोनों पर nil के रूप में सहेजा जाता है, इसलिए यह कभी ख़ाली स्ट्रिंग नहीं होता।
permissionsArray<String>- भूमिका जो कुछ देती है, पहले से विस्तारित और मानक क्रम में, न कि उस क्रम में जिसमें किसी ने टाइप किया। यह क्रम अहम है: एक जैसी अनुमतियों वाली दो भूमिकाओं की Arrays बराबर होती हैं, और इसी से सेटिंग्स स्क्रीन उन्हें `==` से तुलना करके तय कर पाती है कि Save सक्षम हो या नहीं।
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:` भी चाहिए, वरना delete `role_in_use` (409) है। दोनों अस्वीकार `OpenEmail::ConflictError` के रूप में raise होते हैं, और `code` उन्हें अलग बताता है।
membersInteger- कितने लोग यह भूमिका रखते हैं, वर्कस्पेस की सदस्य पंक्तियों से गिना गया। मालिक उनमें नहीं है: उसकी कोई सदस्य पंक्ति नहीं होती और उसे भूमिका नहीं दी जा सकती, इसलिए Owner भूमिका शून्य धारक बताती है, भले ही सदस्य सूची उसे दिखाए।
apiKeysInteger- कितनी सक्रिय API कुंजियाँ इस भूमिका से सीमित हैं। रद्द की गई कुंजियाँ गिनती से बाहर रहती हैं, हालाँकि delete भूमिका की ओर इशारा करने वाली हर कुंजी पंक्ति को, रद्द की गई समेत, दूसरी ओर मोड़ देता है। यह दूसरी आबादी है जिसे भूमिका हटने से पहले खिसकाना पड़ता है, और जिस पर किसी का ध्यान नहीं जाता: कुंजियाँ प्रोग्राम हैं, और प्रोग्राम शिकायत नहीं करता।
createdAtString- भूमिका पंक्ति कब लिखी गई, ISO 8601 String के रूप में। built-in पंक्तियाँ आलस्य से, पहली बार किसी चीज़ को उनकी ज़रूरत पड़ने पर बनती हैं, जैसे भूमिका सूची पढ़ना, भूमिका बनाना या API कुंजी स्क्रीन, वर्कस्पेस बनते समय नहीं। इसलिए built-in भूमिका का timestamp वह समय है जब वह पहली रिक्वेस्ट पहुँची, न कि जब वर्कस्पेस बना।
updatedAtString- भूमिका आख़िरी बार कब बदली, ISO 8601 String के रूप में। हर स्वीकृत `update` इसे आगे बढ़ाता है, वह भी जो किसी फ़ील्ड को उसी मान पर सेट करे जो उसका पहले से था।