mirror of https://github.com/jumpserver/jumpserver
perf: 添加 is_org_admin (#7644)
* fix: 修复 org members 的问题 * perf: 修改 org member * perf: 修改 is sa * perf: 修改 active * perf: 修复写法 * perf: is_sa to is_service_account Co-authored-by: ibuler <ibuler@qq.com>pull/7645/head
parent
48d0c7b6cc
commit
63de4e1806
|
@ -327,11 +327,11 @@ class UserConnectionTokenViewSet(
|
||||||
}
|
}
|
||||||
CACHE_KEY_PREFIX = 'CONNECTION_TOKEN_{}'
|
CACHE_KEY_PREFIX = 'CONNECTION_TOKEN_{}'
|
||||||
rbac_perms = {
|
rbac_perms = {
|
||||||
'GET': 'view_connectiontoken',
|
'GET': 'authentication.view_connectiontoken',
|
||||||
'create': 'add_connectiontoken',
|
'create': 'authentication.add_connectiontoken',
|
||||||
'get_secret_detail': 'view_connectiontokensecret',
|
'get_secret_detail': 'authentication.view_connectiontokensecret',
|
||||||
'get_rdp_file': 'add_connectiontoken',
|
'get_rdp_file': 'authentication.add_connectiontoken',
|
||||||
'get_client_protocol_url': 'add_connectiontoken',
|
'get_client_protocol_url': 'authentication.add_connectiontoken',
|
||||||
}
|
}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -31,7 +31,7 @@ if len(defines_errors) != 0:
|
||||||
raise ValueError('Perms define error: {}'.format(defines_errors))
|
raise ValueError('Perms define error: {}'.format(defines_errors))
|
||||||
|
|
||||||
|
|
||||||
class PreRole:
|
class PredefineRole:
|
||||||
id_prefix = '00000000-0000-0000-0000-00000000000'
|
id_prefix = '00000000-0000-0000-0000-00000000000'
|
||||||
|
|
||||||
def __init__(self, index, name, scope, perms, perms_type='include'):
|
def __init__(self, index, name, scope, perms, perms_type='include'):
|
||||||
|
@ -45,7 +45,7 @@ class PreRole:
|
||||||
from rbac.models import Role
|
from rbac.models import Role
|
||||||
return Role.objects.get(id=self.id)
|
return Role.objects.get(id=self.id)
|
||||||
|
|
||||||
def get_defaults(self):
|
def _get_defaults(self):
|
||||||
from rbac.models import Permission
|
from rbac.models import Permission
|
||||||
q = Permission.get_define_permissions_q(self.perms)
|
q = Permission.get_define_permissions_q(self.perms)
|
||||||
permissions = Permission.get_permissions(self.scope)
|
permissions = Permission.get_permissions(self.scope)
|
||||||
|
@ -66,7 +66,7 @@ class PreRole:
|
||||||
|
|
||||||
def get_or_create_role(self):
|
def get_or_create_role(self):
|
||||||
from rbac.models import Role
|
from rbac.models import Role
|
||||||
defaults = self.get_defaults()
|
defaults = self._get_defaults()
|
||||||
permissions = defaults.pop('permissions', [])
|
permissions = defaults.pop('permissions', [])
|
||||||
role, created = Role.objects.get_or_create(defaults, id=self.id)
|
role, created = Role.objects.get_or_create(defaults, id=self.id)
|
||||||
role.permissions.set(permissions)
|
role.permissions.set(permissions)
|
||||||
|
@ -74,25 +74,25 @@ class PreRole:
|
||||||
|
|
||||||
|
|
||||||
class BuiltinRole:
|
class BuiltinRole:
|
||||||
system_admin = PreRole(
|
system_admin = PredefineRole(
|
||||||
'1', ugettext_noop('SystemAdmin'), Scope.system, []
|
'1', ugettext_noop('SystemAdmin'), Scope.system, []
|
||||||
)
|
)
|
||||||
system_auditor = PreRole(
|
system_auditor = PredefineRole(
|
||||||
'2', ugettext_noop('SystemAuditor'), Scope.system, auditor_perms
|
'2', ugettext_noop('SystemAuditor'), Scope.system, auditor_perms
|
||||||
)
|
)
|
||||||
system_component = PreRole(
|
system_component = PredefineRole(
|
||||||
'4', ugettext_noop('SystemComponent'), Scope.system, app_exclude_perms, 'exclude'
|
'4', ugettext_noop('SystemComponent'), Scope.system, app_exclude_perms, 'exclude'
|
||||||
)
|
)
|
||||||
system_user = PreRole(
|
system_user = PredefineRole(
|
||||||
'3', ugettext_noop('User'), Scope.system, []
|
'3', ugettext_noop('User'), Scope.system, []
|
||||||
)
|
)
|
||||||
org_admin = PreRole(
|
org_admin = PredefineRole(
|
||||||
'5', ugettext_noop('OrgAdmin'), Scope.org, []
|
'5', ugettext_noop('OrgAdmin'), Scope.org, []
|
||||||
)
|
)
|
||||||
org_auditor = PreRole(
|
org_auditor = PredefineRole(
|
||||||
'6', ugettext_noop('OrgAuditor'), Scope.org, auditor_perms
|
'6', ugettext_noop('OrgAuditor'), Scope.org, auditor_perms
|
||||||
)
|
)
|
||||||
org_user = PreRole(
|
org_user = PredefineRole(
|
||||||
'7', ugettext_noop('OrgUser'), Scope.org, user_perms
|
'7', ugettext_noop('OrgUser'), Scope.org, user_perms
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ class BuiltinRole:
|
||||||
roles = {
|
roles = {
|
||||||
k: v
|
k: v
|
||||||
for k, v in cls.__dict__.items()
|
for k, v in cls.__dict__.items()
|
||||||
if isinstance(v, PreRole)
|
if isinstance(v, PredefineRole)
|
||||||
}
|
}
|
||||||
return roles
|
return roles
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,7 @@ def migrate_system_role_binding(apps, schema_editor):
|
||||||
role_bindings = []
|
role_bindings = []
|
||||||
for user in users:
|
for user in users:
|
||||||
role = BuiltinRole.get_system_role_by_old_name(user.role)
|
role = BuiltinRole.get_system_role_by_old_name(user.role)
|
||||||
role_binding = role_binding_model(
|
role_binding = role_binding_model(scope='system', user_id=user.id, role_id=role.id)
|
||||||
scope='system',
|
|
||||||
user_id=user.id,
|
|
||||||
role_id=role.id,
|
|
||||||
)
|
|
||||||
role_bindings.append(role_binding)
|
role_bindings.append(role_binding)
|
||||||
role_binding_model.objects.bulk_create(role_bindings, ignore_conflicts=True)
|
role_binding_model.objects.bulk_create(role_bindings, ignore_conflicts=True)
|
||||||
|
|
||||||
|
|
|
@ -49,10 +49,10 @@ class Role(JMSModel):
|
||||||
return '%s(%s)' % (self.name, self.get_scope_display())
|
return '%s(%s)' % (self.name, self.get_scope_display())
|
||||||
|
|
||||||
def is_system_admin(self):
|
def is_system_admin(self):
|
||||||
return self.name == self.BuiltinRole.system_admin.name and self.builtin
|
return self.id == self.BuiltinRole.system_admin.id and self.builtin
|
||||||
|
|
||||||
def is_org_admin(self):
|
def is_org_admin(self):
|
||||||
return self.name == self.BuiltinRole.org_admin.name and self.builtin
|
return self.id == self.BuiltinRole.org_admin.id and self.builtin
|
||||||
|
|
||||||
def is_admin(self):
|
def is_admin(self):
|
||||||
yes = self.is_system_admin() or self.is_org_admin()
|
yes = self.is_system_admin() or self.is_org_admin()
|
||||||
|
|
|
@ -6,7 +6,7 @@ from django.db import migrations, models
|
||||||
def migrate_app_users(apps, schema_editor):
|
def migrate_app_users(apps, schema_editor):
|
||||||
user_model = apps.get_model('users', 'User')
|
user_model = apps.get_model('users', 'User')
|
||||||
app_users = user_model.objects.filter(role='App')
|
app_users = user_model.objects.filter(role='App')
|
||||||
app_users.update(is_app=True)
|
app_users.update(is_service_account=True)
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
@ -18,8 +18,8 @@ class Migration(migrations.Migration):
|
||||||
operations = [
|
operations = [
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='user',
|
model_name='user',
|
||||||
name='is_app',
|
name='is_service_account',
|
||||||
field=models.BooleanField(default=False),
|
field=models.BooleanField(default=False, verbose_name='Is service account'),
|
||||||
),
|
),
|
||||||
migrations.RunPython(migrate_app_users),
|
migrations.RunPython(migrate_app_users),
|
||||||
migrations.AlterModelOptions(
|
migrations.AlterModelOptions(
|
||||||
|
|
|
@ -270,9 +270,14 @@ class RoleMixin:
|
||||||
@lazyproperty
|
@lazyproperty
|
||||||
def is_superuser(self):
|
def is_superuser(self):
|
||||||
from rbac.builtin import BuiltinRole
|
from rbac.builtin import BuiltinRole
|
||||||
names = [r.name for r in self.system_roles.all()]
|
return self.system_roles.filter(id=BuiltinRole.system_admin.id).exists()
|
||||||
yes = BuiltinRole.system_admin.name in names
|
|
||||||
return yes
|
@lazyproperty
|
||||||
|
def is_org_admin(self):
|
||||||
|
from rbac.builtin import BuiltinRole
|
||||||
|
if self.is_superuser:
|
||||||
|
return True
|
||||||
|
return self.org_roles.filter(id=BuiltinRole.org_admin.id).exists()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_staff(self):
|
def is_staff(self):
|
||||||
|
@ -286,8 +291,8 @@ class RoleMixin:
|
||||||
def create_service_account(cls, name, comment):
|
def create_service_account(cls, name, comment):
|
||||||
app = cls.objects.create(
|
app = cls.objects.create(
|
||||||
username=name, name=name, email='{}@local.domain'.format(name),
|
username=name, name=name, email='{}@local.domain'.format(name),
|
||||||
is_active=False, comment=comment, is_first_login=False,
|
comment=comment, is_first_login=False,
|
||||||
created_by='System', is_app=True,
|
created_by='System', is_service_account=True,
|
||||||
)
|
)
|
||||||
access_key = app.create_access_key()
|
access_key = app.create_access_key()
|
||||||
return app, access_key
|
return app, access_key
|
||||||
|
@ -319,7 +324,7 @@ class RoleMixin:
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_nature_users(cls):
|
def get_nature_users(cls):
|
||||||
return cls.objects.filter(is_app=False)
|
return cls.objects.filter(is_service_account=False)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_org_users(cls, org=None):
|
def get_org_users(cls, org=None):
|
||||||
|
@ -528,7 +533,7 @@ class User(AuthMixin, TokenMixin, RoleMixin, MFAMixin, AbstractUser):
|
||||||
default='User', max_length=10,
|
default='User', max_length=10,
|
||||||
blank=True, verbose_name=_('Role')
|
blank=True, verbose_name=_('Role')
|
||||||
)
|
)
|
||||||
is_app = models.BooleanField(default=False)
|
is_service_account = models.BooleanField(default=False, verbose_name=_("Is service account"))
|
||||||
avatar = models.ImageField(
|
avatar = models.ImageField(
|
||||||
upload_to="avatar", null=True, verbose_name=_('Avatar')
|
upload_to="avatar", null=True, verbose_name=_('Avatar')
|
||||||
)
|
)
|
||||||
|
|
|
@ -101,7 +101,7 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer
|
||||||
fields_small = fields_mini + fields_write_only + [
|
fields_small = fields_mini + fields_write_only + [
|
||||||
'email', 'wechat', 'phone', 'mfa_level', 'source', 'source_display',
|
'email', 'wechat', 'phone', 'mfa_level', 'source', 'source_display',
|
||||||
'can_public_key_auth', 'need_update_password',
|
'can_public_key_auth', 'need_update_password',
|
||||||
'mfa_enabled', 'is_app', 'is_valid', 'is_expired', 'is_active', # 布尔字段
|
'mfa_enabled', 'is_service_account', 'is_valid', 'is_expired', 'is_active', # 布尔字段
|
||||||
'date_expired', 'date_joined', 'last_login', # 日期字段
|
'date_expired', 'date_joined', 'last_login', # 日期字段
|
||||||
'created_by', 'comment', # 通用字段
|
'created_by', 'comment', # 通用字段
|
||||||
'is_wecom_bound', 'is_dingtalk_bound', 'is_feishu_bound', 'is_otp_secret_key_bound',
|
'is_wecom_bound', 'is_dingtalk_bound', 'is_feishu_bound', 'is_otp_secret_key_bound',
|
||||||
|
@ -132,7 +132,7 @@ class UserSerializer(RolesSerializerMixin, CommonBulkSerializerMixin, serializer
|
||||||
'public_key': {'write_only': True},
|
'public_key': {'write_only': True},
|
||||||
'is_first_login': {'label': _('Is first login'), 'read_only': True},
|
'is_first_login': {'label': _('Is first login'), 'read_only': True},
|
||||||
'is_valid': {'label': _('Is valid')},
|
'is_valid': {'label': _('Is valid')},
|
||||||
'is_app': {'label': _('Is app user')},
|
'is_service_account': {'label': _('Is service account')},
|
||||||
'is_expired': {'label': _('Is expired')},
|
'is_expired': {'label': _('Is expired')},
|
||||||
'avatar_url': {'label': _('Avatar url')},
|
'avatar_url': {'label': _('Avatar url')},
|
||||||
'created_by': {'read_only': True, 'allow_blank': True},
|
'created_by': {'read_only': True, 'allow_blank': True},
|
||||||
|
|
Loading…
Reference in New Issue