কীভাবে একজন ব্যবহারকারী সদস্য হিসাবে (উত্তরাধিকারী ভূমিকা সহ) সমস্ত ভূমিকা পালন করবেন?


23

ধরা যাক আমার দুটি পোস্টগ্র্যাস্কল ডাটাবেস গ্রুপ, "লেখক" এবং "সম্পাদক" এবং দুটি ব্যবহারকারী "ম্যাক্সওয়েল" এবং "আর্নেস্ট" রয়েছে।

create role authors;

create role editors;

create user maxwell;

create user ernest;

grant authors to editors; --editors can do what authors can do

grant editors to maxwell; --maxwell is an editor

grant authors to ernest; --ernest is an author

আমি এমন একটি পারফরম্যান্ট ফাংশন লিখতে চাই যা ম্যাক্সওয়েলের অন্তর্ভুক্ত ভূমিকার (সাধারণত তাদের মঞ্জুরীর) একটি তালিকা ফেরত দেয়:

create or replace function get_all_roles() returns oid[] ...

এটি ম্যাক্সওয়েল, লেখক এবং সম্পাদকদের (তবে আর্জেস্ট নয়) এর জন্য মেশিনগুলি ফিরিয়ে আনতে হবে।

তবে উত্তরাধিকার থাকলে কীভাবে এটি করা যায় তা আমি নিশ্চিত নই।

উত্তর:


23

আপনি বিশেষত বিশেষত : পুনরাবৃত্ত হওয়া ক্যোয়ারী সহ সিস্টেম ক্যাটালগটি প্রশ্ন করতে পারেন pg_auth_members:

WITH RECURSIVE cte AS (
   SELECT oid FROM pg_roles WHERE rolname = 'maxwell'

   UNION ALL
   SELECT m.roleid
   FROM   cte
   JOIN   pg_auth_members m ON m.member = cte.oid
)
SELECT oid FROM cte;

বিটিডাব্লু, INHERITহ'ল CREATE ROLEএটির ডিফল্ট আচরণ এবং তা বানান করতে হবে না।

বিটিডাব্লু 2: বিজ্ঞপ্তি নির্ভরতা সম্ভব নয়। পোস্টগ্রাগেস তা অস্বীকার করে। সুতরাং আমাদের এটি পরীক্ষা করতে হবে না।


18

সংক্ষিপ্ত সংস্করণ:

SELECT a.oid 
FROM pg_authid a 
WHERE pg_has_role('maxwell', a.oid, 'member');

এখানে আমরা এর pg_has_roleএমন একটি সংস্করণ ব্যবহার করি যা সদস্যতার জন্য পরীক্ষার জন্য বিষয় হিসাবে ভূমিকা এবং ভূমিকা হিসাবে ভূমিকা রাখে , memberমোড পাস করে আমরা উত্তরাধিকার সূত্রে সদস্যতার জন্য পরীক্ষা করি।

ব্যবহারের সুবিধা pg_has_roleহ'ল এটি সদস্যপদ অনুসন্ধানগুলি দ্রুত পূরণ করতে পোস্টগ্র্রেএসকিউএল এর ভূমিকা তথ্যের অভ্যন্তরীণ ক্যাশেগুলি ব্যবহার করে।

অ্যাক্সেস সীমাবদ্ধ করার SECURITY DEFINERকারণে আপনি pg_authidএটি কোনও ফাংশনে মুড়িয়ে রাখতে চাইতে পারেন । কিছুটা এইরকম:

CREATE OR REPLACE FUNCTION user_role_memberships(text)
RETURNS SETOF oid
LANGUAGE sql
SECURITY DEFINER
SET search_path = pg_catalog, pg_temp
AS $$
SELECT a.oid 
FROM pg_authid a 
WHERE pg_has_role($1, a.oid, 'member');
$$;

REVOKE EXECUTE ON FUNCTION user_role_memberships(text) FROM public;

GRANT EXECUTE ON FUNCTION user_role_memberships(text) TO ...whoever...;

আপনি pg_get_userbyid(oid)জিজ্ঞাসা করার প্রয়োজন ছাড়াই ওড থেকে ভূমিকাটির নামটি পেতে ব্যবহার করতে পারেন pg_authid:

SELECT a.oid AS member_oid, pg_get_userbyid(oid) AS member_name
FROM pg_authid a 
WHERE pg_has_role('maxwell', a.oid, 'member');

2
যাইহোক +1, যেহেতু pg_has_role()সম্ভবত আমার পুনরাবৃত্ত ক্যোয়ারির চেয়ে কিছুটা দ্রুত, এমনকি যদি এটি খুব কমই গুরুত্বপূর্ণ। যদিও একটি শেষ জিনিস: এটি সুপারসুসারদের জন্য সমস্ত ভূমিকা ফেরত দেয়, যা স্বাগত পার্শ্ব প্রতিক্রিয়া হতে পারে বা নাও পারে। ফলাফলটি আমার প্রশ্নের থেকে পৃথক from
এরউইন ব্র্যান্ডসেটেটার

16

এটি ক্রেগ রিঞ্জারের উত্তরের সরলিকৃত সংস্করণ যা কোনও নন সুপারভাইজার সরাসরি ব্যবহার করতে পারে:

 SELECT oid, rolname FROM pg_roles WHERE
   pg_has_role( 'maxwell', oid, 'member');

pg_rolesমূলত pg_authidজনসাধারণের কাছে অ্যাক্সেসযোগ্য এমন একটি দৃষ্টিভঙ্গি , কারণ এটি বিপরীতে পাসওয়ার্ডগুলি প্রকাশ করে না pg_authid। বেস oidএমনকি দৃশ্যে রপ্তানি করা হয়। যখন পাসওয়ার্ডের প্রয়োজন হবে না, তখন উত্সর্গীকৃত অতি ব্যবহারকারী-মালিকানাধীন ক্রিয়াকলাপটি তৈরি করার কোনও মানে নেই।


3

এটি আমার গ্রহণ এখানে। এটি একটি নির্দিষ্ট ব্যবহারকারী বা সকল ব্যবহারকারীর জন্য কাজ করে।

select a.oid as user_role_id
, a.rolname as user_role_name
, b.roleid as other_role_id
, c.rolname as other_role_name
from pg_roles a
inner join pg_auth_members b on a.oid=b.member
inner join pg_roles c on b.roleid=c.oid 
where a.rolname = 'user_1'

1
আপনি যদি পূর্ববর্তী উত্তরগুলি থেকে পৃথক হয়ে ও উন্নত করেন তবে কীভাবে তা ব্যাখ্যা করা যায় এটি অনেক উন্নত হবে। আপনি অতিরিক্ত তথ্য সরাসরি উত্তরে সম্পাদনা করতে পারেন।
মাইকেল গ্রিন

1

আমি বিশ্বাস করি এটি এটি করবে

SELECT 
    oid 
FROM 
    pg_roles 
WHERE 
    oid IN (SELECT 
                roleid 
            FROM 
                pg_auth_members 
            WHERE 
                member=(SELECT oid FROM pg_roles WHERE rolname='maxwell'));

আপনি যদি ভূমিকাটির নাম পেতে পছন্দ করেন তবে প্রথমে এর oidসাথে প্রতিস্থাপন করুন rolname


0

যদি আপনি বর্তমানে সক্রিয় ভূমিকার সমস্ত ভূমিকা জানতে চান:

CREATE OR REPLACE VIEW public.my_roles
AS WITH RECURSIVE cte AS (
         SELECT pg_roles.oid,
            pg_roles.rolname
           FROM pg_roles
          WHERE pg_roles.rolname = CURRENT_USER
        UNION ALL
         SELECT m.roleid,
            pgr.rolname
           FROM cte cte_1
             JOIN pg_auth_members m ON m.member = cte_1.oid
             JOIN pg_roles pgr ON pgr.oid = m.roleid
        )
 SELECT array_agg(cte.rolname) AS my_roles
   FROM cte;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.