برنامه نویسی

مدل سازی مدیریت دسترسی گروه های فیس بوک

معرفی

ما اغلب در مورد نحوه مدل‌سازی انواع مختلف مجوزها یا خط‌مشی‌ها با استفاده از Permify Schema Language سؤالاتی دریافت می‌کنیم.

برای کسانی که ممکن است آشنا نباشند، زبان طرحواره یک زبان مجوز است که به شما امکان می دهد روابط دلخواه بین کاربران و اشیاء را برای مدل کردن منطق مجوز خود تعریف کنید. و توسط Permify، یک سرویس مجوز مبتنی بر رابطه منبع باز ارائه شده است. فقط برای اطلاع شما، من یکی از نگهبانان و یکی از بنیانگذاران Permify هستم 🙂

ما قبلاً اسناد، مثال‌ها، تشابه‌ها و منابع دیگری داریم که نحوه عملکرد زبان طرحواره و جنبه‌های مختلف آن را نشان می‌دهند. با این حال، وقتی صحبت از موارد پیچیده می شود، ممکن است چندین رویکرد وجود داشته باشد که بتواند به نتایج یکسانی دست یابد. بنابراین کاملاً طبیعی است که کاربران به دنبال برداشت و بهترین شیوه های ما برای چنین سناریوهایی باشند.

بنابراین ما شروع به جستجو و پیاده‌سازی نمونه‌های «زندگی واقعی» کرده‌ایم که با Permify در منابع ما نگهداری می‌شوند، معتقدیم این رویکرد می‌تواند موتوری برای پذیرش بیشتر زبان طرحواره ما باشد.

بنابراین در این مقاله آموزشی، مدل مجوز گروه های فیس بوک را بررسی کرده و با استفاده از Permify آن را پیاده سازی می کنیم.

گروه های فیس بوک و کنترل دسترسی آن

گروه‌های فیس‌بوک قابلیتی است که به کاربران فیس‌بوک اجازه می‌دهد تا جوامعی را ایجاد کنند که حول علایق، موضوعات یا سازمان‌های مختلف متمرکز شده‌اند.

کاربران می توانند گروه های خود را ایجاد کنند یا گروه های موجود را برای پیوستن جستجو کنند. هنگام ایجاد یک گروه، کاربران هدف، تنظیمات حریم خصوصی و سایر جزئیات را تعریف می کنند. چند نوع کاربر مختلف از گروه مانند عضو، مدیر و ناظر با مجوزها و توانایی های مختلف وجود دارد.

هر گروه فید خود را دارد که در آن اعضا می‌توانند به‌روزرسانی‌های متنی، عکس‌ها، ویدیوها و سایر محتوای مرتبط با موضوع گروه را پست کنند. اعضا می‌توانند با لایک کردن، نظر دادن و اشتراک‌گذاری پست‌ها با آن‌ها ارتباط برقرار کنند. گروه‌ها ویژگی‌های اضافی مانند رویدادها، نظرسنجی‌ها، اشتراک‌گذاری فایل، چت گروهی و اسناد مشارکتی را ارائه می‌کنند که به اعضا امکان می‌دهد رویدادها را سازماندهی کنند، نظرات را جمع‌آوری کنند، فایل‌ها را به اشتراک بگذارند، و در درون گروه ارتباط برقرار کنند.

در برخی موارد، همه گروه‌ها، پست‌ها، نظرات، لایک‌ها، رویدادهای این موجودیت یک پیوند طبیعی بین آنها برقرار می‌کنند. به عنوان نمونه نظرات، لایک ها متعلق به یک پست والدین است که به یک گروه خاص تعلق دارد. این ساختار داده مبتنی بر رابطه فرصت ایجاد یک ساختار کنترل دسترسی قوی با استفاده از ReBAC (کنترل دسترسی مبتنی بر رابطه) را می دهد.

پیاده سازی با Permify

تعریف موجودیت ها و روابط بین منابع

اولین قدم برای ساختن یک مدل مجوز با زبان طرحواره Permify، ایجاد موجودیت های شماست.

بنابراین با توجه به مثال گروه های فیس بوک ما، چندین نهاد داریم:

کاربر نهاد نماینده یک کاربر در فیس بوک است.

گروه نهاد نماینده گروه فیس بوک است و روابط متعددی از جمله عضو، مدیر و ناظر برای نمایندگی اعضا، ادمین ها و مدیران گروه دارد. علاوه بر این، روابطی برای نمایش پست ها و نظرات در گروه وجود دارد.

پست نهاد نشان دهنده یک پست در گروه فیس بوک است و روابطی برای نشان دادن صاحب پست و گروهی که پست به آن تعلق دارد دارد.

اظهار نظر entity یک نظر روی یک پست در گروه فیس بوک را نشان می دهد و روابطی برای نشان دادن صاحب نظر، پستی که نظر به آن تعلق دارد و خود نظر دارد.

پسندیدن موجودیت نشان دهنده یک لایک در یک پست در گروه فیس بوک است و روابطی برای نشان دادن صاحب لایک و پستی دارد که لایک به آن تعلق دارد.

نظرسنجی نهاد یک نظرسنجی را در گروه فیس بوک نشان می دهد و روابطی برای نمایندگی صاحب نظرسنجی و گروهی که نظرسنجی به آن تعلق دارد دارد.

فایل entity یک فایل را در گروه فیس بوک نشان می دهد و روابطی برای نشان دادن مالک فایل و گروهی که فایل به آن تعلق دارد دارد.

رویداد entity یک رویداد را در گروه فیس بوک نشان می دهد و روابطی برای نشان دادن مالک رویداد و گروهی که رویداد به آن تعلق دارد دارد.

بیایید آن موجودیت ها و روابط آنها را به زبان طرحواره خود قرار دهیم،

// Represents a user
entity user {}

// Represents a Facebook group
entity group {

    // Relation to represent the members of the group
    relation member @user
    // Relation to represent the admins of the group
    relation admin @user
    // Relation to represent the moderators of the group
    relation moderator @user

}

// Represents a post in a Facebook group
entity post {

    // Relation to represent the owner of the post
    relation owner @user
    // Relation to represent the group that the post belongs to
    relation group @group

}

// Represents a comment on a post in a Facebook group
entity comment {

    // Relation to represent the owner of the comment
    relation owner @user

    // Relation to represent the post that the comment belongs to
    relation post @post
}

// Represents a comment like on a post in a Facebook group
entity like {

    // Relation to represent the owner of the like
    relation owner @user

    // Relation to represent the post that the like belongs to
    relation post @post

}

// Definition of poll entity
entity poll {

     // Relation to represent the owner of the poll
    relation owner @user

    // Relation to represent the group that the poll belongs to
    relation group @group

}

// Definition of file entity
entity file {

    // Relation to represent the owner of the file
    relation owner @user

    // Relation to represent the group that the file belongs to
    relation group @group

}

// Definition of event entity
entity event {

    // Relation to represent the owner of the event
    relation owner @user
    // Relation to represent the group that the event belongs to
    relation group @group

}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تعریف مجوزها

ما اقدامات متعددی را به نهادها متصل کرده‌ایم که با مجوزهای خاصی محدود شده‌اند. اجازه دهید برای ویرایش پست مجوز ایجاد کنیم.

برای ویرایش پست X در گروه‌های فیس‌بوک، کاربران یا مالک/خالق آن پست هستند یا کاربر باید در گروهی که پست X به آن تعلق دارد، نقش مدیریت داشته باشد.

زبان Permify Schema از عملگرها و یا نه برای دستیابی به تقاطع مجوز و حذف پشتیبانی می کند. کلمات کلیدی اقدام یا مجوز را می توان با آن عملگرها برای ایجاد قوانینی برای منطق مجوز شما استفاده کرد.

بنابراین اگر عمل edit post را به عنوان مشخص کنیم edit_post، سپس موجودیت پست باید به صورت زیر بازسازی شود:

// Represents a post in a Facebook group
entity post {

    // Relation to represent the owner of the post
    relation owner @user

    // Relation to represent the group that the post belongs to
    relation group @group

    action edit_post = owner or group.admin

}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

همانطور که از نحو group.admin می بینید، می توانید به روابط موجودیت ها با علامت نقطه کلاسیک دسترسی داشته باشید.

اجازه دهید مجوزهای پیشرفته تری را تعریف کنیم. به عنوان مثال، ما می توانیم یک مجوز تعریف کنیم.view_comment” در نهاد نظر برای کنترل دسترسی برای انجام مشاهده عمل نظر.

در گروه‌های فیس‌بوک، به کاربران اجازه داده می‌شود که یک نظر را مشاهده کنند اگر:

کاربر عضو گروهی است که پست نظر به آن تعلق دارد.

کاربر مالک/خالق نظر است.

مالکیت یک مدل پایه ReBAC است، بخش دشوار این مجوز ساختار سلسله مراتبی تودرتو شرط اول است: کاربر عضوی از گروهی است که پست نظر به آن تعلق دارد.

برای افزودن این مجوز به طرح خود، باید هم پست و هم نهاد نظر را به صورت زیر به روز کنیم:

// Represents a post in a Facebook group
entity post {

    ..
    ..

    // Relation to represent the group that the post belongs to
    relation group @group

    // Permissions for the post entity

    ..
    ..
    permission group_member = group.member
}

// Represents a comment on a post in a Facebook group
entity comment {

    // Relation to represent the owner of the comment
    relation owner @user

    // Relation to represent the post that the comment belongs to
    relation post @post
    relation comment @comment

    ..
    ..

    // Permissions 
    action view_comment = owner or post.group_member

    ..
    ..
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

را post.group_member به اعضای گروهی که پست به آن تعلق دارد اشاره دارد. ما آن را به عنوان عمل در موجودیت پست تعریف کردیم،

// Represents a post in a Facebook group
entity post {

    ..
    ..

    // Relation to represent the group that the post belongs to
    relation group @group

    // Permissions for the post entity

    ..
    ..
    permission group_member = group.member
}

// Represents a comment on a post in a Facebook group
entity comment {

    // Relation to represent the owner of the comment
    relation owner @user

    // Relation to represent the post that the comment belongs to
    relation post @post
    relation comment @comment

    ..
    ..

    // Permissions 
    action view_comment = owner or post.group_member

    ..
    ..
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

مجوزها را می توان به عنوان روابط در سایر نهادها به ارث برد.

این اجازه می دهد تا روابط سلسله مراتبی تودرتو بین موجودیت ها شکل گیرد.

با توجه به مثال ما، یک نظر متعلق به پستی است که بخشی از یک گروه است. از آنجایی که یک ‘ وجود داردعضو“رابطه تعریف شده برای موجودیت گروه، می توانیم از ” استفاده کنیمعضوگروهاجازه به ارث بردن رابطه عضو از گروه در پست و سپس استفاده از آن در نظر به صورت زیر:

action view_comment = owner or post.group_member
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

طرحواره کامل

به خاطر سادگی این پست، من برای هر مجوز تجزیه و تحلیل نمی کنم و به عمق نمی پردازم.

بنابراین اجازه دهید مجوزهای باقیمانده را اضافه کرده و طرح خود را تکمیل کنیم.

// Represents a user
entity user {}

// Represents a Facebook group
entity group {

    // Relation to represent the members of the group
    relation member @user
    // Relation to represent the admins of the group
    relation admin @user
    // Relation to represent the moderators of the group
    relation moderator @user

    // Permissions for the group entity
    action create = member
    action join = member
    action leave = member
    action invite_to_group = admin
    action remove_from_group = admin or moderator
    action edit_settings = admin or moderator
    action post_to_group = member
    action comment_on_post = member
    action view_group_insights = admin or moderator
}

// Represents a post in a Facebook group
entity post {

    // Relation to represent the owner of the post
    relation owner @user
    // Relation to represent the group that the post belongs to
    relation group @group

    // Permissions for the post entity
    action view_post = owner or group.member
    action edit_post = owner or group.admin
    action delete_post = owner or group.admin

    permission group_member = group.member
}

// Represents a comment on a post in a Facebook group
entity comment {

    // Relation to represent the owner of the comment
    relation owner @user

    // Relation to represent the post that the comment belongs to
    relation post @post

    // Permissions for the comment entity
    action view_comment = owner or post.group_member
    action edit_comment = owner
    action delete_comment = owner
}

// Represents a comment like on a post in a Facebook group
entity like {

    // Relation to represent the owner of the like
    relation owner @user

    // Relation to represent the post that the like belongs to
    relation post @post

    // Permissions for the like entity
    action like_post = owner or post.group_member
    action unlike_post = owner or post.group_member
}

// Definition of poll entity
entity poll {

     // Relation to represent the owner of the poll
    relation owner @user

    // Relation to represent the group that the poll belongs to
    relation group @group

    // Permissions for the poll entity
    action create_poll = owner or group.admin
    action view_poll = owner or group.member
    action edit_poll = owner or group.admin
    action delete_poll = owner or group.admin
}

// Definition of file entity
entity file {

    // Relation to represent the owner of the file
    relation owner @user

    // Relation to represent the group that the file belongs to
    relation group @group

    // Permissions for the file entity
    action upload_file = owner or group.member
    action view_file = owner or group.member
    action delete_file = owner or group.admin
}

// Definition of event entity
entity event {

    // Relation to represent the owner of the event
    relation owner @user
    // Relation to represent the group that the event belongs to
    relation group @group

    // Permissions for the event entity
    action create_event = owner or group.admin
    action view_event = owner or group.member
    action edit_event = owner or group.admin
    action delete_event = owner or group.admin
    action RSVP_to_event = owner or group.member

}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

ایجاد نمونه داده های مجوز

برای آزمایش مدل مجوزی که در بالا ایجاد شد، باید داده‌های مرتبط داشته باشیم. هر داده باید نشان دهنده روابط بین موجودیت ها، اشیاء و کاربران باشد و مجموعه ای از لیست های کنترل دسترسی (ACL) ایجاد کند.

در Permify از یک فرم خاص برای نمایش روابط شی به شی و شی به موضوع استفاده می کنیم. به آن تاپل های رابطه ای می گویند.

ساده‌ترین شکل تاپل رابطه‌ای که به‌عنوان نهاد # رابطه @ کاربر ساختار یافته است. هر تاپل رابطه‌ای نشان‌دهنده عملی است که یک کاربر یا مجموعه کاربری خاص می‌تواند روی یک منبع انجام دهد و به شکل کاربر U دارای رابطه R با شی O است، جایی که کاربر U می‌تواند یک کاربر ساده یا یک مجموعه کاربری مانند اعضای گروه X باشد.

در اینجا چند تاپل رابطه ای مطابق با مثال گروه های فیس بوک ما آورده شده است.

//group relationships
group:1#member@user:1
group:1#admin@user:2
group:2#moderator@user:3
group:2#member@user:4
group:1#member@user:5

//post relationships
post:1#owner@user:1
post:1#group@group:1
post:2#owner@user:4
post:2#group@group:1

//comment relationships
comment:1#owner@user:2
comment:1#post@post:1
comment:2#owner@user:5
comment:2#post@post:2

//like relationships
like:1#owner@user:3
like:1#post@post:1
like:2#owner@user:4
like:2#post@post:2

//poll relationships
poll:1#owner@user:2
poll:1#group@group:1
poll:2#owner@user:5
poll:2#group@group:1

//like relationships
file:1#owner@user:1
file:1#group@group:1

//event relationships
event:1#owner@user:3
event:1#group@group:1
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

تست و اعتبارسنجی

در نهایت، ما می توانیم برخی از مجوزها را بررسی کرده و منطق مجوز خود را آزمایش کنیم.

بیایید با عمل view در موجودیت رویداد شروع کنیم،

آیا کاربر 4 می تواند رویداد:1 را مشاهده کند؟

entity event {

   // Relation to represent the owner of the event
   relation owner @user
   // Relation to represent the group that the event belongs to

   relation group @group

   // Permissions for the event entity

   ..
   ..

   action view = owner or group.member
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با توجه به آنچه که برای “چشم انداز‘ اقدام، کاربرانی که یا مالک رویداد:1 یا عضوی از گروهی هستند که به آن تعلق دارند رویداد: 1 می تواند رویداد را مشاهده کند.

با توجه به تاپل های رابطه ای که ایجاد کردیم، user:4 مالک رویداد نیست.

علاوه بر این، وقتی بررسی می کنیم که آیا کاربر:4 عضو تنها گروه (گروه: 1) آن رویداد: 1 بخشی از (رویداد:1#group@group:1، می بینیم که هیچ رابطه عضوی برای وجود ندارد کاربر:4 در آن گروه

بنابراین، کاربر:4 چشم انداز رویداد: 1 درخواست چک باید پاسخ “نادرست” بدهد.

آیا کاربر:5 می تواند نظر: 1 را مشاهده کند؟

// Represents a post in a Facebook group
entity post {

    ..
    ..

    // Relation to represent the group that the post belongs to
    relation group @group

    // Permissions for the post entity

    ..
    ..
    permission group_member = group.member
}

// Represents a comment on a post in a Facebook group
entity comment {

    // Relation to represent the owner of the comment
    relation owner @user

    // Relation to represent the post that the comment belongs to
    relation post @post
    relation comment @comment

    ..
    ..

    // Permissions 
    action view_comment = owner or post.group_member

    ..
    ..
}
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

با توجه به تاپل های رابطه ای که ایجاد کردیم، user:5 صاحب نظر نیست.

اما عضو گروه: 1 و آن کمک هزینه کاربر: 5 (group:1#member@user:5) دسترسی به انجام مشاهده نظر:1.

به خصوص، نظر: 1 بخشی از است پست: 1 (نظر:1#post@post:1) و پست: 1 بخشی از است گروه: 1 (post:1#group@group:1). و از تعریف عمل در مدل بالا گروه: 1 اعضا می توانند مشاهده کنند نظر: 1.

بنابراین، کاربر: 5 view_comment نظر: 1 درخواست چک باید یک پاسخ “درست” بدهد.

بیایید این دو بررسی دسترسی را در محلی خود با استفاده از اعتبارسنجی permify آزمایش کنیم. ما از طرح زیر برای اعتبار سنجی فایل yaml استفاده خواهیم کرد.

schema: >-
    entity user {}

    entity group {

        // Relation to represent the members of the group
        relation member @user
        // Relation to represent the admins of the group
        relation admin @user
        // Relation to represent the moderators of the group
        relation moderator @user

        // Permissions for the group entity
        action create = member
        action join = member
        action leave = member
        action invite_to_group = admin
        action remove_from_group = admin or moderator
        action edit_settings = admin or moderator
        action post_to_group = member
        action comment_on_post = member
        action view_group_insights = admin or moderator
    }

    entity post {

        // Relation to represent the owner of the post
        relation owner @user
        // Relation to represent the group that the post belongs to
        relation group @group

        // Permissions for the post entity
        action view_post = owner or group.member
        action edit_post = owner or group.admin
        action delete_post = owner or group.admin

        permission group_member = group.member
    }

    entity comment {

        // Relation to represent the owner of the comment
        relation owner @user

        // Relation to represent the post that the comment belongs to
        relation post @post

        // Permissions for the comment entity
        action view_comment = owner or post.group_member
        action edit_comment = owner
        action delete_comment = owner
    }

    entity like {

        // Relation to represent the owner of the like
        relation owner @user

        // Relation to represent the post that the like belongs to
        relation post @post

        // Permissions for the like entity
        action like_post = owner or post.group_member
        action unlike_post = owner or post.group_member
    }

    entity poll {

        // Relation to represent the owner of the poll
        relation owner @user

        // Relation to represent the group that the poll belongs to
        relation group @group

        // Permissions for the poll entity
        action create_poll = owner or group.admin
        action view_poll = owner or group.member
        action edit_poll = owner or group.admin
        action delete_poll = owner or group.admin
    }

    entity file {

        // Relation to represent the owner of the file
        relation owner @user

        // Relation to represent the group that the file belongs to
        relation group @group

        // Permissions for the file entity
        action upload_file = owner or group.member
        action view_file = owner or group.member
        action delete_file = owner or group.admin
    }

    entity event {

        // Relation to represent the owner of the event
        relation owner @user
        // Relation to represent the group that the event belongs to
        relation group @group

        // Permissions for the event entity
        action create_event = owner or group.admin
        action view_event = owner or group.member
        action edit_event = owner or group.admin
        action delete_event = owner or group.admin
        action RSVP_to_event = owner or group.member
    }

relationships:
    - group:1#member@user:1
    - group:1#admin@user:2
    - group:2#moderator@user:3
    - group:2#member@user:4
    - group:1#member@user:5
    - post:1#owner@user:1
    - post:1#group@group:1
    - post:2#owner@user:4
    - post:2#group@group:1
    - comment:1#owner@user:2
    - comment:1#post@post:1
    - comment:2#owner@user:5
    - comment:2#post@post:2
    - like:1#owner@user:3
    - like:1#post@post:1
    - like:2#owner@user:4
    - like:2#post@post:2
    - poll:1#owner@user:2
    - poll:1#group@group:1
    - poll:2#owner@user:5
    - poll:2#group@group:1
    - file:1#owner@user:1
    - file:1#group@group:1
    - event:1#owner@user:3
    - event:1#group@group:1

scenarios:
  - name: "scenario 1"
    description: "test description"
    checks:
      - entity: "event:1"
        subject: "user:4"
        assertions:
          RSVP_to_event : false
      - entity: "comment:1"
        subject: "user:5"
        assertions:
          view_comment : true
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

برای استفاده از تابع permify validate، Permify را از GitHub کلون کنید و یک فایل جدید باز کنید و محتوای فایل yaml طرحواره را در داخل آن کپی کنید. سپس با استفاده از دستور make run نمونه Permify را بسازید و اجرا کنید.

توضیحات تصویر

سپس permify validate {path of your schema validation file} را اجرا کنید تا فرآیند تست شروع شود. نتیجه اعتبار سنجی مطابق فایل تأیید طرح نمونه ما:

توضیحات تصویر

نتیجه

این پایان نمایش و اجرای ساختار مجوز برای گروه های فیس بوک با استفاده از Permify است. می توانید این نمونه را در زمین بازی ما پیدا کنید تا آن را در مرورگر خود بررسی کنید.

اگر علاقه مند به کسب اطلاعات بیشتر در مورد راه حل ما هستید یا معتقدید که ممکن است برای سازمان شما مفید باشد، لطفاً در پیوستن به انجمن ما در Discord تردید نکنید. از فرصت گپ زدن و به اشتراک گذاشتن دیدگاه های خود استقبال می کنیم.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا