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

معرفی
ما اغلب در مورد نحوه مدلسازی انواع مختلف مجوزها یا خطمشیها با استفاده از 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 تردید نکنید. از فرصت گپ زدن و به اشتراک گذاشتن دیدگاه های خود استقبال می کنیم.