logologo
البدء
الدليل
التطوير
الإضافات
API
English
简体中文
日本語
한국어
Deutsch
Français
Español
Português
Русский
Italiano
Türkçe
Українська
Tiếng Việt
Bahasa Indonesia
ไทย
Polski
Nederlands
Čeština
العربية
עברית
हिन्दी
Svenska
البدء
الدليل
التطوير
الإضافات
API
logologo

بدء سريع

نظرة عامة على تطوير الإضافات
كتابة الإضافة الأولى
هيكل دليل المشروع

تطوير الواجهة الخلفية

نظرة عامة
Plugin
جداول بيانات Collections
عمليات Database
إدارة مصادر بيانات DataSourceManager
إدارة موارد ResourceManager
التحكم في أذونات ACL
Middleware
Cache
Event
سياق طلب Context
نص ترقية Migration
Logger
Telemetry
I18n (تدويل)
Command (سطر الأوامر)
إدارة المهام المجدولة CronJobManager
Test

تطوير الواجهة الأمامية

نظرة عامة
Plugin
Context (السياق)
Router
التحكم في أذونات ACL
إدارة مصادر بيانات DataSourceManager
Resource
Request
Styles & Themes (الأنماط والمظاهر)
Logger
I18n (تدويل)
Test

أخرى

دليل ترقية الإضافات
قائمة اللغات
إدارة التبعيات
البناء
Previous Pageإدارة موارد ResourceManager
Next PageMiddleware
إشعار الترجمة بالذكاء الاصطناعي

تمت ترجمة هذه الوثائق تلقائيًا بواسطة الذكاء الاصطناعي.

#التحكم بالصلاحيات باستخدام ACL (قائمة التحكم بالوصول)

تُستخدم ACL (قائمة التحكم بالوصول) للتحكم في صلاحيات عمليات الموارد. يمكنك منح الصلاحيات للأدوار، أو تجاوز قيود الأدوار وتحديد الصلاحيات مباشرةً. يوفر نظام ACL آلية مرنة لإدارة الصلاحيات، تدعم مقتطفات الصلاحيات (Snippets)، والبرمجيات الوسيطة (Middleware)، والتحقق الشرطي، وطرقًا أخرى متعددة.

ملاحظة

كائنات ACL تنتمي إلى مصادر البيانات (dataSource.acl). يمكن الوصول إلى ACL لمصدر البيانات الرئيسي عبر app.acl. لاستخدام ACL لمصادر البيانات الأخرى، راجع فصل إدارة مصادر البيانات.

#تسجيل مقتطفات الصلاحيات (Snippets)

تُمكن مقتطفات الصلاحيات (Snippets) من تسجيل مجموعات الصلاحيات الشائعة كوحدات صلاحيات قابلة لإعادة الاستخدام. بعد ربط الدور بمقتطف، يحصل على مجموعة الصلاحيات المقابلة، مما يقلل من التكوين المتكرر ويحسن كفاءة إدارة الصلاحيات.

acl.registerSnippet({
  name: 'ui.customRequests', // البادئة ui.* تشير إلى الصلاحيات التي يمكن تهيئتها في الواجهة
  actions: ['customRequests:*'], // عمليات المورد المقابلة، تدعم أحرف البدل
});

#الصلاحيات التي تتجاوز قيود الأدوار (allow)

تُستخدم acl.allow() للسماح لبعض العمليات بتجاوز قيود الأدوار، وهي مناسبة لواجهات برمجة التطبيقات العامة (APIs)، والسيناريوهات التي تتطلب تقييمًا ديناميكيًا للصلاحيات، أو الحالات التي يحتاج فيها تحديد الصلاحيات إلى أن يستند إلى سياق الطلب.

// وصول عام، لا يتطلب تسجيل الدخول
acl.allow('app', 'getLang', 'public');

// متاح للمستخدمين المسجلين دخولهم
acl.allow('app', 'getInfo', 'loggedIn');

// بناءً على شرط مخصص
acl.allow('orders', ['create', 'update'], (ctx) => {
  return ctx.auth.user?.isAdmin ?? false;
});

وصف معلمة condition:

  • 'public': يمكن لأي مستخدم (بما في ذلك المستخدمين غير المسجلين دخولهم) الوصول دون أي مصادقة.
  • 'loggedIn': يمكن للمستخدمين المسجلين دخولهم فقط الوصول، ويتطلب هوية مستخدم صالحة.
  • (ctx) => Promise<boolean> أو (ctx) => boolean: دالة مخصصة تحدد ديناميكيًا ما إذا كان الوصول مسموحًا به بناءً على سياق الطلب، ويمكنها تنفيذ منطق صلاحيات معقد.

#تسجيل برمجيات وسيطة للصلاحيات (use)

تُستخدم acl.use() لتسجيل برمجيات وسيطة مخصصة للصلاحيات، مما يسمح بإدراج منطق مخصص في سير عمل فحص الصلاحيات. تُستخدم عادةً بالاقتران مع ctx.permission لقواعد الصلاحيات المخصصة. وهي مناسبة للسيناريوهات التي تتطلب تحكمًا غير تقليدي في الصلاحيات، مثل النماذج العامة التي تحتاج إلى التحقق من كلمة مرور مخصصة، أو فحوصات الصلاحيات الديناميكية بناءً على معلمات الطلب، وما إلى ذلك.

سيناريوهات التطبيق النموذجية:

  • سيناريوهات النماذج العامة: لا يوجد مستخدم ولا دور، ولكن يجب تقييد الصلاحيات عبر كلمات مرور مخصصة.
  • التحكم في الصلاحيات بناءً على معلمات الطلب، وعناوين IP، وشروط أخرى.
  • قواعد صلاحيات مخصصة، تتجاوز أو تعدل سير عمل فحص الصلاحيات الافتراضي.

التحكم في الصلاحيات عبر ctx.permission:

acl.use(async (ctx, next) => {
  const { resourceName, actionName } = ctx.action;
  
  // مثال: نموذج عام يتطلب التحقق من كلمة المرور لتجاوز فحص الصلاحيات
  if (resourceName === 'publicForms' && actionName === 'submit') {
    const password = ctx.request.body?.password;
    if (password === 'your-secret-password') {
      // تم التحقق بنجاح، تجاوز فحص الصلاحيات
      ctx.permission = {
        skip: true,
      };
    } else {
      ctx.throw(403, 'Invalid password');
    }
  }
  
  // تنفيذ فحص الصلاحيات (متابعة سير عمل ACL)
  await next();
});

وصف خاصية ctx.permission:

  • skip: true: يتجاوز فحوصات صلاحيات ACL اللاحقة ويسمح بالوصول مباشرةً.
  • يمكن تعيينه ديناميكيًا في البرمجيات الوسيطة بناءً على منطق مخصص لتحقيق تحكم مرن في الصلاحيات.

#إضافة قيود بيانات ثابتة لعمليات محددة (addFixedParams)

يمكن لـ addFixedParams إضافة قيود نطاق بيانات ثابتة (فلتر) لعمليات موارد معينة. تتجاوز هذه القيود قيود الأدوار وتُطبق مباشرةً، وتُستخدم عادةً لحماية بيانات النظام الحساسة.

acl.addFixedParams('roles', 'destroy', () => {
  return {
    filter: {
      $and: [
        { 'name.$ne': 'root' },
        { 'name.$ne': 'admin' },
        { 'name.$ne': 'member' },
      ],
    },
  };
});

// حتى لو كان لدى المستخدم صلاحية حذف الأدوار، فلن يتمكن من حذف أدوار النظام مثل root و admin و member

تلميح: يمكن استخدام addFixedParams لمنع حذف أو تعديل البيانات الحساسة عن طريق الخطأ، مثل أدوار النظام المضمنة، وحسابات المسؤولين، وما إلى ذلك. تعمل هذه القيود بالاشتراك مع صلاحيات الأدوار، مما يضمن أنه حتى مع وجود الصلاحيات، لا يمكن التلاعب بالبيانات المحمية.

#التحقق من الصلاحيات (can)

تُستخدم acl.can() للتحقق مما إذا كان الدور يمتلك صلاحية لتنفيذ عملية محددة، وتُعيد كائن نتيجة الصلاحية أو null. تُستخدم عادةً للتحقق ديناميكيًا من الصلاحيات في منطق الأعمال، مثل تحديد ما إذا كانت عمليات معينة مسموح بها بناءً على الأدوار في البرمجيات الوسيطة أو معالجات العمليات.

const result = acl.can({
  roles: ['admin', 'manager'], // يمكن تمرير دور واحد أو مصفوفة من الأدوار
  resource: 'orders',
  action: 'delete',
});

if (result) {
  console.log(`الدور ${result.role} يمكنه تنفيذ عملية ${result.action}`);
  // يحتوي result.params على المعلمات الثابتة التي تم تعيينها عبر addFixedParams
  console.log('المعلمات الثابتة:', result.params);
} else {
  console.log('لا توجد صلاحية لتنفيذ هذه العملية');
}

تلميح: إذا تم تمرير أدوار متعددة، فسيتم فحص كل دور على حدة، وسيتم إرجاع النتيجة للدور الأول الذي يمتلك الصلاحية.

تعريفات الأنواع:

interface CanArgs {
  role?: string;      // دور واحد
  roles?: string[];   // أدوار متعددة (يتم فحصها بالتسلسل، وتُرجع الدور الأول الذي يمتلك الصلاحية)
  resource: string;   // اسم المورد
  action: string;    // اسم العملية
}

interface CanResult {
  role: string;       // الدور الذي يمتلك الصلاحية
  resource: string;   // اسم المورد
  action: string;    // اسم العملية
  params?: any;       // معلومات المعلمات الثابتة (إذا تم تعيينها عبر addFixedParams)
}

#تسجيل العمليات القابلة للتهيئة (setAvailableAction)

إذا كنت ترغب في أن تكون العمليات المخصصة قابلة للتهيئة في الواجهة (مثل عرضها في صفحة إدارة الأدوار)، فأنت بحاجة إلى استخدام setAvailableAction لتسجيلها. ستظهر العمليات المسجلة في واجهة تهيئة الصلاحيات، حيث يمكن للمسؤولين تهيئة صلاحيات العمليات للأدوار المختلفة.

acl.setAvailableAction('importXlsx', {
  displayName: '{{t("استيراد")}}', // اسم العرض في الواجهة، يدعم التدويل
  type: 'new-data',               // نوع العملية
  onNewRecord: true,              // ما إذا كانت ستدخل حيز التنفيذ عند إنشاء سجلات جديدة
});

وصف المعلمات:

  • displayName: الاسم المعروض في واجهة تهيئة الصلاحيات، يدعم التدويل (باستخدام تنسيق {{t("key")}}).
  • type: نوع العملية، يحدد تصنيف هذه العملية في تهيئة الصلاحيات.
    • 'new-data': العمليات التي تنشئ بيانات جديدة (مثل الاستيراد، الإنشاء، إلخ).
    • 'existing-data': العمليات التي تعدل البيانات الموجودة (مثل التحديث، الحذف، إلخ).
  • onNewRecord: ما إذا كانت ستدخل حيز التنفيذ عند إنشاء سجلات جديدة، صالحة فقط للنوع 'new-data'.