mirror of https://github.com/jumpserver/jumpserver
commit
2752770ce2
|
@ -1,10 +1,12 @@
|
||||||
from django.db.models import F
|
from django.db.models import F, Q
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
from django_filters import rest_framework as filters
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
from orgs.mixins.api import OrgBulkModelViewSet
|
from orgs.mixins.api import OrgBulkModelViewSet
|
||||||
from common.permissions import IsOrgAdmin, IsOrgAdminOrAppUser, NeedMFAVerify
|
from common.permissions import IsOrgAdmin, IsOrgAdminOrAppUser, NeedMFAVerify
|
||||||
|
from common.drf.filters import BaseFilterSet
|
||||||
from ..tasks.account_connectivity import test_accounts_connectivity_manual
|
from ..tasks.account_connectivity import test_accounts_connectivity_manual
|
||||||
from ..models import AuthBook
|
from ..models import AuthBook
|
||||||
from .. import serializers
|
from .. import serializers
|
||||||
|
@ -12,10 +14,38 @@ from .. import serializers
|
||||||
__all__ = ['AccountViewSet', 'AccountSecretsViewSet']
|
__all__ = ['AccountViewSet', 'AccountSecretsViewSet']
|
||||||
|
|
||||||
|
|
||||||
|
class AccountFilterSet(BaseFilterSet):
|
||||||
|
username = filters.CharFilter(method='do_nothing')
|
||||||
|
ip = filters.CharFilter(field_name='ip', lookup_expr='exact')
|
||||||
|
hostname = filters.CharFilter(field_name='hostname', lookup_expr='exact')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def qs(self):
|
||||||
|
qs = super().qs
|
||||||
|
qs = self.filter_username(qs)
|
||||||
|
return qs
|
||||||
|
|
||||||
|
def filter_username(self, qs):
|
||||||
|
username = self.get_query_param('username')
|
||||||
|
if not username:
|
||||||
|
return qs
|
||||||
|
qs = qs.filter(Q(username=username) | Q(systemuser__username=username)).distinct()
|
||||||
|
return qs
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
model = AuthBook
|
||||||
|
fields = [
|
||||||
|
'asset', 'systemuser', 'id',
|
||||||
|
]
|
||||||
|
|
||||||
|
from rest_framework.filters import SearchFilter
|
||||||
|
|
||||||
|
|
||||||
class AccountViewSet(OrgBulkModelViewSet):
|
class AccountViewSet(OrgBulkModelViewSet):
|
||||||
model = AuthBook
|
model = AuthBook
|
||||||
filterset_fields = ("username", "asset", "systemuser")
|
filterset_fields = ("username", "asset", "systemuser", 'ip', 'hostname')
|
||||||
search_fields = filterset_fields
|
search_fields = ('username', 'ip', 'hostname', 'systemuser__username')
|
||||||
|
filterset_class = AccountFilterSet
|
||||||
serializer_classes = {
|
serializer_classes = {
|
||||||
'default': serializers.AccountSerializer,
|
'default': serializers.AccountSerializer,
|
||||||
'verify_account': serializers.AssetTaskSerializer
|
'verify_account': serializers.AssetTaskSerializer
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# Generated by Django 3.1.6 on 2021-07-12 02:25
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('assets', '0075_auto_20210705_1759'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='AssetUser',
|
||||||
|
),
|
||||||
|
]
|
|
@ -237,6 +237,12 @@ class Asset(AbsConnectivity, ProtocolsMixin, NodesRelationMixin, OrgModelMixin):
|
||||||
raise ValidationError('System user should be type admin')
|
raise ValidationError('System user should be type admin')
|
||||||
system_user.assets.add(self)
|
system_user.assets.add(self)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def admin_user_display(self):
|
||||||
|
if not self.admin_user:
|
||||||
|
return ''
|
||||||
|
return str(self.admin_user)
|
||||||
|
|
||||||
def remove_admin_user(self):
|
def remove_admin_user(self):
|
||||||
from ..models import AuthBook
|
from ..models import AuthBook
|
||||||
AuthBook.objects.filter(asset=self, systemuser__type='admin').delete()
|
AuthBook.objects.filter(asset=self, systemuser__type='admin').delete()
|
||||||
|
|
|
@ -63,6 +63,12 @@ class AuthBook(BaseUser, AbsConnectivity):
|
||||||
def username_display(self):
|
def username_display(self):
|
||||||
return self.get_or_systemuser_attr('username') or '*'
|
return self.get_or_systemuser_attr('username') or '*'
|
||||||
|
|
||||||
|
@property
|
||||||
|
def systemuser_display(self):
|
||||||
|
if not self.systemuser:
|
||||||
|
return ''
|
||||||
|
return str(self.systemuser)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def smart_name(self):
|
def smart_name(self):
|
||||||
username = self.username_display
|
username = self.username_display
|
||||||
|
|
|
@ -215,7 +215,7 @@ class SystemUser(ProtocolMixin, AuthMixin, BaseUser):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
username = self.username
|
username = self.username
|
||||||
if self.username_same_with_user:
|
if self.username_same_with_user:
|
||||||
username = 'dynamic'
|
username = '*'
|
||||||
return '{0.name}({1})'.format(self, username)
|
return '{0.name}({1})'.format(self, username)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -270,11 +270,6 @@ class SystemUser(ProtocolMixin, AuthMixin, BaseUser):
|
||||||
assets = Asset.objects.filter(id__in=asset_ids)
|
assets = Asset.objects.filter(id__in=asset_ids)
|
||||||
return assets
|
return assets
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
if self.username_same_with_user:
|
|
||||||
self.username = '*'
|
|
||||||
return super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['name']
|
ordering = ['name']
|
||||||
unique_together = [('name', 'org_id')]
|
unique_together = [('name', 'org_id')]
|
||||||
|
|
|
@ -17,7 +17,7 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
fields_write_only = ['password', 'private_key', "public_key"]
|
fields_write_only = ['password', 'private_key', "public_key"]
|
||||||
fields_other = ['date_created', 'date_updated', 'connectivity', 'date_verified', 'comment']
|
fields_other = ['date_created', 'date_updated', 'connectivity', 'date_verified', 'comment']
|
||||||
fields_small = fields_mini + fields_write_only + fields_other
|
fields_small = fields_mini + fields_write_only + fields_other
|
||||||
fields_fk = ['asset', 'systemuser']
|
fields_fk = ['asset', 'systemuser', 'systemuser_display']
|
||||||
fields = fields_small + fields_fk
|
fields = fields_small + fields_fk
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
'username': {'required': True},
|
'username': {'required': True},
|
||||||
|
|
|
@ -83,7 +83,7 @@ class AssetSerializer(BulkOrgResourceModelSerializer):
|
||||||
'hardware_info', 'connectivity', 'date_verified'
|
'hardware_info', 'connectivity', 'date_verified'
|
||||||
]
|
]
|
||||||
fields_fk = [
|
fields_fk = [
|
||||||
'domain', 'domain_display', 'platform', 'admin_user'
|
'domain', 'domain_display', 'platform', 'admin_user', 'admin_user_display'
|
||||||
]
|
]
|
||||||
fields_m2m = [
|
fields_m2m = [
|
||||||
'nodes', 'nodes_display', 'labels',
|
'nodes', 'nodes_display', 'labels',
|
||||||
|
|
|
@ -97,13 +97,12 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
|
||||||
protocol = self.initial_data.get("protocol")
|
protocol = self.initial_data.get("protocol")
|
||||||
username_same_with_user = self.initial_data.get("username_same_with_user")
|
username_same_with_user = self.initial_data.get("username_same_with_user")
|
||||||
|
|
||||||
if login_mode == SystemUser.LOGIN_AUTO and \
|
if username_same_with_user:
|
||||||
protocol != SystemUser.Protocol.vnc:
|
return ''
|
||||||
|
|
||||||
|
if login_mode == SystemUser.LOGIN_AUTO and protocol != SystemUser.Protocol.vnc:
|
||||||
msg = _('* Automatic login mode must fill in the username.')
|
msg = _('* Automatic login mode must fill in the username.')
|
||||||
raise serializers.ValidationError(msg)
|
raise serializers.ValidationError(msg)
|
||||||
|
|
||||||
if username_same_with_user:
|
|
||||||
username = '*'
|
|
||||||
return username
|
return username
|
||||||
|
|
||||||
def validate_home(self, home):
|
def validate_home(self, home):
|
||||||
|
@ -234,7 +233,7 @@ class SystemUserSimpleSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
|
|
||||||
class RelationMixin(BulkSerializerMixin, serializers.Serializer):
|
class RelationMixin(BulkSerializerMixin, serializers.Serializer):
|
||||||
systemuser_display = serializers.ReadOnlyField()
|
systemuser_display = serializers.ReadOnlyField(label=_("System user"))
|
||||||
|
|
||||||
def get_field_names(self, declared_fields, info):
|
def get_field_names(self, declared_fields, info):
|
||||||
fields = super().get_field_names(declared_fields, info)
|
fields = super().get_field_names(declared_fields, info)
|
||||||
|
@ -243,7 +242,7 @@ class RelationMixin(BulkSerializerMixin, serializers.Serializer):
|
||||||
|
|
||||||
|
|
||||||
class SystemUserAssetRelationSerializer(RelationMixin, serializers.ModelSerializer):
|
class SystemUserAssetRelationSerializer(RelationMixin, serializers.ModelSerializer):
|
||||||
asset_display = serializers.ReadOnlyField()
|
asset_display = serializers.ReadOnlyField(label=_('Asset'))
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = SystemUser.assets.through
|
model = SystemUser.assets.through
|
||||||
|
|
|
@ -16,6 +16,17 @@ from perms.utils.asset.user_permission import UserGrantedTreeRefreshController
|
||||||
logger = get_logger(__file__)
|
logger = get_logger(__file__)
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(pre_delete, sender=UserGroup)
|
||||||
|
def on_user_group_delete(sender, instance: UserGroup, using, **kwargs):
|
||||||
|
exists = AssetPermission.user_groups.through.objects.filter(usergroup_id=instance.id).exists()
|
||||||
|
if not exists:
|
||||||
|
return
|
||||||
|
|
||||||
|
org_id = instance.org_id
|
||||||
|
user_ids = UserGroup.users.through.objects.filter(usergroup_id=instance.id).values_list('user_id', flat=True)
|
||||||
|
UserGrantedTreeRefreshController.add_need_refresh_orgs_for_users([org_id], list(user_ids))
|
||||||
|
|
||||||
|
|
||||||
@receiver(m2m_changed, sender=User.groups.through)
|
@receiver(m2m_changed, sender=User.groups.through)
|
||||||
def on_user_groups_change(sender, instance, action, reverse, pk_set, **kwargs):
|
def on_user_groups_change(sender, instance, action, reverse, pk_set, **kwargs):
|
||||||
if not action.startswith('post'):
|
if not action.startswith('post'):
|
||||||
|
|
Loading…
Reference in New Issue