mirror of https://github.com/jumpserver/jumpserver
parent
f430c9e435
commit
8eb6cfa9c9
Binary file not shown.
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: JumpServer 0.3.3\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-07-08 15:05+0800\n"
|
||||
"POT-Creation-Date: 2020-07-09 10:05+0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: ibuler <ibuler@qq.com>\n"
|
||||
"Language-Team: JumpServer team<ibuler@qq.com>\n"
|
||||
|
@ -211,7 +211,7 @@ msgstr "IP"
|
|||
|
||||
#: assets/models/asset.py:187 assets/serializers/asset_user.py:45
|
||||
#: assets/serializers/gathered_user.py:20 settings/serializers/settings.py:51
|
||||
#: tickets/serializers/request_asset_perm.py:13
|
||||
#: tickets/serializers/request_asset_perm.py:14
|
||||
#: users/templates/users/_granted_assets.html:25
|
||||
#: users/templates/users/user_asset_permission.html:157
|
||||
msgid "Hostname"
|
||||
|
@ -485,7 +485,7 @@ msgstr "每行一个命令"
|
|||
#: assets/models/cmd_filter.py:55 audits/models.py:57
|
||||
#: authentication/templates/authentication/_access_key_modal.html:34
|
||||
#: perms/forms/asset_permission.py:20
|
||||
#: tickets/serializers/request_asset_perm.py:51
|
||||
#: tickets/serializers/request_asset_perm.py:54
|
||||
#: tickets/serializers/ticket.py:26
|
||||
#: users/templates/users/_granted_assets.html:29
|
||||
#: users/templates/users/user_asset_permission.html:44
|
||||
|
@ -540,7 +540,7 @@ msgstr "默认资产组"
|
|||
#: templates/index.html:78 terminal/backends/command/models.py:18
|
||||
#: terminal/backends/command/serializers.py:12 terminal/models.py:185
|
||||
#: tickets/models/ticket.py:35 tickets/models/ticket.py:130
|
||||
#: tickets/serializers/request_asset_perm.py:52
|
||||
#: tickets/serializers/request_asset_perm.py:55
|
||||
#: tickets/serializers/ticket.py:27 users/forms/group.py:15
|
||||
#: users/models/user.py:160 users/models/user.py:176 users/models/user.py:615
|
||||
#: users/serializers/group.py:20
|
||||
|
@ -648,6 +648,7 @@ msgstr "SFTP根路径"
|
|||
#: perms/models/remote_app_permission.py:16 templates/_nav.html:45
|
||||
#: terminal/backends/command/models.py:20
|
||||
#: terminal/backends/command/serializers.py:14 terminal/models.py:189
|
||||
#: tickets/serializers/request_asset_perm.py:16
|
||||
#: users/templates/users/_granted_assets.html:27
|
||||
#: users/templates/users/user_asset_permission.html:42
|
||||
#: users/templates/users/user_asset_permission.html:76
|
||||
|
@ -918,7 +919,7 @@ msgid "Success"
|
|||
msgstr "成功"
|
||||
|
||||
#: audits/models.py:43 ops/models/command.py:28 perms/models/base.py:52
|
||||
#: terminal/models.py:199 tickets/serializers/request_asset_perm.py:15
|
||||
#: terminal/models.py:199 tickets/serializers/request_asset_perm.py:18
|
||||
#: xpack/plugins/change_auth_plan/models.py:177
|
||||
#: xpack/plugins/change_auth_plan/models.py:308
|
||||
#: xpack/plugins/gathered_user/models.py:76
|
||||
|
@ -1009,7 +1010,7 @@ msgstr "多因子认证"
|
|||
msgid "Reason"
|
||||
msgstr "原因"
|
||||
|
||||
#: audits/models.py:106 tickets/serializers/request_asset_perm.py:50
|
||||
#: audits/models.py:106 tickets/serializers/request_asset_perm.py:53
|
||||
#: tickets/serializers/ticket.py:25 xpack/plugins/cloud/models.py:214
|
||||
#: xpack/plugins/cloud/models.py:272
|
||||
msgid "Status"
|
||||
|
@ -1699,7 +1700,7 @@ msgstr "动作"
|
|||
msgid "Asset permission"
|
||||
msgstr "资产授权"
|
||||
|
||||
#: perms/models/base.py:53 tickets/serializers/request_asset_perm.py:17
|
||||
#: perms/models/base.py:53 tickets/serializers/request_asset_perm.py:20
|
||||
#: users/models/user.py:505 users/templates/users/user_detail.html:93
|
||||
#: users/templates/users/user_profile.html:120
|
||||
msgid "Date expired"
|
||||
|
@ -2432,36 +2433,40 @@ msgstr "结束日期"
|
|||
msgid "Args"
|
||||
msgstr "参数"
|
||||
|
||||
#: tickets/api/request_asset_perm.py:36
|
||||
#: tickets/api/request_asset_perm.py:40
|
||||
msgid "Ticket closed"
|
||||
msgstr "工单已关闭"
|
||||
|
||||
#: tickets/api/request_asset_perm.py:39
|
||||
#: tickets/api/request_asset_perm.py:43
|
||||
#, python-format
|
||||
msgid "Ticket has %s"
|
||||
msgstr "工单已%s"
|
||||
|
||||
#: tickets/api/request_asset_perm.py:59
|
||||
#: tickets/api/request_asset_perm.py:69
|
||||
msgid "Superuser"
|
||||
msgstr "超级管理员"
|
||||
|
||||
#: tickets/api/request_asset_perm.py:102
|
||||
msgid "Confirm assets first"
|
||||
msgstr "请先确认资产"
|
||||
|
||||
#: tickets/api/request_asset_perm.py:62
|
||||
#: tickets/api/request_asset_perm.py:105
|
||||
msgid "Confirmed assets changed"
|
||||
msgstr "确认的资产变更了"
|
||||
|
||||
#: tickets/api/request_asset_perm.py:66
|
||||
#: tickets/api/request_asset_perm.py:109
|
||||
msgid "Confirm system-user first"
|
||||
msgstr "请先确认系统用户"
|
||||
|
||||
#: tickets/api/request_asset_perm.py:70
|
||||
#: tickets/api/request_asset_perm.py:113
|
||||
msgid "Confirmed system-user changed"
|
||||
msgstr "确认的系统用户变更了"
|
||||
|
||||
#: tickets/api/request_asset_perm.py:73 xpack/plugins/cloud/models.py:205
|
||||
#: tickets/api/request_asset_perm.py:116 xpack/plugins/cloud/models.py:205
|
||||
msgid "Succeed"
|
||||
msgstr "成功"
|
||||
|
||||
#: tickets/api/request_asset_perm.py:81
|
||||
#: tickets/api/request_asset_perm.py:124
|
||||
msgid "{} request assets, approved by {}"
|
||||
msgstr "{} 申请资产,通过人 {}"
|
||||
|
||||
|
@ -2525,19 +2530,19 @@ msgstr "{} {} 这个工单"
|
|||
msgid "this ticket"
|
||||
msgstr "这个工单"
|
||||
|
||||
#: tickets/serializers/request_asset_perm.py:11
|
||||
#: tickets/serializers/request_asset_perm.py:12
|
||||
msgid "IP group"
|
||||
msgstr "IP组"
|
||||
|
||||
#: tickets/serializers/request_asset_perm.py:21
|
||||
#: tickets/serializers/request_asset_perm.py:24
|
||||
msgid "Confirmed assets"
|
||||
msgstr "确认的资产"
|
||||
|
||||
#: tickets/serializers/request_asset_perm.py:25
|
||||
#: tickets/serializers/request_asset_perm.py:28
|
||||
msgid "Confirmed system user"
|
||||
msgstr "确认的系统用户"
|
||||
|
||||
#: tickets/serializers/request_asset_perm.py:58
|
||||
#: tickets/serializers/request_asset_perm.py:65
|
||||
msgid "Must be organization admin or superuser"
|
||||
msgstr "必须是组织管理员或者超级管理员"
|
||||
|
||||
|
@ -2778,10 +2783,6 @@ msgstr "最后更新密码日期"
|
|||
msgid "Administrator is the super user of system"
|
||||
msgstr "Administrator是初始的超级管理员"
|
||||
|
||||
#: users/serializers/group.py:50
|
||||
msgid "Auditors cannot be join in the user group"
|
||||
msgstr "审计员不能被加入到用户组"
|
||||
|
||||
#: users/serializers/user.py:69 users/serializers/user.py:229
|
||||
msgid "Is first login"
|
||||
msgstr "首次登录"
|
||||
|
@ -3948,6 +3949,9 @@ msgstr "企业版"
|
|||
msgid "Ultimate edition"
|
||||
msgstr "旗舰版"
|
||||
|
||||
#~ msgid "Auditors cannot be join in the user group"
|
||||
#~ msgstr "审计员不能被加入到用户组"
|
||||
|
||||
#~ msgid "Always update"
|
||||
#~ msgstr "总是更新"
|
||||
|
||||
|
@ -4758,9 +4762,6 @@ msgstr "旗舰版"
|
|||
#~ msgid "Tips: Some provider use token except password"
|
||||
#~ msgstr "提示:一些邮件提供商需要输入的是Token"
|
||||
|
||||
#~ msgid "Send user"
|
||||
#~ msgstr "发送账号"
|
||||
|
||||
#~ msgid "Tips: Send mail account, default SMTP account as the send account"
|
||||
#~ msgstr "提示:发送邮件账号,默认使用SMTP账号作为发送账号"
|
||||
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
from collections import namedtuple
|
||||
|
||||
from django.db.transaction import atomic
|
||||
from django.db.models import F
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.response import Response
|
||||
|
||||
from common.const.http import POST
|
||||
from users.models.user import User
|
||||
from common.const.http import POST, GET
|
||||
from common.drf.api import JMSModelViewSet
|
||||
from common.permissions import IsValidUser
|
||||
from common.utils.django import get_object_or_none
|
||||
|
@ -26,6 +30,7 @@ class RequestAssetPermTicketViewSet(JMSModelViewSet):
|
|||
'default': serializers.RequestAssetPermTicketSerializer,
|
||||
'approve': EmptySerializer,
|
||||
'reject': EmptySerializer,
|
||||
'assignees': serializers.OrgAssigneeSerializer,
|
||||
}
|
||||
permission_classes = (IsValidUser,)
|
||||
filter_fields = ['status', 'title', 'action', 'user_display']
|
||||
|
@ -38,6 +43,41 @@ class RequestAssetPermTicketViewSet(JMSModelViewSet):
|
|||
action_display = dict(instance.ACTION_CHOICES).get(action)
|
||||
raise TicketActionYet(detail=_('Ticket has %s') % action_display)
|
||||
|
||||
@action(detail=False, methods=[GET], permission_classes=[IsValidUser])
|
||||
def assignees(self, request, *args, **kwargs):
|
||||
org_mapper = {}
|
||||
UserTuple = namedtuple('UserTuple', ('id', 'name', 'username'))
|
||||
user = request.user
|
||||
superusers = User.objects.filter(role=User.ROLE_ADMIN)
|
||||
|
||||
admins_with_org = User.objects.filter(related_admin_orgs__users=user).annotate(
|
||||
org_id=F('related_admin_orgs__id'), org_name=F('related_admin_orgs__name')
|
||||
)
|
||||
|
||||
for user in admins_with_org:
|
||||
org_id = user.org_id
|
||||
|
||||
if org_id not in org_mapper:
|
||||
org_mapper[org_id] = {
|
||||
'org_name': user.org_name,
|
||||
'org_admins': set() # 去重
|
||||
}
|
||||
org_mapper[org_id]['org_admins'].add(UserTuple(user.id, user.name, user.username))
|
||||
|
||||
result = [
|
||||
{
|
||||
'org_name': _('Superuser'),
|
||||
'org_admins': set(UserTuple(user.id, user.name, user.username)
|
||||
for user in superusers)
|
||||
}
|
||||
]
|
||||
|
||||
for org in org_mapper.values():
|
||||
result.append(org)
|
||||
serializer_class = self.get_serializer_class()
|
||||
serilizer = serializer_class(instance=result, many=True)
|
||||
return Response(data=serilizer.data)
|
||||
|
||||
@action(detail=True, methods=[POST], permission_classes=[IsAssignee, IsValidUser])
|
||||
def reject(self, request, *args, **kwargs):
|
||||
instance = self.get_object()
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
from rest_framework import serializers
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.urls import reverse
|
||||
from django.db.models import Q
|
||||
|
||||
from orgs.utils import current_org
|
||||
from users.models.user import User
|
||||
from ..models import Ticket
|
||||
|
||||
|
||||
|
@ -10,7 +11,9 @@ class RequestAssetPermTicketSerializer(serializers.ModelSerializer):
|
|||
ips = serializers.ListField(child=serializers.IPAddressField(), source='meta.ips',
|
||||
default=list, label=_('IP group'))
|
||||
hostname = serializers.CharField(max_length=256, source='meta.hostname', default=None,
|
||||
allow_blank=True, label=_('Hostname'))
|
||||
allow_blank=True, label=_('Hostname'))
|
||||
system_user = serializers.CharField(max_length=256, source='meta.system_user', default='',
|
||||
allow_blank=True, label=_('System user'))
|
||||
date_start = serializers.DateTimeField(source='meta.date_start', allow_null=True,
|
||||
required=False, label=_('Date start'))
|
||||
date_expired = serializers.DateTimeField(source='meta.date_expired', allow_null=True,
|
||||
|
@ -33,7 +36,7 @@ class RequestAssetPermTicketSerializer(serializers.ModelSerializer):
|
|||
'status', 'action', 'date_created', 'date_updated', 'system_user_waitlist_url',
|
||||
'type', 'type_display', 'action_display', 'ips', 'confirmed_assets',
|
||||
'date_start', 'date_expired', 'confirmed_system_user', 'hostname',
|
||||
'assets_waitlist_url'
|
||||
'assets_waitlist_url', 'system_user'
|
||||
]
|
||||
m2m_fields = [
|
||||
'user', 'user_display', 'assignees', 'assignees_display',
|
||||
|
@ -53,7 +56,11 @@ class RequestAssetPermTicketSerializer(serializers.ModelSerializer):
|
|||
}
|
||||
|
||||
def validate_assignees(self, assignees):
|
||||
count = current_org.org_admins().filter(id__in=[assignee.id for assignee in assignees]).count()
|
||||
user = self.context['request'].user
|
||||
|
||||
count = User.objects.filter(Q(related_admin_orgs__users=user) | Q(role=User.ROLE_ADMIN)).filter(
|
||||
id__in=[assignee.id for assignee in assignees]).distinct().count()
|
||||
|
||||
if count != len(assignees):
|
||||
raise serializers.ValidationError(_('Must be organization admin or superuser'))
|
||||
return assignees
|
||||
|
@ -61,7 +68,10 @@ class RequestAssetPermTicketSerializer(serializers.ModelSerializer):
|
|||
def get_system_user_waitlist_url(self, instance: Ticket):
|
||||
if not self._is_assignee(instance):
|
||||
return None
|
||||
return {'url': reverse('api-assets:system-user-list')}
|
||||
meta = instance.meta
|
||||
url = reverse('api-assets:system-user-list')
|
||||
query = meta.get('system_user', '')
|
||||
return '{}?search={}'.format(url, query)
|
||||
|
||||
def get_assets_waitlist_url(self, instance: Ticket):
|
||||
if not self._is_assignee(instance):
|
||||
|
@ -118,3 +128,14 @@ class RequestAssetPermTicketSerializer(serializers.ModelSerializer):
|
|||
def _is_assignee(self, obj: Ticket):
|
||||
user = self.context['request'].user
|
||||
return obj.is_assignee(user)
|
||||
|
||||
|
||||
class AssigneeSerializer(serializers.Serializer):
|
||||
id = serializers.UUIDField()
|
||||
name = serializers.CharField()
|
||||
username = serializers.CharField()
|
||||
|
||||
|
||||
class OrgAssigneeSerializer(serializers.Serializer):
|
||||
org_name = serializers.CharField()
|
||||
org_admins = AssigneeSerializer(many=True)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from rest_framework.compat import coreapi, coreschema
|
||||
from rest_framework import filters
|
||||
|
||||
from users.models.user import User
|
||||
from orgs.utils import current_org
|
||||
|
||||
|
||||
|
@ -11,7 +12,7 @@ class OrgRoleUserFilterBackend(filters.BaseFilterBackend):
|
|||
return queryset
|
||||
|
||||
if org_role == 'admins':
|
||||
return queryset & current_org.get_org_admins()
|
||||
return queryset & (current_org.get_org_admins() | User.objects.filter(role=User.ROLE_ADMIN))
|
||||
elif org_role == 'auditors':
|
||||
return queryset & current_org.get_org_auditors()
|
||||
elif org_role == 'users':
|
||||
|
|
|
@ -320,3 +320,9 @@ class UserUpdatePublicKeySerializer(serializers.ModelSerializer):
|
|||
new_public_key = self.validated_data.get('public_key')
|
||||
instance.set_public_key(new_public_key)
|
||||
return instance
|
||||
|
||||
|
||||
class MiniUserSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = ['id', 'name', 'username']
|
||||
|
|
Loading…
Reference in New Issue