Merge pull request #7622 from jumpserver/dev

v2.19.0-rc3
pull/7642/head
Jiangjie.Bai 2022-02-16 16:42:19 +08:00 committed by GitHub
commit 7be76feeb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 194 additions and 141 deletions

View File

@ -26,6 +26,7 @@ class AccountFilterSet(BaseFilterSet):
qs = super().qs
qs = self.filter_username(qs)
qs = self.filter_node(qs)
qs = qs.distinct()
return qs
def filter_username(self, qs):

View File

@ -1,18 +1,17 @@
# ~*~ coding: utf-8 ~*~
from django.shortcuts import get_object_or_404
from django.middleware import csrf
from rest_framework.response import Response
from django.db.models import Q
from common.utils import get_logger, get_object_or_none
from common.utils.crypto import get_aes_crypto
from common.permissions import IsOrgAdmin, IsOrgAdminOrAppUser, IsValidUser
from orgs.mixins.api import OrgBulkModelViewSet
from orgs.mixins import generics
from common.mixins.api import SuggestionMixin
from orgs.utils import tmp_to_root_org
from rest_framework.decorators import action
from users.models import User, UserGroup
from applications.models import Application
from ..models import SystemUser, Asset, CommandFilter, CommandFilterRule
from ..models import SystemUser, CommandFilterRule
from .. import serializers
from ..serializers import SystemUserWithAuthInfoSerializer, SystemUserTempAuthSerializer
from ..tasks import (
@ -95,17 +94,27 @@ class SystemUserTempAuthInfoApi(generics.CreateAPIView):
permission_classes = (IsValidUser,)
serializer_class = SystemUserTempAuthSerializer
def decrypt_data_if_need(self, data):
csrf_token = self.request.META.get('CSRF_COOKIE')
aes = get_aes_crypto(csrf_token, 'ECB')
password = data.get('password', '')
try:
data['password'] = aes.decrypt(password)
except:
pass
return data
def create(self, request, *args, **kwargs):
serializer = super().get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
pk = kwargs.get('pk')
user = self.request.user
data = serializer.validated_data
data = self.decrypt_data_if_need(serializer.validated_data)
instance_id = data.get('instance_id')
with tmp_to_root_org():
instance = get_object_or_404(SystemUser, pk=pk)
instance.set_temp_auth(instance_id, user.id, data)
instance.set_temp_auth(instance_id, self.request.user, data)
return Response(serializer.data, status=201)

View File

@ -6,6 +6,7 @@ from orgs.mixins.serializers import BulkOrgResourceModelSerializer
from .base import AuthSerializerMixin
from .utils import validate_password_contains_left_double_curly_bracket
from common.utils.encode import ssh_pubkey_gen
class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
@ -40,6 +41,21 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer):
}
ref_name = 'AssetAccountSerializer'
def _validate_gen_key(self, attrs):
private_key = attrs.get('private_key')
if not private_key:
return attrs
password = attrs.get('passphrase')
username = attrs.get('username')
public_key = ssh_pubkey_gen(private_key, password=password, username=username)
attrs['public_key'] = public_key
return attrs
def validate(self, attrs):
attrs = self._validate_gen_key(attrs)
return attrs
def get_protocols(self, v):
return v.protocols.replace(' ', ', ')

View File

@ -11,6 +11,7 @@ from django.conf import settings
from django.core.cache import cache
from django.shortcuts import get_object_or_404
from django.http import HttpResponse
from django.utils import timezone
from django.utils.translation import ugettext as _
from rest_framework.response import Response
from rest_framework.request import Request
@ -20,15 +21,17 @@ from rest_framework.exceptions import PermissionDenied
from rest_framework import serializers
from applications.models import Application
from authentication.signals import post_auth_failed, post_auth_success
from authentication.signals import post_auth_failed
from common.utils import get_logger, random_string
from common.mixins.api import SerializerMixin
from common.permissions import IsSuperUserOrAppUser, IsValidUser, IsSuperUser
from common.utils.common import get_file_by_arch
from orgs.mixins.api import RootOrgViewMixin
from common.http import is_true
from perms.utils.asset.permission import get_asset_system_user_ids_with_actions_by_user
from perms.models.base import Action
from perms.utils.application.permission import validate_permission as app_validate_permission
from perms.utils.application.permission import get_application_actions
from perms.utils.asset.permission import get_asset_actions
from ..serializers import (
ConnectionTokenSerializer, ConnectionTokenSecretSerializer,
@ -99,10 +102,14 @@ class ClientProtocolMixin:
token = self.create_token(user, asset, application, system_user)
# 设置磁盘挂载
if drives_redirect and asset:
systemuser_actions_mapper = get_asset_system_user_ids_with_actions_by_user(user, asset)
actions = systemuser_actions_mapper.get(system_user.id, 0)
if actions & Action.UPDOWNLOAD:
if drives_redirect:
actions = 0
if asset:
actions = get_asset_actions(user, asset, system_user)
elif application:
actions = get_application_actions(user, application, system_user)
if actions & Action.UPDOWNLOAD == Action.UPDOWNLOAD:
options['drivestoredirect:s'] = '*'
# 全屏
@ -148,7 +155,6 @@ class ClientProtocolMixin:
return name, content
def get_encrypt_cmdline(self, app: Application):
parameters = app.get_rdp_remote_app_setting()['parameters']
parameters = parameters.encode('ascii')
@ -231,19 +237,16 @@ class SecretDetailMixin:
@staticmethod
def _get_application_secret_detail(application):
from perms.models.base import Action
gateway = None
remote_app = None
asset = None
if not application.category_remote_app:
actions = Action.NONE
remote_app = {}
asset = None
domain = application.domain
else:
if application.category_remote_app:
remote_app = application.get_rdp_remote_app_setting()
actions = Action.CONNECT
asset = application.get_remote_app_asset()
domain = asset.domain
else:
domain = application.domain
if domain and domain.has_gateway():
gateway = domain.random_gateway()
@ -253,15 +256,10 @@ class SecretDetailMixin:
'application': application,
'gateway': gateway,
'remote_app': remote_app,
'actions': actions
}
@staticmethod
def _get_asset_secret_detail(asset, user, system_user):
from perms.utils.asset import get_asset_system_user_ids_with_actions_by_user
systemuserid_actions_mapper = get_asset_system_user_ids_with_actions_by_user(user, asset)
actions = systemuserid_actions_mapper.get(system_user.id, [])
def _get_asset_secret_detail(asset):
gateway = None
if asset and asset.domain and asset.domain.has_gateway():
gateway = asset.domain.random_gateway()
@ -271,14 +269,13 @@ class SecretDetailMixin:
'application': None,
'gateway': gateway,
'remote_app': None,
'actions': actions,
}
@action(methods=['POST'], detail=False, permission_classes=[IsSuperUserOrAppUser], url_path='secret-info/detail')
def get_secret_detail(self, request, *args, **kwargs):
token = request.data.get('token', '')
try:
value, user, system_user, asset, app, expired_at = self.valid_token(token)
value, user, system_user, asset, app, expired_at, actions = self.valid_token(token)
except serializers.ValidationError as e:
post_auth_failed.send(
sender=self.__class__, username='', request=self.request,
@ -286,9 +283,13 @@ class SecretDetailMixin:
)
raise e
data = dict(user=user, system_user=system_user, expired_at=expired_at)
data = dict(
id=token, secret=value.get('secret', ''),
user=user, system_user=system_user,
expired_at=expired_at, actions=actions
)
if asset:
asset_detail = self._get_asset_secret_detail(asset, user=user, system_user=system_user)
asset_detail = self._get_asset_secret_detail(asset)
system_user.load_asset_more_auth(asset.id, user.username, user.id)
data['type'] = 'asset'
data.update(asset_detail)
@ -333,11 +334,16 @@ class UserConnectionTokenViewSet(
raise PermissionDenied('Only super user can create user token')
self.check_resource_permission(user, asset, application, system_user)
token = random_string(36)
secret = random_string(16)
value = {
'id': token,
'secret': secret,
'user': str(user.id),
'username': user.username,
'system_user': str(system_user.id),
'system_user_name': system_user.name
'system_user_name': system_user.name,
'created_by': str(self.request.user),
'date_created': str(timezone.now())
}
if asset:
@ -395,7 +401,7 @@ class UserConnectionTokenViewSet(
if not has_perm:
raise serializers.ValidationError('Permission expired or invalid')
return value, user, system_user, asset, app, expired_at
return value, user, system_user, asset, app, expired_at, actions
def get_permissions(self):
if self.action in ["create", "get_rdp_file"]:

View File

@ -191,6 +191,8 @@ class ConnectionTokenApplicationSerializer(serializers.ModelSerializer):
class ConnectionTokenSecretSerializer(serializers.Serializer):
id = serializers.CharField(read_only=True)
secret = serializers.CharField(read_only=True)
type = serializers.ChoiceField(choices=[('application', 'Application'), ('asset', 'Asset')])
user = ConnectionTokenUserSerializer(read_only=True)
asset = ConnectionTokenAssetSerializer(read_only=True)

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-02-08 17:40+0800\n"
"POT-Creation-Date: 2022-02-15 17:52+0800\n"
"PO-Revision-Date: 2021-05-20 10:54+0800\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: JumpServer team<ibuler@qq.com>\n"
@ -35,12 +35,12 @@ msgid "Name"
msgstr "名称"
#: acls/models/base.py:27 assets/models/cmd_filter.py:84
#: assets/models/user.py:214
#: assets/models/user.py:234
msgid "Priority"
msgstr "优先级"
#: acls/models/base.py:28 assets/models/cmd_filter.py:84
#: assets/models/user.py:214
#: assets/models/user.py:234
msgid "1-100, the lower the value will be match first"
msgstr "优先级可选范围为 1-100 (数值越小越优先)"
@ -208,7 +208,7 @@ msgid ""
msgstr "格式为逗号分隔的字符串, * 表示匹配所有. 可选的协议有: {}"
#: acls/serializers/login_asset_acl.py:55 assets/models/asset.py:214
#: assets/models/domain.py:63 assets/models/user.py:215
#: assets/models/domain.py:63 assets/models/user.py:235
#: terminal/serializers/session.py:30 terminal/serializers/storage.py:69
msgid "Protocol"
msgstr "协议"
@ -270,7 +270,7 @@ msgid "Application"
msgstr "应用程序"
#: applications/models/account.py:15 assets/models/authbook.py:20
#: assets/models/cmd_filter.py:42 assets/models/user.py:305 audits/models.py:40
#: assets/models/cmd_filter.py:42 assets/models/user.py:325 audits/models.py:40
#: perms/models/application_permission.py:32
#: perms/models/asset_permission.py:26 templates/_nav.html:45
#: terminal/backends/command/models.py:21
@ -311,11 +311,11 @@ msgstr "类别"
#: applications/models/application.py:207
#: applications/serializers/application.py:101 assets/models/backup.py:49
#: assets/models/cmd_filter.py:82 assets/models/user.py:213
#: assets/models/cmd_filter.py:82 assets/models/user.py:233
#: perms/models/application_permission.py:23
#: perms/serializers/application/user_permission.py:34
#: terminal/models/storage.py:55 terminal/models/storage.py:116
#: tickets/models/flow.py:55 tickets/models/ticket.py:52
#: tickets/models/flow.py:56 tickets/models/ticket.py:52
#: tickets/serializers/ticket/meta/ticket_type/apply_application.py:29
#: xpack/plugins/change_auth_plan/models/app.py:28
#: xpack/plugins/change_auth_plan/models/app.py:153
@ -564,7 +564,7 @@ msgstr "主机名原始"
msgid "Protocols"
msgstr "协议组"
#: assets/models/asset.py:219 assets/models/user.py:205
#: assets/models/asset.py:219 assets/models/user.py:225
#: perms/models/asset_permission.py:25
#: xpack/plugins/change_auth_plan/models/asset.py:43
#: xpack/plugins/gathered_user/models.py:24
@ -577,7 +577,7 @@ msgid "Is active"
msgstr "激活"
#: assets/models/asset.py:223 assets/models/cluster.py:19
#: assets/models/user.py:202 assets/models/user.py:354 templates/_nav.html:44
#: assets/models/user.py:222 assets/models/user.py:374 templates/_nav.html:44
msgid "Admin user"
msgstr "特权用户"
@ -703,7 +703,7 @@ msgstr "可连接性"
msgid "Date verified"
msgstr "校验日期"
#: assets/models/base.py:177 audits/signals_handler.py:66
#: assets/models/base.py:177 audits/signals_handler.py:68
#: authentication/forms.py:22
#: authentication/templates/authentication/login.html:151
#: settings/serializers/auth/ldap.py:44 users/forms/profile.py:21
@ -906,75 +906,75 @@ msgstr "ssh私钥"
msgid "Node"
msgstr "节点"
#: assets/models/user.py:196
#: assets/models/user.py:216
msgid "Automatic managed"
msgstr "托管密码"
#: assets/models/user.py:197
#: assets/models/user.py:217
msgid "Manually input"
msgstr "手动输入"
#: assets/models/user.py:201
#: assets/models/user.py:221
msgid "Common user"
msgstr "普通用户"
#: assets/models/user.py:204
#: assets/models/user.py:224
msgid "Username same with user"
msgstr "用户名与用户相同"
#: assets/models/user.py:207 assets/serializers/domain.py:29
#: assets/models/user.py:227 assets/serializers/domain.py:29
#: templates/_nav.html:39
#: terminal/templates/terminal/_msg_command_execute_alert.html:16
#: xpack/plugins/change_auth_plan/models/asset.py:39
msgid "Assets"
msgstr "资产"
#: assets/models/user.py:211 templates/_nav.html:17
#: assets/models/user.py:231 templates/_nav.html:17
#: users/views/profile/pubkey.py:37
msgid "Users"
msgstr "用户管理"
#: assets/models/user.py:212
#: assets/models/user.py:232
msgid "User groups"
msgstr "用户组"
#: assets/models/user.py:216
#: assets/models/user.py:236
msgid "Auto push"
msgstr "自动推送"
#: assets/models/user.py:217
#: assets/models/user.py:237
msgid "Sudo"
msgstr "Sudo"
#: assets/models/user.py:218
#: assets/models/user.py:238
msgid "Shell"
msgstr "Shell"
#: assets/models/user.py:219
#: assets/models/user.py:239
msgid "Login mode"
msgstr "认证方式"
#: assets/models/user.py:220
#: assets/models/user.py:240
msgid "SFTP Root"
msgstr "SFTP根路径"
#: assets/models/user.py:221 authentication/models.py:45
#: assets/models/user.py:241 authentication/models.py:45
msgid "Token"
msgstr ""
#: assets/models/user.py:222
#: assets/models/user.py:242
msgid "Home"
msgstr "家目录"
#: assets/models/user.py:223
#: assets/models/user.py:243
msgid "System groups"
msgstr "用户组"
#: assets/models/user.py:226
#: assets/models/user.py:246
msgid "User switch"
msgstr "用户切换"
#: assets/models/user.py:227
#: assets/models/user.py:247
msgid "Switch from"
msgstr "切换自"
@ -1047,6 +1047,7 @@ msgid "Actions"
msgstr "动作"
#: assets/serializers/backup.py:31 ops/mixin.py:106 ops/mixin.py:147
#: settings/serializers/auth/ldap.py:59
#: xpack/plugins/change_auth_plan/serializers/base.py:42
msgid "Periodic perform"
msgstr "定时执行"
@ -1225,24 +1226,24 @@ msgid ""
"The task of self-checking is already running and cannot be started repeatedly"
msgstr "自检程序已经在运行,不能重复启动"
#: assets/tasks/push_system_user.py:199
#: assets/tasks/push_system_user.py:200
msgid "System user is dynamic: {}"
msgstr "系统用户是动态的: {}"
#: assets/tasks/push_system_user.py:239
#: assets/tasks/push_system_user.py:241
msgid "Start push system user for platform: [{}]"
msgstr "推送系统用户到平台: [{}]"
#: assets/tasks/push_system_user.py:240
#: assets/tasks/push_system_user.py:242
#: assets/tasks/system_user_connectivity.py:106
msgid "Hosts count: {}"
msgstr "主机数量: {}"
#: assets/tasks/push_system_user.py:282 assets/tasks/push_system_user.py:315
#: assets/tasks/push_system_user.py:259 assets/tasks/push_system_user.py:292
msgid "Push system users to assets: "
msgstr "推送系统用户到入资产: "
#: assets/tasks/push_system_user.py:294
#: assets/tasks/push_system_user.py:271
msgid "Push system users to asset: "
msgstr "推送系统用户到入资产: "
@ -1448,209 +1449,209 @@ msgstr "运行用户名称"
msgid "User display"
msgstr "用户名称"
#: audits/signals_handler.py:65
#: audits/signals_handler.py:67
msgid "SSH Key"
msgstr "SSH 密钥"
#: audits/signals_handler.py:67
#: audits/signals_handler.py:69
msgid "SSO"
msgstr ""
#: audits/signals_handler.py:68
#: audits/signals_handler.py:70
msgid "Auth Token"
msgstr "认证令牌"
#: audits/signals_handler.py:69 authentication/notifications.py:73
#: audits/signals_handler.py:71 authentication/notifications.py:73
#: authentication/views/login.py:164 authentication/views/wecom.py:158
#: notifications/backends/__init__.py:11 users/models/user.py:607
msgid "WeCom"
msgstr "企业微信"
#: audits/signals_handler.py:70 authentication/views/dingtalk.py:160
#: audits/signals_handler.py:72 authentication/views/dingtalk.py:160
#: authentication/views/login.py:170 notifications/backends/__init__.py:12
#: users/models/user.py:608
msgid "DingTalk"
msgstr "钉钉"
#: audits/signals_handler.py:104
#: audits/signals_handler.py:106
msgid "User and Organization"
msgstr "用户与组织"
#: audits/signals_handler.py:105
#: audits/signals_handler.py:107
#, python-brace-format
msgid "{User} JOINED {Organization}"
msgstr "{User} 加入 {Organization}"
#: audits/signals_handler.py:106
#: audits/signals_handler.py:108
#, python-brace-format
msgid "{User} LEFT {Organization}"
msgstr "{User} 离开 {Organization}"
#: audits/signals_handler.py:109
#: audits/signals_handler.py:111
msgid "User and Group"
msgstr "用户与用户组"
#: audits/signals_handler.py:110
#: audits/signals_handler.py:112
#, python-brace-format
msgid "{User} JOINED {UserGroup}"
msgstr "{User} 加入 {UserGroup}"
#: audits/signals_handler.py:111
#: audits/signals_handler.py:113
#, python-brace-format
msgid "{User} LEFT {UserGroup}"
msgstr "{User} 离开 {UserGroup}"
#: audits/signals_handler.py:114
#: audits/signals_handler.py:116
msgid "Asset and SystemUser"
msgstr "资产与系统用户"
#: audits/signals_handler.py:115
#: audits/signals_handler.py:117
#, python-brace-format
msgid "{Asset} ADD {SystemUser}"
msgstr "{Asset} 添加 {SystemUser}"
#: audits/signals_handler.py:116
#: audits/signals_handler.py:118
#, python-brace-format
msgid "{Asset} REMOVE {SystemUser}"
msgstr "{Asset} 移除 {SystemUser}"
#: audits/signals_handler.py:119
#: audits/signals_handler.py:121
msgid "Node and Asset"
msgstr "节点与资产"
#: audits/signals_handler.py:120
#: audits/signals_handler.py:122
#, python-brace-format
msgid "{Node} ADD {Asset}"
msgstr "{Node} 添加 {Asset}"
#: audits/signals_handler.py:121
#: audits/signals_handler.py:123
#, python-brace-format
msgid "{Node} REMOVE {Asset}"
msgstr "{Node} 移除 {Asset}"
#: audits/signals_handler.py:124
#: audits/signals_handler.py:126
msgid "User asset permissions"
msgstr "用户资产授权"
#: audits/signals_handler.py:125
#: audits/signals_handler.py:127
#, python-brace-format
msgid "{AssetPermission} ADD {User}"
msgstr "{AssetPermission} 添加 {User}"
#: audits/signals_handler.py:126
#: audits/signals_handler.py:128
#, python-brace-format
msgid "{AssetPermission} REMOVE {User}"
msgstr "{AssetPermission} 移除 {User}"
#: audits/signals_handler.py:129
#: audits/signals_handler.py:131
msgid "User group asset permissions"
msgstr "用户组资产授权"
#: audits/signals_handler.py:130
#: audits/signals_handler.py:132
#, python-brace-format
msgid "{AssetPermission} ADD {UserGroup}"
msgstr "{AssetPermission} 添加 {UserGroup}"
#: audits/signals_handler.py:131
#: audits/signals_handler.py:133
#, python-brace-format
msgid "{AssetPermission} REMOVE {UserGroup}"
msgstr "{AssetPermission} 移除 {UserGroup}"
#: audits/signals_handler.py:134 perms/models/asset_permission.py:30
#: audits/signals_handler.py:136 perms/models/asset_permission.py:30
#: templates/_nav.html:78 users/templates/users/_user_detail_nav_header.html:31
msgid "Asset permission"
msgstr "资产授权"
#: audits/signals_handler.py:135
#: audits/signals_handler.py:137
#, python-brace-format
msgid "{AssetPermission} ADD {Asset}"
msgstr "{AssetPermission} 添加 {Asset}"
#: audits/signals_handler.py:136
#: audits/signals_handler.py:138
#, python-brace-format
msgid "{AssetPermission} REMOVE {Asset}"
msgstr "{AssetPermission} 移除 {Asset}"
#: audits/signals_handler.py:139
#: audits/signals_handler.py:141
msgid "Node permission"
msgstr "节点授权"
#: audits/signals_handler.py:140
#: audits/signals_handler.py:142
#, python-brace-format
msgid "{AssetPermission} ADD {Node}"
msgstr "{AssetPermission} 添加 {Node}"
#: audits/signals_handler.py:141
#: audits/signals_handler.py:143
#, python-brace-format
msgid "{AssetPermission} REMOVE {Node}"
msgstr "{AssetPermission} 移除 {Node}"
#: audits/signals_handler.py:144
#: audits/signals_handler.py:146
msgid "Asset permission and SystemUser"
msgstr "资产授权与系统用户"
#: audits/signals_handler.py:145
#: audits/signals_handler.py:147
#, python-brace-format
msgid "{AssetPermission} ADD {SystemUser}"
msgstr "{AssetPermission} 添加 {SystemUser}"
#: audits/signals_handler.py:146
#: audits/signals_handler.py:148
#, python-brace-format
msgid "{AssetPermission} REMOVE {SystemUser}"
msgstr "{AssetPermission} 移除 {SystemUser}"
#: audits/signals_handler.py:149
#: audits/signals_handler.py:151
msgid "User application permissions"
msgstr "用户应用授权"
#: audits/signals_handler.py:150
#: audits/signals_handler.py:152
#, python-brace-format
msgid "{ApplicationPermission} ADD {User}"
msgstr "{ApplicationPermission} 添加 {User}"
#: audits/signals_handler.py:151
#: audits/signals_handler.py:153
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {User}"
msgstr "{ApplicationPermission} 移除 {User}"
#: audits/signals_handler.py:154
#: audits/signals_handler.py:156
msgid "User group application permissions"
msgstr "用户组应用授权"
#: audits/signals_handler.py:155
#: audits/signals_handler.py:157
#, python-brace-format
msgid "{ApplicationPermission} ADD {UserGroup}"
msgstr "{ApplicationPermission} 添加 {UserGroup}"
#: audits/signals_handler.py:156
#: audits/signals_handler.py:158
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {UserGroup}"
msgstr "{ApplicationPermission} 移除 {UserGroup}"
#: audits/signals_handler.py:159 perms/models/application_permission.py:37
#: audits/signals_handler.py:161 perms/models/application_permission.py:37
msgid "Application permission"
msgstr "应用授权"
#: audits/signals_handler.py:160
#: audits/signals_handler.py:162
#, python-brace-format
msgid "{ApplicationPermission} ADD {Application}"
msgstr "{ApplicationPermission} 添加 {Application}"
#: audits/signals_handler.py:161
#: audits/signals_handler.py:163
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {Application}"
msgstr "{ApplicationPermission} 移除 {Application}"
#: audits/signals_handler.py:164
#: audits/signals_handler.py:166
msgid "Application permission and SystemUser"
msgstr "应用授权与系统用户"
#: audits/signals_handler.py:165
#: audits/signals_handler.py:167
#, python-brace-format
msgid "{ApplicationPermission} ADD {SystemUser}"
msgstr "{ApplicationPermission} 添加 {SystemUser}"
#: audits/signals_handler.py:166
#: audits/signals_handler.py:168
#, python-brace-format
msgid "{ApplicationPermission} REMOVE {SystemUser}"
msgstr "{ApplicationPermission} 移除 {SystemUser}"
@ -2557,15 +2558,16 @@ msgid "Operations"
msgstr "运维"
#: ops/mixin.py:29 ops/mixin.py:92 ops/mixin.py:162
#: settings/serializers/auth/ldap.py:66
msgid "Cycle perform"
msgstr "周期执行"
#: ops/mixin.py:33 ops/mixin.py:90 ops/mixin.py:109 ops/mixin.py:150
#: settings/serializers/auth/ldap.py:64
#: settings/serializers/auth/ldap.py:63
msgid "Regularly perform"
msgstr "定期执行"
#: ops/mixin.py:112 settings/serializers/auth/ldap.py:61
#: ops/mixin.py:112
msgid "Interval"
msgstr "间隔"
@ -2592,7 +2594,7 @@ msgstr ""
"分 时 日 月 星期> <a href='https://tool.lu/crontab/' target='_blank'>在线工"
"具</a> <br>注意: 如果同时设置了定期执行和周期执行,优先使用定期执行"
#: ops/mixin.py:162 settings/serializers/auth/ldap.py:61
#: ops/mixin.py:162
msgid "Unit: hour"
msgstr "单位: 时"
@ -2873,7 +2875,7 @@ msgstr "用户名称"
#: perms/serializers/asset/permission.py:22
msgid "User groups display"
msgstr "用户名称"
msgstr "用户名称"
#: perms/serializers/asset/permission.py:23
msgid "Assets display"
@ -3062,21 +3064,15 @@ msgstr ""
"用户属性映射代表怎样将LDAP中用户属性映射到jumpserver用户上username, name,"
"email 是jumpserver的用户需要属性"
#: settings/serializers/auth/ldap.py:58
#: xpack/plugins/cloud/serializers/task.py:70
#: xpack/plugins/gathered_user/serializers.py:20
msgid "Periodic display"
msgstr "定时执行"
#: settings/serializers/auth/ldap.py:68
#: settings/serializers/auth/ldap.py:70
msgid "Connect timeout"
msgstr "连接超时时间"
#: settings/serializers/auth/ldap.py:70
#: settings/serializers/auth/ldap.py:72
msgid "Search paged size"
msgstr "搜索分页数量"
#: settings/serializers/auth/ldap.py:72
#: settings/serializers/auth/ldap.py:74
msgid "Enable LDAP auth"
msgstr "启用 LDAP 认证"
@ -4366,19 +4362,19 @@ msgstr "Jmservisor 是在 windows 远程应用发布服务器中用来拉起远
msgid "Filters"
msgstr "过滤"
#: terminal/api/session.py:190
#: terminal/api/session.py:192
msgid "Session does not exist: {}"
msgstr "会话不存在: {}"
#: terminal/api/session.py:193
#: terminal/api/session.py:195
msgid "Session is finished or the protocol not supported"
msgstr "会话已经完成或协议不支持"
#: terminal/api/session.py:198
#: terminal/api/session.py:200
msgid "User does not exist: {}"
msgstr "用户不存在: {}"
#: terminal/api/session.py:205
#: terminal/api/session.py:207
msgid "User does not have permission"
msgstr "用户没有权限"
@ -4935,24 +4931,24 @@ msgstr "用户显示名称"
msgid "Body"
msgstr "内容"
#: tickets/models/flow.py:18 tickets/models/flow.py:60
#: tickets/models/flow.py:19 tickets/models/flow.py:61
#: tickets/models/ticket.py:29
msgid "Approve level"
msgstr "审批级别"
#: tickets/models/flow.py:23 tickets/serializers/ticket/ticket.py:141
#: tickets/models/flow.py:24 tickets/serializers/ticket/ticket.py:141
msgid "Approve strategy"
msgstr "审批策略"
#: tickets/models/flow.py:28 tickets/serializers/ticket/ticket.py:142
#: tickets/models/flow.py:29 tickets/serializers/ticket/ticket.py:142
msgid "Assignees"
msgstr "受理人"
#: tickets/models/flow.py:32
#: tickets/models/flow.py:33
msgid "Ticket flow approval rule"
msgstr "工单批准信息"
#: tickets/models/flow.py:65
#: tickets/models/flow.py:66
msgid "Ticket flow"
msgstr "工单流程"
@ -6287,6 +6283,11 @@ msgstr "实例个数"
msgid "Linux admin user"
msgstr "Linux 管理员"
#: xpack/plugins/cloud/serializers/task.py:70
#: xpack/plugins/gathered_user/serializers.py:20
msgid "Periodic display"
msgstr "定时执行"
#: xpack/plugins/cloud/utils.py:68
msgid "Account unavailable"
msgstr "账户无效"

View File

@ -1,4 +1,5 @@
import time
from functools import reduce
from django.db.models import Q
@ -79,3 +80,14 @@ def get_application_system_user_ids(user, application):
def has_application_system_permission(user, application, system_user):
system_user_ids = get_application_system_user_ids(user, application)
return system_user.id in system_user_ids
def get_application_actions(user, application, system_user):
perm_ids = get_user_all_app_perm_ids(user)
actions = ApplicationPermission.objects.filter(
applications=application, system_users=system_user,
id__in=list(perm_ids)
).values_list('actions', flat=True)
actions = reduce(lambda x, y: x | y, actions, 0)
return actions

View File

@ -109,3 +109,9 @@ def get_asset_system_user_ids_with_actions_by_group(group: UserGroup, asset: Ass
user_groups=group
).valid().values_list('id', flat=True).distinct()
return get_asset_system_user_ids_with_actions(asset_perm_ids, asset)
def get_asset_actions(user, asset, system_user):
systemuser_actions_mapper = get_asset_system_user_ids_with_actions_by_user(user, asset)
actions = systemuser_actions_mapper.get(system_user.id, 0)
return actions

View File

@ -55,13 +55,15 @@ class LDAPSettingSerializer(serializers.Serializer):
help_text=_('User attr map present how to map LDAP user attr to '
'jumpserver, username,name,email is jumpserver attr')
)
AUTH_LDAP_SYNC_IS_PERIODIC = serializers.BooleanField(required=False, label=_('Periodic display'))
AUTH_LDAP_SYNC_INTERVAL = serializers.CharField(
required=False, max_length=1024, allow_null=True,
label=_('Interval'), help_text=_('Unit: hour')
AUTH_LDAP_SYNC_IS_PERIODIC = serializers.BooleanField(
required=False, label=_('Periodic perform')
)
AUTH_LDAP_SYNC_CRONTAB = serializers.CharField(
required=False, max_length=1024, allow_null=True, label=_('Regularly perform')
required=False, max_length=128, allow_null=True, allow_blank=True,
label=_('Regularly perform')
)
AUTH_LDAP_SYNC_INTERVAL = serializers.IntegerField(
required=False, default=24, allow_null=True, label=_('Cycle perform')
)
AUTH_LDAP_CONNECT_TIMEOUT = serializers.IntegerField(
min_value=1, max_value=300,

View File

@ -1,7 +1,6 @@
from typing import Callable
import textwrap
from django.utils.translation import gettext_lazy as _
from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from django.template.loader import render_to_string
@ -11,7 +10,6 @@ from notifications.notifications import SystemMessage
from terminal.models import Session, Command
from notifications.models import SystemMsgSubscription
from notifications.backends import BACKEND
from orgs.utils import tmp_to_root_org
from common.utils import lazyproperty
from common.utils.timezone import local_now_display

View File

@ -81,7 +81,7 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet):
class TicketFlowViewSet(JMSBulkModelViewSet):
permission_classes = (IsOrgAdmin,)
permission_classes = (IsSuperUser,)
serializer_class = serializers.TicketFlowSerializer
filterset_fields = ['id', 'type']