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.
152 lines
4.6 KiB
152 lines
4.6 KiB
from django.utils.translation import ugettext_lazy as _, gettext |
|
from django.db import models |
|
|
|
from common.db.models import JMSModel |
|
from common.utils import lazyproperty |
|
from .permission import Permission |
|
from ..builtin import BuiltinRole |
|
from .. import const |
|
|
|
__all__ = ['Role', 'SystemRole', 'OrgRole'] |
|
|
|
|
|
class SystemRoleManager(models.Manager): |
|
def get_queryset(self): |
|
queryset = super().get_queryset() |
|
return queryset.filter(scope=const.Scope.system) |
|
|
|
|
|
class OrgRoleManager(models.Manager): |
|
def get_queryset(self): |
|
queryset = super().get_queryset() |
|
return queryset.filter(scope=const.Scope.org) |
|
|
|
|
|
class Role(JMSModel): |
|
""" 定义 角色 | 角色-权限 关系 """ |
|
Scope = const.Scope |
|
|
|
name = models.CharField(max_length=128, verbose_name=_('Name')) |
|
scope = models.CharField( |
|
max_length=128, choices=Scope.choices, default=Scope.system, verbose_name=_('Scope') |
|
) |
|
permissions = models.ManyToManyField( |
|
'rbac.Permission', related_name='roles', blank=True, verbose_name=_('Permissions') |
|
) |
|
builtin = models.BooleanField(default=False, verbose_name=_('Built-in')) |
|
comment = models.TextField(max_length=128, default='', blank=True, verbose_name=_('Comment')) |
|
|
|
BuiltinRole = BuiltinRole |
|
objects = models.Manager() |
|
org_roles = OrgRoleManager() |
|
system_roles = SystemRoleManager() |
|
|
|
class Meta: |
|
unique_together = [('name', 'scope')] |
|
verbose_name = _('Role') |
|
|
|
def __str__(self): |
|
return '%s(%s)' % (self.name, self.get_scope_display()) |
|
|
|
def is_system_admin(self): |
|
return str(self.id) == self.BuiltinRole.system_admin.id and self.builtin |
|
|
|
def is_org_admin(self): |
|
return str(self.id) == self.BuiltinRole.org_admin.id and self.builtin |
|
|
|
def is_admin(self): |
|
yes = self.is_system_admin() or self.is_org_admin() |
|
return yes |
|
|
|
@staticmethod |
|
def get_scope_roles_perms(roles, scope): |
|
has_admin = any([r.is_admin() for r in roles]) |
|
if has_admin: |
|
perms = Permission.objects.all() |
|
else: |
|
perms = Permission.objects.filter(roles__in=roles).distinct() |
|
perms = Permission.clean_permissions(perms, scope=scope) |
|
return perms |
|
|
|
@classmethod |
|
def get_roles_permissions(cls, roles): |
|
org_roles = [role for role in roles if role.scope == cls.Scope.org] |
|
org_perms_id = cls.get_scope_roles_perms(org_roles, cls.Scope.org)\ |
|
.values_list('id', flat=True) |
|
|
|
system_roles = [role for role in roles if role.scope == cls.Scope.system] |
|
system_perms_id = cls.get_scope_roles_perms(system_roles, cls.Scope.system)\ |
|
.values_list('id', flat=True) |
|
perms_id = set(org_perms_id) | set(system_perms_id) |
|
permissions = Permission.objects.filter(id__in=perms_id)\ |
|
.prefetch_related('content_type') |
|
return permissions |
|
|
|
@classmethod |
|
def get_roles_perms(cls, roles): |
|
permissions = cls.get_roles_permissions(roles) |
|
return Permission.to_perms(permissions) |
|
|
|
def get_permissions(self): |
|
if self.is_admin(): |
|
permissions = Permission.objects.all() |
|
else: |
|
permissions = self.permissions.all() |
|
permissions = Permission.clean_permissions(permissions, self.scope) |
|
return permissions |
|
|
|
@lazyproperty |
|
def users(self): |
|
from .rolebinding import RoleBinding |
|
return RoleBinding.get_role_users(self) |
|
|
|
@lazyproperty |
|
def users_amount(self): |
|
return self.users.count() |
|
|
|
@lazyproperty |
|
def permissions_amount(self): |
|
return self.permissions.count() |
|
|
|
@classmethod |
|
def create_builtin_roles(cls): |
|
BuiltinRole.sync_to_db() |
|
|
|
@property |
|
def display_name(self): |
|
if not self.builtin: |
|
return self.name |
|
return gettext(self.name) |
|
|
|
def is_org(self): |
|
return self.scope == const.Scope.org |
|
|
|
@classmethod |
|
def get_roles_by_perm(cls, perm): |
|
app_label, codename = perm.split('.') |
|
p = Permission.objects.filter( |
|
codename=codename, |
|
content_type__app_label=app_label |
|
).first() |
|
if not p: |
|
return p.roles.none() |
|
role_ids = list(p.roles.all().values_list('id', flat=True)) |
|
admin_ids = [BuiltinRole.system_admin.id, BuiltinRole.org_admin.id] |
|
role_ids += admin_ids |
|
return cls.objects.filter(id__in=role_ids) |
|
|
|
|
|
class SystemRole(Role): |
|
objects = SystemRoleManager() |
|
|
|
class Meta: |
|
proxy = True |
|
verbose_name = _('System role') |
|
|
|
|
|
class OrgRole(Role): |
|
objects = OrgRoleManager() |
|
|
|
class Meta: |
|
proxy = True |
|
verbose_name = _('Organization role')
|
|
|