mirror of https://github.com/jumpserver/jumpserver
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.2 KiB
145 lines
4.2 KiB
from django.apps import apps |
|
from django.contrib.auth.models import ContentType as DjangoContentType |
|
from django.contrib.auth.models import Permission as DjangoPermission |
|
from django.db.models import Q |
|
from django.utils.translation import gettext_lazy as _ |
|
|
|
from common.utils import lazyproperty |
|
from .. import const |
|
|
|
Scope = const.Scope |
|
|
|
__all__ = ['Permission', 'ContentType'] |
|
|
|
|
|
class ContentType(DjangoContentType): |
|
class Meta: |
|
proxy = True |
|
verbose_name = _('ContentType') |
|
|
|
_apps_map = {} |
|
|
|
@property |
|
def app_model(self): |
|
return '%s.%s' % (self.app_label, self.model) |
|
|
|
@classmethod |
|
def apps_map(cls): |
|
from ..tree import app_nodes_data |
|
if cls._apps_map: |
|
return cls._apps_map |
|
mapper = {} |
|
for d in app_nodes_data: |
|
i = d['id'] |
|
name = d.get('name') |
|
|
|
if not name: |
|
config = apps.get_app_config(d['id']) |
|
if config: |
|
name = config.verbose_name |
|
if name: |
|
mapper[i] = name |
|
cls._apps_map = mapper |
|
return mapper |
|
|
|
@property |
|
def app_display(self): |
|
return self.apps_map().get(self.app_label) |
|
|
|
@lazyproperty |
|
def fields(self): |
|
model = self.model_class() |
|
return model._meta.fields |
|
|
|
@lazyproperty |
|
def field_names(self): |
|
return [f.name for f in self.fields] |
|
|
|
@lazyproperty |
|
def filter_field_names(self): |
|
names = [] |
|
if 'name' in self.field_names: |
|
names.append('name') |
|
if 'address' in self.field_names: |
|
names.append('address') |
|
return names |
|
|
|
def filter_queryset(self, queryset, keyword): |
|
q = Q() |
|
for name in self.filter_field_names: |
|
q |= Q(**{name + '__icontains': keyword}) |
|
return queryset.filter(q) |
|
|
|
|
|
class Permission(DjangoPermission): |
|
""" 权限类 """ |
|
|
|
class Meta: |
|
proxy = True |
|
verbose_name = _('Permissions') |
|
|
|
@classmethod |
|
def to_perms(cls, queryset): |
|
perms = queryset.values_list( |
|
'content_type__app_label', 'codename' |
|
) |
|
perms = list(set(["%s.%s" % (ct, codename) for ct, codename in perms])) |
|
return sorted(perms) |
|
|
|
@property |
|
def app_label_codename(self): |
|
return '%s.%s' % (self.content_type.app_label, self.codename) |
|
|
|
@classmethod |
|
def get_define_permissions_q(cls, defines): |
|
""" |
|
:param defines: [(app, model, codename),] |
|
:return: |
|
""" |
|
if not defines: |
|
return None |
|
q = Q() |
|
|
|
for define in defines: |
|
app_label, model, actions, resource, *args = list(define) |
|
kwargs = {} |
|
if app_label != '*': |
|
kwargs['content_type__app_label'] = app_label |
|
if model != '*': |
|
kwargs['content_type__model'] = model |
|
|
|
actions_list = [a.strip() for a in actions.split(',')] |
|
actions_regex = '|'.join(actions_list) |
|
if actions == '*' and resource == '*': |
|
pass |
|
elif actions == '*' and resource != '*': |
|
kwargs['codename__iregex'] = r'[a-z]+_{}$'.format(resource) |
|
elif actions != '*' and resource == '*': |
|
kwargs['codename__iregex'] = r'({})_[a-z]+'.format(actions_regex) |
|
else: |
|
kwargs['codename__iregex'] = r'({})_{}$'.format(actions_regex, resource) |
|
q |= Q(**kwargs) |
|
return q |
|
|
|
@classmethod |
|
def clean_permissions(cls, permissions, scope=Scope.system): |
|
if scope == Scope.org: |
|
excludes = const.org_exclude_permissions |
|
else: |
|
excludes = const.system_exclude_permissions |
|
q = cls.get_define_permissions_q(excludes) |
|
if q: |
|
permissions = permissions.exclude(q) |
|
return permissions |
|
|
|
@staticmethod |
|
def create_tree_nodes(permissions, scope, check_disabled=False): |
|
from ..tree import PermissionTreeUtil |
|
util = PermissionTreeUtil(permissions, scope, check_disabled) |
|
return util.create_tree_nodes() |
|
|
|
@classmethod |
|
def get_permissions(cls, scope): |
|
permissions = cls.objects.all() |
|
permissions = cls.clean_permissions(permissions, scope=scope) |
|
return permissions
|
|
|