AuthorizationRules
Features#
Authorization rules,As a system of certification, supplementation,It can support more fine -grained permissions given。 It can support the given authority for different attributes of users,For example user name、Nick name、gender、Mobile phone number waiting。 You can also give the permissions of the different attributes of the grouping。 You can also according to the development of the developer,The structure of the data storage,Realize the authority of permission in specific scenarios。
Implementation#
arkidThe system has assumed the permissions of the user attributes by default,Convenient developer for reference
graph LR
  A[start] --> B {Design SCHEMA} --> C {Register the front -end page}--> D {register SCHEMA}--> E {Implementing the authorization function} --> F [End];Let's make a brief introduction to the realization of ideas:
- 
Need developers want to know the attributes that need to be screened if they develop plugins,Is the user attribute,Still packet attributes,Or other attributes。And those applications need to be filtered,And those permissions。 To design schema,Used to store data structure。If there are some application lists in SCHEMA,Permission list,User lists, etc.,Need to use the front -end page used,Use the parent class register_front_pages registered separately。 
- 
Different authorization rules are divided through different SCHEMA,So when the developer designed the SCHEMA,Need to pass register_impowerrule_schema,Register。 
- 
After the registration is completed,Page green Type fields that create authorized rules will have one more authorized rules,As shown below: If we choose different authorization rules,The red part will show different content,The display content is determined by the SCHEMA structure。 Create editing and deletion of authorization rules,They are all processed in advance by Arkid,Developers only need to pay attention to the method of power。 Let's introduce the use of the method of empowerment: Need developers to implement [GET_auth_result(event, **Kwargs)] (#arkid.core.extension.impower_rule.ImpowerRuleBaseExtension.get_auth_Result) method - parameter: This methodKwargs,eventTwo parameters,We focus oneventparameter,This parameter containsdataandtenantTwo attributes,inevent.tenantYou can get the current tenant;event.dataYou can get the data passed over。We get the value in the data- data.userCan get the current user;
- data.appCan get the current application,If this application is a None,It means that the application is arkid,On the contrary, it is other applications;
- data.arrYou can get user permissions array (0 or 1 composition,0 is no authority,1 There is authority,SOON's sort_ID is the same);
- data.configYou can get the current authorization rules
 
- use: Developers need to be based on the rules of authorizationevent.config,Combinedata.user,According to your own needs,After screening,Return to SORT with permissions_ID array
 
- parameter: This method
Abstract method#
Foundation definition#
        
arkid.core.extension.impower_rule.ImpowerRuleBaseExtension            (Extension)
        
#
    Source code in arkid/core/extension/impower_rule.py
          class ImpowerRuleBaseExtension(Extension):
    TYPE = 'impower_rule'
    composite_schema_map = {}
    created_composite_schema_list = []
    composite_key = 'type'
    composite_model = TenantExtensionConfig
    @property
    def type(self):
        return ImpowerRuleBaseExtension.TYPE
    def load(self):
        super().load()
        self.listen_event(core_event.GET_AUTH_RESULT, self.filter_auth_result)
    def get_extensions(self):
        '''
        获取当前类型所有的插件
        '''
        return Extension_Obj.active_objects.filter(
            package=self.package,
            type=self.TYPE
        ).all()
    def get_all_config(self, tenant_id):
        '''
        获取所有的配置
        '''
        return TenantExtensionConfig.active_objects.filter(
            tenant_id=tenant_id,
            extension__in=self.get_extensions()
        ).all()
    def register_impower_rule_schema(self, schema, impowerrule_type):
        """
        注册授权规则的schema
        Params:
            schema: schema
            impowerrule_type: 授权规则类型
        """
        self.register_config_schema(schema, self.package + '_' + impowerrule_type)
        self.register_composite_config_schema(schema, impowerrule_type, exclude=['extension'])
    def filter_auth_result(self, event, **kwargs):
        '''
        筛选抽象结果
        '''
        tenant = event.tenant
        configs = self.get_all_config(tenant.id)
        data = event.data
        arr = data.get('arr', [])
        copy_arr = [x for x in arr]
        result_sort_ids = []
        # 每一个授权规则配置单独验证
        for config in configs:
            data['config'] = config
            sort_ids = self.get_auth_result(event, **kwargs)
            if sort_ids:
                result_sort_ids.extend(sort_ids)
        # 对于授权结果进行合并
        for index, value in enumerate(copy_arr):
            if int(value) == 0 and index in result_sort_ids:
                copy_arr[index] = 1
        return copy_arr
    @abstractmethod
    def get_auth_result(self, event, **kwargs):
        """
        抽象方法,获取权限的鉴定结果
        Params:
            event: 事件参数
                data: 数据
                    user: 用户
                    app: 应用(如果app是None,就表示这个应用是arkid)
                    arr: 权限结果数组(这个是已经赋值过分组权限的数据,有权限是1,没权限是0)
                    config: 应用的授权规则
                tenant: 租户
            kwargs: 其它方法参数
        Return:
            arr: sort_id数组
        """
        pass
        
composite_model            (BaseModel)
        
  
      django-model
  
#
    TenantExtensionConfig(id, is_del, is_active, updated, created, tenant, extension, config, name, type)
Source code in arkid/core/extension/impower_rule.py
          class TenantExtensionConfig(BaseModel):
    class Meta(object):
        verbose_name = _("插件运行时配置")
        verbose_name_plural = _("插件运行时配置")
    tenant = models.ForeignKey('core.Tenant', blank=False, on_delete=models.PROTECT, verbose_name=_('租户'))
    extension = models.ForeignKey('Extension', blank=False, on_delete=models.PROTECT, verbose_name=_('插件'))
    config = models.JSONField(blank=True, default=dict, verbose_name=_('Runtime Config','运行时配置'))
    name = models.CharField(max_length=128, default='', verbose_name=_('名称'))
    type = models.CharField(max_length=128, default='', verbose_name=_('类型'))
config: JSONField
  
      blank
      django-field
  
#
    Runtime Config
created: DateTimeField
  
      blank
      django-field
      nullable
  
#
    创建时间
extension: ForeignKey
  
      django-field
  
#
    插件
id: UUIDField
  
      django-field
  
#
    ID
is_active: BooleanField
  
      django-field
  
#
    是否可用
is_del: BooleanField
  
      django-field
  
#
    是否删除
name: CharField
  
      django-field
  
#
    名称
tenant: ForeignKey
  
      django-field
  
#
    租户
type: CharField
  
      django-field
  
#
    类型
updated: DateTimeField
  
      blank
      django-field
      nullable
  
#
    更新时间
filter_auth_result(self, event, **kwargs)
#
    筛选抽象结果
Source code in arkid/core/extension/impower_rule.py
          def filter_auth_result(self, event, **kwargs):
    '''
    筛选抽象结果
    '''
    tenant = event.tenant
    configs = self.get_all_config(tenant.id)
    data = event.data
    arr = data.get('arr', [])
    copy_arr = [x for x in arr]
    result_sort_ids = []
    # 每一个授权规则配置单独验证
    for config in configs:
        data['config'] = config
        sort_ids = self.get_auth_result(event, **kwargs)
        if sort_ids:
            result_sort_ids.extend(sort_ids)
    # 对于授权结果进行合并
    for index, value in enumerate(copy_arr):
        if int(value) == 0 and index in result_sort_ids:
            copy_arr[index] = 1
    return copy_arr
get_all_config(self, tenant_id)
#
    
  
get_auth_result(self, event, **kwargs)
#
    抽象方法,获取权限的鉴定结果
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| event | 事件参数 data: 数据 user: 用户 app: 应用(如果app是None,就表示这个应用是arkid) arr: 权限结果数组(这个是已经赋值过分组权限的数据,有权限是1,没权限是0) config: 应用的授权规则 tenant: 租户 | required | |
| kwargs | 其它方法参数 | {} | 
Returns:
| Type | Description | 
|---|---|
| arr | sort_id数组 | 
Source code in arkid/core/extension/impower_rule.py
          
        
get_extensions(self)
#
    
  
load(self)
#
    
  
register_impower_rule_schema(self, schema, impowerrule_type)
#
    注册授权规则的schema
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| schema | schema | required | |
| impowerrule_type | 授权规则类型 | required | 
Source code in arkid/core/extension/impower_rule.py
          
        Exemplary#
        
extension_root.com_longgui_impower_rule.ImpowerRuleExtension            (ImpowerRuleBaseExtension)
        
#
    Source code in extension_root/com_longgui_impower_rule/__init__.py
          class ImpowerRuleExtension(ImpowerRuleBaseExtension):
    def load(self):
        super().load()
        # 注册前端页面
        self.load_front_page()
        # 注册schema
        self.register_impower_rule_schema(ImpowerRuleCreateIn, 'DefaultImpowerRule')
    def load_front_page(self):
        '''
        注册前端页面
        '''
        self.register_front_pages(user_field_page)
        self.register_front_pages(app_page)
        self.register_front_pages(app_permission_page)
    def get_auth_result(self, event, **kwargs):
        '''
        获取权限鉴定结果
        '''
        data = event.data
        tenant = event.tenant
        user = data.get('user')
        config = data.get('config')
        # 处理授权逻辑
        permission_info = {}
        # 取得了所有配置
        config_info = config.config
        config_matchfield = config_info.get('matchfield')
        config_matchsymbol = config_info.get('matchsymbol')
        config_matchvalue = config_info.get('matchvalue')
        config_app = config_info.get('app')
        config_app_id = config_app.get('id')
        config_permissions = config_info.get('permissions')
        # 用户扩展字段用于筛选
        user = User.expand_objects.filter(id=user.id).first()
        # 选择的字段值
        select_value = user.get(config_matchfield.get('id'))
        # 取得返回值
        sort_ids = []
        if config_matchsymbol == '等于' and config_matchvalue == select_value:
            for config_permission in config_permissions:
                sort_ids.append(config_permission.get('sort_id'))
        return sort_ids
get_auth_result(self, event, **kwargs)
#
    获取权限鉴定结果
Source code in extension_root/com_longgui_impower_rule/__init__.py
          def get_auth_result(self, event, **kwargs):
    '''
    获取权限鉴定结果
    '''
    data = event.data
    tenant = event.tenant
    user = data.get('user')
    config = data.get('config')
    # 处理授权逻辑
    permission_info = {}
    # 取得了所有配置
    config_info = config.config
    config_matchfield = config_info.get('matchfield')
    config_matchsymbol = config_info.get('matchsymbol')
    config_matchvalue = config_info.get('matchvalue')
    config_app = config_info.get('app')
    config_app_id = config_app.get('id')
    config_permissions = config_info.get('permissions')
    # 用户扩展字段用于筛选
    user = User.expand_objects.filter(id=user.id).first()
    # 选择的字段值
    select_value = user.get(config_matchfield.get('id'))
    # 取得返回值
    sort_ids = []
    if config_matchsymbol == '等于' and config_matchvalue == select_value:
        for config_permission in config_permissions:
            sort_ids.append(config_permission.get('sort_id'))
    return sort_ids
