الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

طريقة فعالة لمعالجة صلاحيات المستخدمين

بدأه najy_zl في 4 يناير 2009 · 5 رد · 2,347 مشاهدة · في لغة Ms Visual Basic 6 وما قبلها من إصدارات
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم...

استعمال حقل من النوع Boolean (نعم/لا في Access) لكل صلاحية من الصلاحيات في جدول المستخدمين (Users) أو المشغلين قد يكون مقبولاً إذا كان عدد الصلاحيات 4 أو 5، مع عدم احتمال زيادة تلك الصلاحيات.

لكن ماذا لو كان عدد الصلاحيات 15 أو 20 أو 30 صلاحية؟؟!! من غير المعقول أن يكون لدي 20 أو 30 حقلاً من أجل معالجة الصلاحيات!!! بالإضافة إلى أننا سنضطر لتعديل الجدول في قاعدة البيانات كلما تم تعديل عدد الصلاحيات.

من واقع التجربة وجدت أن أفضل طريقة هي استعمال فكرة قناع البتات (BitMask) و ذلك باستعمال حقل رقمي من النوع الصحيح الطويل (Long) و هذا سيعطينا المجال للتعامل مع 32 صلاحية إذا استعملنا Access. و إذا كنا نستعمل SQL Server فإننا نستطيع استعمال حقل من النوع bigint للتعامل مع 64 صلاحية.

لتوضيح الفكرة - و هي بسيطة جداً - سنستعمل البايت (Byte) كمثال. نعرف أن البايت تتكون من 8 بتات (من 0 عند اليمين إلى 7 عند أقصى اليسار. لكننا سنتعامل معها على أنها مرقمة من 1 إلى 8)، و بالتالي فإن قيم هذه البتات هي:

2^0 = 1

2^1 = 2

2^2 = 4

2^3 = 8

2^4 = 16

2^5 = 32

2^6 = 64

2^7 = 128

إذن مع البايت يمكنني أن أتعامل مع 8 صلاحيات. كيف؟ نعطي للصلاحيات أرقام البتات، و يستحسن استخدام الثوابت حتى لا نضطر إلى حفظ القيم، مثلاً:

  1. ' Module في
  2. Public Const AUTH_ADD = 1& ' إضافة سجلات جديدة
  3. Public Const AUTH_MODIFY = 2& ' تعديل بيانات
  4. Public Const AUTH_DELETE = 3& ' حذف سجلات
  5. Public Const AUTH_BACKUP = 4& ' حفظ نسخة احتياطية
  6. Public Const AUTH_PRINT = 5& ' طباعة التقارير
  7.  

لاحظ أننا نضع العلامة & مع الأرقام ليعاملها البرنامج على أنه من النوع Long.

إذا كان من حق المستخدم مثلاً أن يضيف سجلات فقط فإننا نضبط قيمة البايت على 1، و إذا كان من صلاحياته أن يقوم بالنسخ الاحتياطي فقط فإننا نضبط قيمة البايت على 8.

ماذا لو كان من صلاحياته أن يقوم بالعملين معاً؟؟ نضبط قيمة البايت على 9 (1 و 8) و إذا كان من حقه أيضاً أن يطبع التقارير فإننا نضبط القيمة على 25 (1 و 8 و 16) ... إلخ.

و إذا أردنا منح المستخدم كافة الصلاحيات فيجب ضبط جميع البتات على 1 أي ستكون قيمة البايت 255.

إذا قمنا بتكبير العدد من بايت إلى عدد صحيح طويل (Long) فذلك يعني أننا سنتعامل مع 4 بايت، و بالتالي 4 × 8 = 32 صلاحية.

نأتي إلى الجانب العملي:

نفرض أن لدينا جدول المستخدمين اسمه Users و يتكون من الحقول التالية:

رقم المستخدم UserID

اسم المستخدم UserName

كلمة المرور Password

الصلاحيات Authority (من النوع الرقمي Number و حجمه عدد صحيح طويل Long).

و ربما يكون لديك حقول أخرى. لا يهم.

لن أتحدث هنا عن كيفية الربط مع الجدول من داخل VB و كيفية التأكد من وجود اسم المستخدم و صحة كلمة المرور! لكني سأفترض أننا نستعمل مكون ADO data control باسم Adodc1 مرتبط بالجدول Users و أننا وجدنا الاسم في الجدول و أن كلمة المرور المدخلة صحيحة.

علينا الآن أن نحتفظ بقيمة الحقل Authority (الذي يمثل الصلاحيات) في متغير عام مصرح عنه في Module كالتالي (يمكنك اختيار أي اسم له). سنحتاج أيضاً للحصول على رقم المستخدم لحفظ الصلاحيات فيما بعد

  1. Public UserAuthority As Long
  2. Public Uid As Long
  3.  

إذن بعد التأكد من وجود الاسم و صحة كلمة المرور سيكون لدينا السطران التاليان:

  1. UserAuthority = Adodc1.Recordset("Authority")
  2. Uid = Adodc1.Recordset("UserID")
  3.  

أيضاً في الـ Module سنكتب 4 إجراءات و دالة واحدة:

  1. ' إجراء لإضافة صلاحية إلى مجموعة الصلاحيات
  2. Public Sub AddAuthority(ByRef Authorities As Long, ByVal Authority As Long)
  3. Dim AuthorityValue As Long
  4.  
  5. If (Authority >= 1) And (Authority <= 32) Then
  6. AuthorityValue = 2 ^ (Authority - 1)
  7. Authorities = (Authorities Or AuthorityValue)
  8. End If
  9. End Sub
  10.  
  11. ' إجراء لمنح المستخدم كافة الصلاحيات
  12. Public Sub AddAllAuthorities(ByRef Authorities As Long)
  13. Authorities = -1&
  14. End Sub
  15.  
  16. ' إجراء لحذف صلاحية من المستخدم
  17. Public Sub RemoveAuthority(ByRef Authorities As Long, ByVal Authority As Integer)
  18. Dim AuthorityValue As Long
  19.  
  20. If (Authority >= 1) And (Authority <= 32) Then
  21. AuthorityValue = 2 ^ (Authority - 1)
  22. Authorities = (Authorities And (Not AuthorityValue))
  23. End If
  24. End Sub
  25.  
  26. ' إجراء لحذف كافة الصلاحيات
  27. Public Sub RemoveAllAuthorities(ByRef Authorities As Long)
  28. Authorities = 0&
  29. End Sub
  30.  
  31. ' دالة للتحقق من وجود صلاحية معينة ضمن الصلاحيات
  32. Public Function UserAuthorized(ByVal Authorities As Long, ByVal Authority As Long) As Boolean
  33. Dim AuthorityValue As Long
  34.  
  35. If (Authority < 1) Or (Authority > 32) Then
  36. UserAuthorized = False
  37. Else
  38. AuthorityValue = 2 ^ (Authority - 1)
  39. If (Authorities And AuthorityValue) = AuthorityValue Then
  40. UserAuthorized = True
  41. Else
  42. UserAuthorized = False
  43. End If
  44. End If
  45. End Function
  46.  

في كل الإجراءات السابقة، البارامتر Authorities هو مجموع صلاحيات المستخدم (الذي يمثله المتغير UserAuthority) و Authority هو أحد أرقام الصلاحيات المطلوبة (و التي قمنا بتعريفها كثوابت في البداية).

و الآن لنفرض أن المستخدم يريد أن يضيف سجلاً جديداً، و نريد أن نتأكد أنه من صلاحياته أن يفعل ذلك:

  1. If UserAuthorized(UserAuthority, AUTH_ADD) Then
  2. ' ...
  3. ' إجراءات تنفيذ الإضافة
  4. ' ...
  5. Else
  6. MsgBox "المعذرة. ليس من صلاحياتك إضافة سجلات جديدة"
  7. End If
  8.  

و إذا أردنا أن نمنح المستخدم صلاحية طباعة التقارير:

  1. AddAuthority UserAuthority, AUTH_PRINT
  2.  

و لمنحه كافة الصلاحيات:

  1. AddAllAuthorities UserAuthority
  2.  

لتعديل صلاحيات مستخدم آخر غير المستخدم الحالي - و هو ما يحدث غالباً - احتفظ برقمه و قيمة صلاحياته في متغيرين (من Adocdc1.Recordset) ثم استعمل الإجراءات المذكورة أعلاه لتعديل قيمة الصلاحيات، ثم لا تنس أن تحفظ القيمة الجديدة للصلاحيات في الجدول:

  1. Adodc1.Recordset("Authority") = UserAuthority
  2. Adodc1.Recordset.Update
  3.  

طبعاً بدل المتغير UserAuthority ستستعمل اسم المتغير لديك، بالإضافة إلى أنك قد تحتاج إلى البحث عن المستخدم برقمه في Adodc1.Recordset.

نرجو الاستفادة و السلام.

وَ قُلِ اعْمَلُوا فَسَيَرَى اللهُ عَمَلَكُمْ وَ رَسُولُهُ وَ الْمُؤْمِنُونَ

صدق الله العظيم

#2

الأخ الفاضل مشكور على هذه الفكرة ولكن

ماهو الداعى الى استخدام الأرقام ثم تحويلها الى النظام الثنائى لمعرفة موضع الصلاحية فيه اعتقد ان الموضوع اخذ وقت اكثر من اللازم

الأفضل هو استخدام حقل من النوع memo والصلاحيات تأخذ الشكل FFFTFTTFFT

وبذلك يمكن استيعاب صلاحيات تصل الى 65536 صلاحية

وللوصول الى الصلاحية رقم 150 مثلا

if mid(spec,150,1)="F" then msgbox "معذرة لا توجد صلاحية"

حيث spec متغير يحمل كل صلاحيات المستخدم

هذا مجرد اقتراح

وشكرا مرة اخرى

كن كالنخيل عن الأحقاد مرتفعا .. يرمى بصخر فيرمى أطيب الثمر

#3

أنا استخدم الطريقة الثانية دائما لأنها تمنح عدد صلاحيات أكبر استطيع عمل صلاحية لكل شاشة لكل مستخدم ...... أمر لامثيل له ....

وانصح بها

1
#4

السلام عليكم...

معكما حق! شكراً لكما (لو كان زر الشكر مازال موجوداً لأضفت شكراً لكل منكما). كلنا نحاول أن نفيد و نستفيد.

و السلام.

وَ قُلِ اعْمَلُوا فَسَيَرَى اللهُ عَمَلَكُمْ وَ رَسُولُهُ وَ الْمُؤْمِنُونَ

صدق الله العظيم

#5
najy_zl كتب:
السلام عليكم...

معكما حق! شكراً لكما (لو كان زر الشكر مازال موجوداً لأضفت شكراً لكل منكما). كلنا نحاول أن نفيد و نستفيد.

و السلام.

ولك الشكر استاذي الكريم على الطريقة الإحترافية ....

#6

مشكوررر أخي على الفكررره جاري التطبيق

اللهم إنا نتوسل بك إليك ونقسم بك عليك أن ترحم والدي ولا تعذبه

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

اللهم أسكنه فسيح الجنان واغفر له يارحمن وارحمه يارحيم.

مواضيع مشابهة

عدد الزوار حالياً

المتواجدون خلال آخر دقيقتين · يتحدّث كل ٣٠ ثانية

—الإجمالي—أعضاء مسجّلون—زوار بدون تسجيل

جارٍ التحقق من المتواجدين…