الصلاحيات بطريقة بسيطة وفعّالة في أنظمة الصلاحيات المُعقدة

السلام عليكم ورحمة الله وبركاته

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

  • فلنفرض أن لدينا 30 صلاحية سيتم تمثيل تلك الصلاحيات كسلسة نصية مكونة من الصفر والواحد كالتالي:

    001100000011101010010100110000

الصفر يرمز لعدم تمكين الصلاحية والواحد يرمز لتمكين الصلاحية

  • ستكون لدينا مصفوفة باسماء الصلاحيات المطلوبة -ويمكنك زيادتها او انقاصها دون تاثير على سير العملية- مفتاح كل قيمة في المصفوفة للصلاحية يناظرة مفتاح لقيمة الصلاحية في السلسة النصية، وعلى هذا يُمكننا بسهولة إعطاء ونزع الصلاحيات للمُستخدمين بسلاسة ولأي عدد من الصلاحيات بتغيير قيمة السلسة النصية على حسب الصلاحيات بما يُناظر كل صلاحية في المصفوفة.

التالي فئة بلغة php لتنفيذ هذه الطريقة -يمكنك تنفيذ الطريقة باللغة التي تُفضلها-:

<?php
class permissions
{
    // مصفوفة لتخزين اسماء الصلاحيات التي ستُستخدم
    private $permissions = [];

    // باني الفئة
    public function __construct()
    {
        // مصفوفة بجميع الصلاحيات المُتاحة
        // عينة من بعض الصلاحيات لنظام ما
        $this->permissions = [  'carAdd','carEdit','carDelete','carEditName','carEditModel','carEditPower',
                                'carEditPrice','carEditColor','carEditCompany','carEditCurancy','carEditMotor',
                                'motoAdd','motoEdit','motoDelete','motoEditName','motoEditModel','motoEditPower',
                                'motoEditPrice','motoEditColor','motoEditCompany','motoEditCurancy','motoEditMotor',
                                ];
    }
    // دالة اختبار الصلاحية
    // تقوم الدالة بإختبار الصلاحية المُممرة للدالة على المُستخدم النشط
    // تعيد الدالة القيمة الصحيحة في حال كان المُستخدم يمتلك تلك الصلاحية
    // تعيد الدالة القيمة الخاطئة في حال كان المُستخدم النشط لا يملك تلك الصلاحية
    public function permission($permissionName)
    {
        if(!in_array($permissionName, $this->permissions))
            return false;

        $userPermissions = $this->getUserPermissons();
        $key = $this->key($permissionName);
        if(!isset($userPermissions[$key]) || $userPermissions[$key] != 1)
            return false;
        else
            return true;
    }

    // دالة إضافة صلاحيات مُستخدم جديد
    // تكون الصلاحيات عبارة عن صناديق اختيار بنفس اسماء الصلاحيات للتحقق منها
    // تقوم الدالة بإعادة سلسة نصية مكونة من الصفر والواحد عبارة عن صلاحيات المُستخدم الجديد
    private function addPermissions()
    {
        $userPermissions = str_pad('', count($this->permissions), '0');

        foreach($this->permissions as $value){
            if(isset($_POST[$value])){
                $userPermissions[$this->key($value)] = 1;
            }
        }
        return $userPermissions;
    }

    // دالة تعديل صلاحيات مُستخدم موجود
    // تكون الصلاحيات عبارة عن صناديق اختيار بنفس اسماء الصلاحيات للتحقق منها
    // تقوم الدالة بإعادة سلسة نصية مكونة من الصفر والواحد بعد تعديل صلاحيات المُستخدم
    // يتم تخزين سلسة الصلاحيات الجديدة للمُستخدم في قاعدة البيانات أو أي وحدة تخزين أُخرى
    private function editPermissions($userPermissions)
    {
        $userPermissions = str_pad($userPermissions, count($this->permissions), '0');

        foreach($this->permissions as $value){
            if(isset($_POST[$value]))
                $userPermissions[$this->key($value)] = 1;
            else
                $userPermissions[$this->key($value)] = 0;
        }
        return $userPermissions;
    }


    // تقوم هذه الدالة بإعادة صلاحيات المُستخدم النشط كسلسة نصية
    // تكون هذه السلسة مُخزنة كقيمة في جدول المُستخدمين ولكل مُستخدم سلسة نصية شبية بالتالية
    public function getUserPermissons()
    {
        return '0001101011110001000111';
    }

    // دالة لإعادة مفتاح القيمة في المصفوفة
    private function key($value)
    {
        return array_search($value, $this->permissions);
    }
}


$perm = new permissions();

// للتحقق من الصلاحية
if($perm->permission('carAdd'))
    echo "can add car";
else
    echo "can't add car";

التعليق السابق

كما توقعت صلاحيات على مستوى الحقول .. رائع جدا انك وصلت الى هذا المستوى في تطبيق فعلي "رائع بكل معنى الكلمة"

الان عليك ان تعمل بجهد كبير لبناء بنيتك بشكل اكاديمي .. طريقتك ليست عملية لانه سوف تحتاج مترجم وسيطلتحويل الصلاحيات الى سلسلة نصية والعكس بين برنامجك واي برنامج اخر سوف تضيفه مستقبلا .. والمشكلة الاكبر لو هناك من سيكمل على برنامجك ! ..

احاول تخيل processعند تعديل الصلاحيات !!!!! او خطأ في الصلاحيات كيف سيكون التتبع والمعالجة !!!!! يارب سترك :)

اضافة الى انك تعتمد 0 - 1 لكل حقل .. وتسنده ايضا لمثلها ان كان اب او ابن .. وتسندها الى ما هو اعلى Modul .. ثم الى ما هو اعلى وهكذا !!؟؟

يعني حتشتغل بلوكات ثابتة .. الى بلوكات ثابته اخرى اعلى .. الى بلوكات ثابته اخرى !!!

الموضوع هنا انك تشتت نفسك اكثر من اللازم .. هذا رائيي

لماذا تضيف جهد وسيط بينما يمكنك الاستعانة بعمل procedure mysql او view .. بحيث يكون الطلب دائما من جدول واحد فقط !!

طبعا الموضوع جميل ولكن مرهق في التأسيس .. انصحك ببنائه على المدى البعيد لجميع برامجك

نحن عملنا على هذا النوع من الصلاحيات ولكن بشكل اكبر بكثير (( تخيل هذا الموضوع الذي امامك الان ))

http://blog.orbitone.com/po...

يمكننا التواصل على سكايب اذا احببت اخي الكريم fsaedy

الان عليك ان تعمل بجهد كبير لبناء بنيتك بشكل اكاديمي .. طريقتك ليست عملية لانه سوف تحتاج مترجم وسيطلتحويل الصلاحيات الى سلسلة نصية والعكس بين برنامجك واي برنامج اخر سوف تضيفه مستقبلا .. والمشكلة الاكبر لو هناك من سيكمل على برنامجك ! ..

بالفعل لم أفكر في مسألة تكامل النظام مع أي برمجيات أُخرى، بالنسبة لعمل أحد على المشروع ففي هذه الحالة عليه تتبع عمل الكود خطوة خطوة :)

احاول تخيل processعند تعديل الصلاحيات !!!!! او خطأ في الصلاحيات كيف سيكون التتبع والمعالجة !!!!! يارب سترك :)

اضافة الى انك تعتمد 0 - 1 لكل حقل .. وتسنده ايضا لمثلها ان كان اب او ابن .. وتسندها الى ما هو اعلى Modul .. ثم الى ما هو اعلى وهكذا !!؟؟

يعني حتشتغل بلوكات ثابتة .. الى بلوكات ثابته اخرى اعلى .. الى بلوكات ثابته اخرى !!!

حقيقًا لا اعلم الكيفية التى وصلتك في الطريقة التي اتبعها أعلاه ولكن سأحاول توضيحها بشكل أفضل.

الشكل الذي استخدمه حاليًا كالتالي:

permissons
    add edit delete view change

users
    ahmed:      11111
    mohamed:    11011
    khaled:     00010
  • فأنا أعتمد على عدد الصلاحيات وترتيبهم، فعدد الصلاحيات يعني طول سلسة الصلاحيات وموضع الصلاحية هو قيمتها سواء 0 أو 1 في السلسة النصية، في حالة تعديل الصلاحية سيتم التعرف على موضع الصلاحية في السلسة النصية من خلال موضعها في مصفوفة الصلاحيات ليتم تعديل قيمتها. والشكل الذي وضعته في الرد

    سيكون على النحو:

    permissions
        add edit delete view change
    
    Rouls
        super_admin 11111
        admin       11011
        editor      01011
        writer      10011
        viewer      00010
        user        00011
        vistor      00000
    
    users
        ahmed: super_admin
        mohamed: admin
        khaled: editor, writer
    

وبالتالي عمليات تعديل الصلاحيات تكون على مستوى الدور

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

ملاحظة: هذا الرد كنت أكتب به قبل مُكالمتك، فوجدت أنه سيكون به بعض الإيضاح للفكرة أعلاه فتركته :)