Django-guardian: الأذونات العامة مقابل أذونات الكائن

تم إنشاؤها على ٢٢ ديسمبر ٢٠١٥  ·  16تعليقات  ·  مصدر: django-guardian/django-guardian

يبدو أن هناك عددًا من الأخطاء بسبب بعض الإجراءات التي تستخدم أذونات عامة ، والبعض الآخر يستخدم أذونات الكائن فقط. سيتم إغلاق الأخطاء ذات الصلة والرجوع إليها هنا.

API change Enhancement

ال 16 كومينتر

نعم لهذا!

إذن ، إذن _required_or_403 يحتوي على المعلمة Accept_global_perms ، ولكن لا توجد طريقة في العرض لفعل الشيء نفسه مع get_obj_perms

أقترح علامة get_obj_perms_with_global التي تتضمن امتيازات عالمية.

لا أعرف ما إذا كنت قد بدأت بالفعل في هذا الطريق ، لكنني سأبدأ في إعداد تصحيح للقيام بذلك ؛ إذا كنت قد بدأت بالفعل ، فلا تتردد في إيقافي :)

ملاحظة: أعتقد أن هناك حجة يجب إجراؤها مفادها أن السلوك الافتراضي يجب أن يتضمن أذونات عامة ، يبدو لي أنه عندما تسأل "هل يمكن للمستخدم X فعل Y للكائن Z" وهذا يعني التحقق من كل مستخدم / كائن ، مجموعة / كائن أذونات المستخدم / العالمية المجموعة / العالمية. ولكن قد يكون هذا بسبب الطريقة التي أستخدمها بها.

بعد قولي هذا كله ، من السهل جدًا التحقق من الأذونات العامة بشكل منفصل ... Hrmmm.

المدقات: هناك قضايا كافية على الوصي كدليل على مدى إرباك ذلك. نحصل عليه كل ستة أشهر ... إذا كان request.user.has_access ('foo'، obj) يجب أن يكون صحيحًا إذا كان لديهم أذونات عامة ولكن ليس لديهم أذونات على مستوى الكائن. كتابة الشيك مرتين مقزز.

ما الذي يجب أن يحدث لتغيير هذا؟

أعتقد أن شخصًا ما يحتاج إلى كتابة طلب سحب ... من الناحية المثالية بطريقة لا تكسر الكود الحالي (إذا كان هذا منطقيًا وممكنًا أم لا لا أعرف).

مشكلة قديمة ، لكنني لا أرى طلب سحب حتى الآن. أي أخبار عن هذه؟ أنا أواجه نفس السلوك ، والذي أعتقد أنه لا يمكن التنبؤ به. اشكرك كثيرا!

لقد أضفت بعض التعليقات إلى رقم 49 نظرًا لأن ذلك كان لديه المزيد من الأفكار حول مسألة ما إذا كان وكيفية الرجوع إلى الكرة الأرضية عندما يفشل مستوى الكائن. لست متأكدًا مما إذا كانت المشكلات المغلقة تثير الإشعار ، لذلك أقوم بإضافة هذا هنا.

اعتمادًا على قرارات التصميم التي يتم اتخاذها ، أعتزم العمل على بعض هذه المشكلات.

سأكون سعيدا للمساعدة في هذه القضايا.

327 يبدو ثابتًا بالنسبة لي.

""
brandon = Person.objects.get (first_name = 'BRANDON')
brandon.is_superuser
خاطئة

school = School.objects.get (pk = 1)

get_users_with_perms (school، attach_perms = True، with_superusers = False، with_group_users = False)
{}

assign_perm ('add_school'، brandon، school)

get_users_with_perms (school، attach_perms = True، with_superusers = False، with_group_users = False)
{: ['add_school']}

mehmet = Person.objects.get (first_name = 'Mehmet')
mehmet.is_superuser
حقيقي

get_users_with_perms (school، attach_perms = True، with_superusers = True، with_group_users = False)
{: []،: ['add_school'، 'change_school'، 'delete_school']}

assign_perm ('add_school'، mehmet، school)

get_users_with_perms (school، attach_perms = True، with_superusers = True، with_group_users = False)
{: []،: ['add_school'، 'change_school'، 'delete_school']}

get_users_with_perms (school، attach_perms = True، with_superusers = False، with_group_users = False)
{: ['add_school']،: ['add_school']}

في # 155:

مطلوب إضافة السطرين التاليين إلى get_obj_perms_field_choices (self) :

        if self.exclude_default:
            choices = list(set(choices).intersection(self.obj._meta.permissions))

لاستبعاد الأذونات الافتراضية للنموذج. أولاً ، لست واضحًا بشأن كيفية قيام intersection بفعل ذلك. ثانيًا ، لا يبدو أن هذا مرتبط بأذونات الكائن مقابل أذونات النموذج. الرجاء تصحيح لي إذا فقدت أي شيء.

لكن أثناء النظر في ذلك ، لاحظت أنه يجب الفصل بين أذونات الكائن مقابل أذونات النموذج في:

    def save_obj_perms(self):
        """
        Saves selected object permissions by creating new ones and removing
        those which were not selected but already exists.

        Should be called *after* form is validated.
        """
        perms = self.cleaned_data[self.get_obj_perms_field_name()]
        model_perms = [c[0] for c in self.get_obj_perms_field_choices()]

        to_remove = set(model_perms) - set(perms)
        for perm in to_remove:
            remove_perm(perm, self.user, self.obj)

        for perm in perms:
            assign_perm(perm, self.user, self.obj)

يبدو أنه يقوم بحفظ أي إذن مفقود على مستوى الكائن ، بينما في رأيي ، يجب تخطي أي إذن متاح على مستوى النموذج ، أو توفير خيار لهذا الغرض.

أعتقد أن إعدادًا عامًا مثل GUARDIAN_FALLBACK_TO_MODEL=False ووسيطة للطرق القابلة للتطبيق مثل fallback_to_model=False مطلوبان لتحديد أذونات الكائن وأذونات النموذج بشكل صحيح. تضمن القيمة الافتراضية البالغة False التوافق مع الإصدارات السابقة. إذا كان أي من الإعداد العام أو الوسيطة صحيحًا ، فيجب أن يحدث الرجوع.

+1 لـ GUARDIAN_FALLBACK_TO_MODEL.

حسب المناقشة في # 49 ، أعتقد أن الإعداد قد يعمل بشكل جيد أيضًا للتحكم في ما إذا كان ObjectPermissionBackend صريحًا أم لا.

لقد قمت بإنشاء طلب سحب (# 546). يسمح لوظائف المدقق في خيار core.py بالرجوع إلى (أو تضمين) أذونات مستوى النموذج. الوحدات الأخرى تحتاج أيضًا إلى المراجعة. أخطط لمراجعتها أثناء استخدامها. إذا كان أي شخص يرغب في القفز ، فمرحبا بكم.

يبدو أن # 327 لم يعد موجودًا. تم إصلاح # 332 من خلال طلب السحب أعلاه إذا تم قبوله. هناك مشكلة جانبية واحدة فقط تتعلق بالرقم 155 (المذكور أعلاه) على اليسار. إذا تم الاهتمام بذلك أيضًا (أو تم نقله إلى مشكلة منفصلة) ، فقد يتم إغلاق هذه المشكلة ، على ما أعتقد.

لا تزال الأذونات العامة غير محترمة للحصول على إذن مستوى الكائن إذا تم تعيينها ، فهل أنا مخطئ هنا؟

u = User.objects.get(id=1)
c = Client.objects.get(id=1)
assign_perm('core.change_client', u)
u = User.objects.get(id=1)  # reloading user for perm refresh
u.has_perm('core.change_client')  # True
u.has_perm('core.change_client', c)  # False
u.has_perm('change_client', c)  # False
get_perms(u, c)  # []

وماذا يفعل تعيين GUARDIAN_GLOBAL_PERMISSIONS_CARRY_OVER أو FALLBACK_TO_MODEL ؟ لا يبدو أنه موثق.

ألا يكفي إضافة هذا إلى core.py ؟

get_user_perms:126 والذي يبدو أنه مركز جميع عمليات التحقق من أذونات المستخدم ؛ بدلا من ذلك يمكن تشغيله باستخدام علم منطقي

def get_user_perms(self, obj):
    # ....
    user_global_perms = Permission.objects.filter(content_type=ctype)\
                                        .filter(user=self.user)\
                                        .values_list('codename', flat=True)
    user_object_perms = user_perms_qs.values_list("codename", flat=True)
    user_perms = list(chain(user_global_perms, user_object_perms))
    return user_perms
هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات

القضايا ذات الصلة

Allan-Nava picture Allan-Nava  ·  35تعليقات

David-OConnor picture David-OConnor  ·  6تعليقات

g-as picture g-as  ·  10تعليقات

xuhcc picture xuhcc  ·  10تعليقات

BenDevelopment picture BenDevelopment  ·  5تعليقات