تخصيص الوصول إلى CakePHP بناءً على الوصول إلى البيانات المحددة بناءً على الدور

StackOverflow https://stackoverflow.com/questions/6370384

  •  28-10-2019
  •  | 
  •  

سؤال

متطلبات مشروعي هي شيء من هذا القبيل:

في الأعلى، سيكون هناك مسؤول، سيكون لديه حق الوصول إلى المستوى الأول

تحت المسؤول، سيكون هناك رؤساء الأقسام، الذين سيكون لديهم حق الوصول الكامل، باستثناء إنشاء رؤساء الأقسام

تحت رئيس القسم، سيكون هناك أعضاء آخرون، الذين سيديرون بيانات القسم المخصصة لهم.

الآن، سيكون لدى جميع رؤساء الأقسام المختلفين معلوماتهم الخاصة وأعضائهم، وسيتمكن جميع رؤساء الأقسام/الأعضاء من الوصول إلى سجلاتهم المحددة، والتي يقومون بإدخالها/إدارتها.

الآن، باستخدام مكون ACL الخاص بـ CakePHP، يمكنني تقسيم الأدوار ومستوى الوصول الخاص بهم، ولكن يمكن لجميع رؤساء الأقسام رؤية معلومات رئيس القسم الآخر، حيث سيكون لديهم نفس مستوى الوصول، ويمكن لجميع الأعضاء الآخرين رؤية معلومات الأعضاء الآخرين على اختلافهم. الإدارات، حيث سيكون لديهم نفس مستوى الوصول.

يكمن تعقيد مشروعي في أنه - يجب أن يكونوا مرئيين فقط للمعلومات / البيانات المخصصة لهم أو التي تم إنشاؤها، على الرغم من أن لديهم نفس المستوى / تعيينات الأدوار مثل الآخرين.

هل يمكن لأي شخص أن يقترح علي أفضل خيار مناسب لإدارة كل هذه الأشياء باستخدام المكونات الإضافية المتوفرة بالفعل مع CakePHP.

يمكنني العمل من خلال تخصيص مكون قائمة التحكم بالوصول (ACL) الافتراضي، لكن ذلك سيستغرق وقتًا أطول مما هو متوقع.

سيكون موضع تقدير أي أفكار / اقتراحات أفضل!

هل كانت مفيدة؟

المحلول

من وجهة نظري، الرباط الصليبي الأمامي ليس سحريًا.على سبيل المثال:يمكن لقائمة التحكم بالوصول (ACL) إدارة الأذونات لمعرفة من لديه حق الوصول لإضافة/تحرير/إزالة منتج.ولكن لن يتمكن من تغيير استعلام لتصفية المنتجات وفقًا للأذونات المحددة (مثل "يمكن للمستخدمين من القسم أ رؤية المنتجات من القسم أ فقط")..حسنًا، هذه كذبة في الواقع، يمكن لـ ACL إدارة ذلك ولكنه قد لا يكون عمليًا، لأنه في كل مرة تضيف فيها منتجًا، سيتعين عليك إنشاء ACO، وتعيين الإذن في جدول AROS_ACOS وبما أن AROS عبارة عن بنية شجرية، لذلك يمكن أن يصبح الأمر بمثابة كابوس بسهولة، إذا كنت تخطط للاستعلام عن بياناتك

سأستخدم أ ACL للمجموعة فقط للتحكم في الوصول إلى صفحات/إجراءات معينة ووضع قواعد مثل:

  • "يمكن لـ Department Head الوصول إلى صفحة" قائمة المنتجات "وإضافة/حذف/تعديل المنتجات"
  • "يمكن للمسؤولين الوصول إلى جميع الصفحات"
  • "يمكن للمستخدمين الآخرين الوصول إلى" قائمة المنتجات "ويمكنهم إضافة منتجات ولكن لا يحذفها"

وسأقوم بتعديل استعلاماتي وفقًا للمستخدم المتصل، لذا في وحدة التحكم في صفحة "قائمة المنتجات"، سأفعل شيئًا مثل:

  • إذا كان المستخدم المتصل يشتاق إلى رئيس القسم، فحدد جميع المنتجات التي يوجد بها product.department_id=connected_user.department_id
  • إذا كان المستخدم المتصل هو المسؤول، فحدد جميع المنتجات

إذا كان لديك الكثير من الاستعلامات ولا تريد تنفيذ آلاف من جمل if، فيمكنك إنشاء مكون أو سلوك أو ربما تمديد find() الطريقة في app_model.تتمثل الفكرة في التقاط جميع الاستعلامات والتحقق مما إذا كان أحد النماذج المستخدمة في الاستعلام يحتوي على حقل يسمى "department_id"، إذا كان يحتوي على ذلك، فقم بإضافة الحقل model.department_id=connected_user.department_id شرط للاستعلام.

لقد فعلت ذلك لموقع ويب واحد يمكن رؤيته بلغات متعددة ولكل لغة مستخدمين وبيانات وسجلات وما إلى ذلك، ويوجد مسؤول واحد يمكنه رؤية جميع المعلومات.وهو يعمل بشكل رائع بالنسبة لي =)

حظ سعيد!

تم التعديل:السلوك الذي أستخدمه هو:

<?php 
class LocalizableBehavior extends ModelBehavior { 

    /** 
     * Filter query conditions with the correct `type' field condition. 
     */ 
    function beforeFind(&$model, $query) 
    {
        /**
         * Condition for the paginators that uses joins
        */
        if(isset($query['joins']) && !empty($query['joins'])){
            foreach($query['joins'] as $key => $joinTable){
                if(ClassRegistry::init($joinTable['alias'])->hasField('lang')){
                    $query['joins'][$key]['conditions'][] = $joinTable['alias'].".lang = '".$_SESSION['lang']."'";
                }
            }
        }

        /**
         * condition for the normal find queries
        */
        if($model->hasField('lang') && $model->name != "User"){
                $query['conditions'][$model->name.'.lang'] = $_SESSION['lang'];
        }
        return $query;
    }

} 
?>

الأمر بسيط جدًا حقًا، أقوم بتغيير الاستعلام لإضافة شرط يتطابق مع اللغة الحالية ($_SESSION['lang']).كل ما أحتاج إلى فعله في وحدة التحكم هو إرفاق LocalizableBehavior واستخدام طريقة البحث كالمعتاد:

$this->Products->find('all');
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top