Skip to content

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:

  1. 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。

  2. Different authorization rules are divided through different SCHEMA,So when the developer designed the SCHEMA,Need to pass register_impowerrule_schema,Register。

  3. After the registration is completed,Page green Type fields that create authorized rules will have one more authorized rules,As shown below:

    jqhUld.md.jpg

    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

    1. parameter: This methodKwargsevent Two 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
      1. data.userCan get the current user;
      2. 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;
      3. data.arr You can get user permissions array (0 or 1 composition,0 is no authority,1 There is authority,SOON's sort_ID is the same);
      4. data.config You can get the current authorization rules
    2. 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

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) #

获取所有的配置

Source code in arkid/core/extension/impower_rule.py
def get_all_config(self, tenant_id):
    '''
    获取所有的配置
    '''
    return TenantExtensionConfig.active_objects.filter(
        tenant_id=tenant_id,
        extension__in=self.get_extensions()
    ).all()

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
@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

get_extensions(self) #

获取当前类型所有的插件

Source code in arkid/core/extension/impower_rule.py
def get_extensions(self):
    '''
    获取当前类型所有的插件
    '''
    return Extension_Obj.active_objects.filter(
        package=self.package,
        type=self.TYPE
    ).all()

load(self) #

抽象方法,插件加载的入口方法

Source code in arkid/core/extension/impower_rule.py
def load(self):
    super().load()
    self.listen_event(core_event.GET_AUTH_RESULT, self.filter_auth_result)

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
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'])

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

load(self) #

抽象方法,插件加载的入口方法

Source code in extension_root/com_longgui_impower_rule/__init__.py
def load(self):
    super().load()
    # 注册前端页面
    self.load_front_page()
    # 注册schema
    self.register_impower_rule_schema(ImpowerRuleCreateIn, 'DefaultImpowerRule')

load_front_page(self) #

注册前端页面

Source code in extension_root/com_longgui_impower_rule/__init__.py
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)

评论