mirror of https://github.com/jumpserver/jumpserver
Merge branch 'v3' of github.com:jumpserver/jumpserver into v3
commit
68ed3ac1a8
|
@ -90,7 +90,7 @@ class LoginAssetACL(BaseACL, OrgModelMixin):
|
|||
'applicant': user,
|
||||
'apply_login_user': user,
|
||||
'apply_login_asset': asset,
|
||||
'apply_login_account': account,
|
||||
'apply_login_account': str(account),
|
||||
'org_id': org_id,
|
||||
}
|
||||
ticket = ApplyLoginAssetTicket.objects.create(**data)
|
||||
|
|
|
@ -2,8 +2,7 @@ from rest_framework import serializers
|
|||
from orgs.utils import tmp_to_root_org
|
||||
from common.utils import get_object_or_none, lazyproperty
|
||||
from users.models import User
|
||||
from assets.models import Asset
|
||||
|
||||
from assets.models import Asset, Account
|
||||
|
||||
__all__ = ['LoginAssetCheckSerializer']
|
||||
|
||||
|
@ -18,7 +17,7 @@ class LoginAssetCheckSerializer(serializers.Serializer):
|
|||
super().__init__(*args, **kwargs)
|
||||
self.user = None
|
||||
self.asset = None
|
||||
self._account = None
|
||||
self.account = None
|
||||
self._account_username = None
|
||||
|
||||
def validate_user_id(self, user_id):
|
||||
|
@ -29,6 +28,10 @@ class LoginAssetCheckSerializer(serializers.Serializer):
|
|||
self.asset = self.validate_object_exist(Asset, asset_id)
|
||||
return asset_id
|
||||
|
||||
def validate_account_id(self, account_id):
|
||||
self.account = self.validate_object_exist(Account, account_id)
|
||||
return account_id
|
||||
|
||||
@staticmethod
|
||||
def validate_object_exist(model, field_id):
|
||||
with tmp_to_root_org():
|
||||
|
|
|
@ -16,5 +16,5 @@ class GatheredUserViewSet(OrgModelViewSet):
|
|||
serializer_class = GatheredUserSerializer
|
||||
extra_filter_backends = [AssetRelatedByNodeFilterBackend]
|
||||
|
||||
filterset_fields = ['asset', 'username', 'present', 'asset__ip', 'asset__name', 'asset_id']
|
||||
search_fields = ['username', 'asset__ip', 'asset__name']
|
||||
filterset_fields = ['asset', 'username', 'present', 'asset__address', 'asset__name', 'asset_id']
|
||||
search_fields = ['username', 'asset__address', 'asset__name']
|
||||
|
|
|
@ -98,7 +98,7 @@ class Asset(AbsConnectivity, NodesRelationMixin, JMSOrgBaseModel):
|
|||
objects = AssetManager.from_queryset(AssetQuerySet)()
|
||||
|
||||
def __str__(self):
|
||||
return '{0.name}({0.ip})'.format(self)
|
||||
return '{0.name}({0.address})'.format(self)
|
||||
|
||||
def get_target_ip(self):
|
||||
return self.address
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
import uuid
|
||||
import re
|
||||
import uuid
|
||||
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
|
@ -9,10 +9,9 @@ from django.core.validators import MinValueValidator, MaxValueValidator
|
|||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from users.models import User, UserGroup
|
||||
from ..models import Asset
|
||||
|
||||
from common.utils import lazyproperty, get_logger, get_object_or_none
|
||||
from orgs.mixins.models import OrgModelMixin
|
||||
from common.utils import lazyproperty, get_logger, get_object_or_none
|
||||
from ..models import Asset, Account
|
||||
|
||||
logger = get_logger(__file__)
|
||||
|
||||
|
@ -167,7 +166,7 @@ class CommandFilterRule(OrgModelMixin):
|
|||
'applicant': session.user_obj,
|
||||
'apply_run_user_id': session.user_id,
|
||||
'apply_run_asset': str(session.asset),
|
||||
'apply_run_system_user_id': session.system_user_id,
|
||||
'apply_run_account': str(session.account),
|
||||
'apply_run_command': run_command[:4090],
|
||||
'apply_from_session_id': str(session.id),
|
||||
'apply_from_cmd_filter_rule_id': str(cmd_filter_rule.id),
|
||||
|
@ -180,9 +179,10 @@ class CommandFilterRule(OrgModelMixin):
|
|||
return ticket
|
||||
|
||||
@classmethod
|
||||
def get_queryset(cls, user_id=None, user_group_id=None, system_user_id=None,
|
||||
asset_id=None, application_id=None, org_id=None):
|
||||
from applications.models import Application
|
||||
def get_queryset(
|
||||
cls, user_id=None, user_group_id=None, system_user_id=None,
|
||||
asset_id=None, org_id=None
|
||||
):
|
||||
user_groups = []
|
||||
user = get_object_or_none(User, pk=user_id)
|
||||
if user:
|
||||
|
@ -191,23 +191,19 @@ class CommandFilterRule(OrgModelMixin):
|
|||
if user_group:
|
||||
org_id = user_group.org_id
|
||||
user_groups.append(user_group)
|
||||
system_user = get_object_or_none(SystemUser, pk=system_user_id)
|
||||
account = get_object_or_none(Account, pk=system_user_id)
|
||||
asset = get_object_or_none(Asset, pk=asset_id)
|
||||
application = get_object_or_none(Application, pk=application_id)
|
||||
q = Q()
|
||||
if user:
|
||||
q |= Q(users=user)
|
||||
if user_groups:
|
||||
q |= Q(user_groups__in=set(user_groups))
|
||||
if system_user:
|
||||
org_id = system_user.org_id
|
||||
q |= Q(system_users=system_user)
|
||||
if account:
|
||||
org_id = account.org_id
|
||||
q |= Q(accounts=account)
|
||||
if asset:
|
||||
org_id = asset.org_id
|
||||
q |= Q(assets=asset)
|
||||
if application:
|
||||
org_id = application.org_id
|
||||
q |= Q(applications=application)
|
||||
if q:
|
||||
cmd_filters = CommandFilter.objects.filter(q).filter(is_active=True)
|
||||
if org_id:
|
||||
|
|
|
@ -144,7 +144,7 @@ class CommandExecutionHostRelationViewSet(OrgRelationMixin, OrgBulkModelViewSet)
|
|||
queryset = queryset.annotate(
|
||||
asset_display=Concat(
|
||||
F('asset__name'), Value('('),
|
||||
F('asset__ip'), Value(')')
|
||||
F('asset__address'), Value(')')
|
||||
)
|
||||
)
|
||||
return queryset
|
||||
|
|
|
@ -49,7 +49,7 @@ class CommandExecutionFilter(BaseFilterSet):
|
|||
queryset = queryset.annotate(
|
||||
hostname_ip=Concat(
|
||||
F('asset__hostname'), Value('('),
|
||||
F('asset__ip'), Value(')')
|
||||
F('asset__address'), Value(')')
|
||||
)
|
||||
).filter(hostname_ip__icontains=value)
|
||||
return queryset
|
||||
|
|
|
@ -78,7 +78,7 @@ class AssetPermissionAssetRelationViewSet(RelationMixin):
|
|||
filterset_fields = [
|
||||
'id', 'asset', 'assetpermission',
|
||||
]
|
||||
search_fields = ["id", "asset__name", "asset__ip", "assetpermission__name"]
|
||||
search_fields = ["id", "asset__name", "asset__address", "assetpermission__name"]
|
||||
|
||||
def get_queryset(self):
|
||||
queryset = super().get_queryset()
|
||||
|
|
|
@ -8,7 +8,6 @@ class TicketType(TextChoices):
|
|||
general = 'general', _("General")
|
||||
login_confirm = 'login_confirm', _("Login confirm")
|
||||
apply_asset = 'apply_asset', _('Apply for asset')
|
||||
apply_application = 'apply_application', _('Apply for application')
|
||||
login_asset_confirm = 'login_asset_confirm', _('Login asset confirm')
|
||||
command_confirm = 'command_confirm', _('Command confirm')
|
||||
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
from django.utils.translation import ugettext as _
|
||||
|
||||
from orgs.utils import tmp_to_org
|
||||
from perms.models import ApplicationPermission
|
||||
from tickets.models import ApplyApplicationTicket
|
||||
from .base import BaseHandler
|
||||
|
||||
|
||||
class Handler(BaseHandler):
|
||||
ticket: ApplyApplicationTicket
|
||||
|
||||
def _on_step_approved(self, step):
|
||||
is_finished = super()._on_step_approved(step)
|
||||
if is_finished:
|
||||
self._create_application_permission()
|
||||
|
||||
# permission
|
||||
def _create_application_permission(self):
|
||||
org_id = self.ticket.org_id
|
||||
with tmp_to_org(org_id):
|
||||
application_permission = ApplicationPermission.objects.filter(id=self.ticket.id).first()
|
||||
if application_permission:
|
||||
return application_permission
|
||||
|
||||
apply_applications = self.ticket.apply_applications.all()
|
||||
apply_system_users = self.ticket.apply_system_users.all()
|
||||
|
||||
apply_permission_name = self.ticket.apply_permission_name
|
||||
apply_actions = self.ticket.apply_actions
|
||||
apply_category = self.ticket.apply_category
|
||||
apply_type = self.ticket.apply_type
|
||||
apply_date_start = self.ticket.apply_date_start
|
||||
apply_date_expired = self.ticket.apply_date_expired
|
||||
permission_created_by = '{}:{}'.format(
|
||||
str(self.ticket.__class__.__name__), str(self.ticket.id)
|
||||
)
|
||||
permission_comment = _(
|
||||
'Created by the ticket, '
|
||||
'ticket title: {}, '
|
||||
'ticket applicant: {}, '
|
||||
'ticket processor: {}, '
|
||||
'ticket ID: {}'
|
||||
).format(
|
||||
self.ticket.title,
|
||||
self.ticket.applicant,
|
||||
','.join([i['processor_display'] for i in self.ticket.process_map]),
|
||||
str(self.ticket.id)
|
||||
)
|
||||
permissions_data = {
|
||||
'id': self.ticket.id,
|
||||
'name': apply_permission_name,
|
||||
'from_ticket': True,
|
||||
'category': apply_category,
|
||||
'actions': apply_actions,
|
||||
'type': apply_type,
|
||||
'comment': str(permission_comment),
|
||||
'created_by': permission_created_by,
|
||||
'date_start': apply_date_start,
|
||||
'date_expired': apply_date_expired,
|
||||
}
|
||||
with tmp_to_org(self.ticket.org_id):
|
||||
application_permission = ApplicationPermission.objects.create(**permissions_data)
|
||||
application_permission.users.add(self.ticket.applicant)
|
||||
application_permission.applications.set(apply_applications)
|
||||
application_permission.system_users.set(apply_system_users)
|
||||
|
||||
return application_permission
|
|
@ -1,7 +1,7 @@
|
|||
from django.utils.translation import ugettext as _
|
||||
|
||||
from perms.models import AssetPermission
|
||||
from orgs.utils import tmp_to_org, tmp_to_root_org
|
||||
from orgs.utils import tmp_to_org
|
||||
from tickets.models import ApplyAssetTicket
|
||||
from .base import BaseHandler
|
||||
|
||||
|
@ -24,7 +24,6 @@ class Handler(BaseHandler):
|
|||
|
||||
apply_nodes = self.ticket.apply_nodes.all()
|
||||
apply_assets = self.ticket.apply_assets.all()
|
||||
apply_system_users = self.ticket.apply_system_users.all()
|
||||
|
||||
apply_permission_name = self.ticket.apply_permission_name
|
||||
apply_actions = self.ticket.apply_actions
|
||||
|
@ -61,6 +60,5 @@ class Handler(BaseHandler):
|
|||
asset_permission.users.add(self.ticket.applicant)
|
||||
asset_permission.nodes.set(apply_nodes)
|
||||
asset_permission.assets.set(apply_assets)
|
||||
asset_permission.system_users.set(apply_system_users)
|
||||
|
||||
return asset_permission
|
||||
|
|
|
@ -65,7 +65,7 @@ class BaseHandler:
|
|||
if state != TicketState.approved:
|
||||
return diff_context
|
||||
|
||||
if self.ticket.type not in [TicketType.apply_asset, TicketType.apply_application]:
|
||||
if self.ticket.type == TicketType.apply_asset:
|
||||
return diff_context
|
||||
|
||||
# 企业微信,钉钉审批不做diff
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# Generated by Django 3.2.13 on 2022-09-21 10:14
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
def migrate_remove_application_flow(apps, schema_editor):
|
||||
flow_model = apps.get_model('tickets', 'TicketFlow')
|
||||
flow_model.objects.filter(type='apply_application').delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
('tickets', '0020_auto_20220817_1346'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='ticket',
|
||||
name='type',
|
||||
field=models.CharField(
|
||||
choices=[('general', 'General'), ('login_confirm', 'Login confirm'), ('apply_asset', 'Apply for asset'),
|
||||
('login_asset_confirm', 'Login asset confirm'), ('command_confirm', 'Command confirm')],
|
||||
default='general', max_length=64, verbose_name='Type'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='ticketflow',
|
||||
name='type',
|
||||
field=models.CharField(
|
||||
choices=[('general', 'General'), ('login_confirm', 'Login confirm'), ('apply_asset', 'Apply for asset'),
|
||||
('login_asset_confirm', 'Login asset confirm'), ('command_confirm', 'Command confirm')],
|
||||
default='general', max_length=64, verbose_name='Type'),
|
||||
),
|
||||
migrations.RunPython(migrate_remove_application_flow),
|
||||
]
|
|
@ -1,65 +0,0 @@
|
|||
from django.utils.translation import ugettext as _
|
||||
from rest_framework import serializers
|
||||
|
||||
from perms.models import ApplicationPermission
|
||||
from perms.serializers.permission import ActionsField
|
||||
from orgs.utils import tmp_to_org
|
||||
from applications.models import Application
|
||||
from tickets.models import ApplyApplicationTicket
|
||||
from .ticket import TicketApplySerializer
|
||||
from .common import BaseApplyAssetApplicationSerializer
|
||||
|
||||
__all__ = ['ApplyApplicationSerializer', 'ApplyApplicationDisplaySerializer', 'ApproveApplicationSerializer']
|
||||
|
||||
|
||||
class ApplyApplicationSerializer(BaseApplyAssetApplicationSerializer, TicketApplySerializer):
|
||||
apply_actions = ActionsField(required=True, allow_empty=False)
|
||||
permission_model = ApplicationPermission
|
||||
|
||||
class Meta:
|
||||
model = ApplyApplicationTicket
|
||||
writeable_fields = [
|
||||
'id', 'title', 'type', 'apply_category',
|
||||
'apply_type', 'apply_applications', 'apply_system_users',
|
||||
'apply_actions', 'apply_date_start', 'apply_date_expired', 'org_id'
|
||||
]
|
||||
fields = TicketApplySerializer.Meta.fields + \
|
||||
writeable_fields + ['apply_permission_name', 'apply_actions_display']
|
||||
read_only_fields = list(set(fields) - set(writeable_fields))
|
||||
ticket_extra_kwargs = TicketApplySerializer.Meta.extra_kwargs
|
||||
extra_kwargs = {
|
||||
'apply_applications': {'required': False, 'allow_empty': True},
|
||||
'apply_system_users': {'required': False, 'allow_empty': True},
|
||||
}
|
||||
extra_kwargs.update(ticket_extra_kwargs)
|
||||
|
||||
def validate_apply_applications(self, applications):
|
||||
if self.is_final_approval and not applications:
|
||||
raise serializers.ValidationError(_('This field is required.'))
|
||||
tp = self.initial_data.get('apply_type')
|
||||
return self.filter_many_to_many_field(Application, applications, type=tp)
|
||||
|
||||
|
||||
class ApproveApplicationSerializer(ApplyApplicationSerializer):
|
||||
class Meta(ApplyApplicationSerializer.Meta):
|
||||
read_only_fields = ApplyApplicationSerializer.Meta.read_only_fields + ['title', 'type']
|
||||
|
||||
|
||||
class ApplyApplicationDisplaySerializer(ApplyApplicationSerializer):
|
||||
apply_applications = serializers.SerializerMethodField()
|
||||
apply_system_users = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = ApplyApplicationSerializer.Meta.model
|
||||
fields = ApplyApplicationSerializer.Meta.fields
|
||||
read_only_fields = fields
|
||||
|
||||
@staticmethod
|
||||
def get_apply_applications(instance):
|
||||
with tmp_to_org(instance.org_id):
|
||||
return instance.apply_applications.values_list('id', flat=True)
|
||||
|
||||
@staticmethod
|
||||
def get_apply_system_users(instance):
|
||||
with tmp_to_org(instance.org_id):
|
||||
return instance.apply_system_users.values_list('id', flat=True)
|
|
@ -23,17 +23,18 @@ class ApplyAssetSerializer(BaseApplyAssetApplicationSerializer, TicketApplySeria
|
|||
model = ApplyAssetTicket
|
||||
writeable_fields = [
|
||||
'id', 'title', 'type', 'apply_nodes', 'apply_assets',
|
||||
'apply_system_users', 'apply_actions',
|
||||
'apply_date_start', 'apply_date_expired', 'org_id'
|
||||
'apply_accounts', 'apply_actions', 'org_id',
|
||||
'apply_date_start', 'apply_date_expired'
|
||||
]
|
||||
fields = TicketApplySerializer.Meta.fields + writeable_fields + [
|
||||
'apply_permission_name', 'apply_actions_display'
|
||||
]
|
||||
fields = TicketApplySerializer.Meta.fields + \
|
||||
writeable_fields + ['apply_permission_name', 'apply_actions_display']
|
||||
read_only_fields = list(set(fields) - set(writeable_fields))
|
||||
ticket_extra_kwargs = TicketApplySerializer.Meta.extra_kwargs
|
||||
extra_kwargs = {
|
||||
'apply_nodes': {'required': False, 'allow_empty': True},
|
||||
'apply_assets': {'required': False, 'allow_empty': True},
|
||||
'apply_system_users': {'required': False, 'allow_empty': True},
|
||||
'apply_accounts': {'required': False, 'allow_empty': True},
|
||||
}
|
||||
extra_kwargs.update(ticket_extra_kwargs)
|
||||
|
||||
|
@ -58,13 +59,14 @@ class ApplyAssetSerializer(BaseApplyAssetApplicationSerializer, TicketApplySeria
|
|||
|
||||
class ApproveAssetSerializer(ApplyAssetSerializer):
|
||||
class Meta(ApplyAssetSerializer.Meta):
|
||||
read_only_fields = ApplyAssetSerializer.Meta.read_only_fields + ['title', 'type']
|
||||
read_only_fields = ApplyAssetSerializer.Meta.read_only_fields + [
|
||||
'title', 'type'
|
||||
]
|
||||
|
||||
|
||||
class ApplyAssetDisplaySerializer(ApplyAssetSerializer):
|
||||
apply_nodes = serializers.SerializerMethodField()
|
||||
apply_assets = serializers.SerializerMethodField()
|
||||
apply_system_users = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = ApplyAssetSerializer.Meta.model
|
||||
|
@ -80,8 +82,3 @@ class ApplyAssetDisplaySerializer(ApplyAssetSerializer):
|
|||
def get_apply_assets(instance):
|
||||
with tmp_to_org(instance.org_id):
|
||||
return instance.apply_assets.values_list('id', flat=True)
|
||||
|
||||
@staticmethod
|
||||
def get_apply_system_users(instance):
|
||||
with tmp_to_org(instance.org_id):
|
||||
return instance.apply_system_users.values_list('id', flat=True)
|
||||
|
|
|
@ -10,7 +10,7 @@ class ApplyCommandConfirmSerializer(TicketApplySerializer):
|
|||
class Meta:
|
||||
model = ApplyCommandTicket
|
||||
fields = TicketApplySerializer.Meta.fields + [
|
||||
'apply_run_user', 'apply_run_asset', 'apply_run_system_user',
|
||||
'apply_run_user', 'apply_run_asset', 'apply_run_account',
|
||||
'apply_run_command', 'apply_from_session', 'apply_from_cmd_filter',
|
||||
'apply_from_cmd_filter_rule'
|
||||
]
|
||||
|
|
|
@ -53,17 +53,16 @@ class BaseApplyAssetApplicationSerializer(serializers.Serializer):
|
|||
qs = model.objects.filter(id__in=ids, **kwargs).values_list('id', flat=True)
|
||||
return list(qs)
|
||||
|
||||
def validate_apply_account(self, system_users):
|
||||
if self.is_final_approval and not system_users:
|
||||
def validate_apply_accounts(self, accounts):
|
||||
if self.is_final_approval and not accounts:
|
||||
raise serializers.ValidationError(_('This field is required.'))
|
||||
return self.filter_many_to_many_field(SystemUser, system_users)
|
||||
return accounts
|
||||
|
||||
def validate(self, attrs):
|
||||
attrs = super().validate(attrs)
|
||||
|
||||
apply_date_start = attrs['apply_date_start'].strftime('%Y-%m-%d %H:%M:%S')
|
||||
apply_date_expired = attrs['apply_date_expired'].strftime('%Y-%m-%d %H:%M:%S')
|
||||
|
||||
if apply_date_expired <= apply_date_start:
|
||||
error = _('The expiration date should be greater than the start date')
|
||||
raise serializers.ValidationError({'apply_date_expired': error})
|
||||
|
|
|
@ -10,5 +10,5 @@ class LoginAssetConfirmSerializer(TicketApplySerializer):
|
|||
class Meta:
|
||||
model = ApplyLoginAssetTicket
|
||||
fields = TicketApplySerializer.Meta.fields + [
|
||||
'apply_login_user', 'apply_login_asset', 'apply_login_system_user'
|
||||
'apply_login_user', 'apply_login_asset', 'apply_login_account'
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue