perf: 批量上传添加权限校验

pull/12954/head
wangruidong 8 months ago committed by Bryan
parent 0aeea414f5
commit 9776d35140

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:0bd11124a56e5fa0b2b8433528d4ffd8c454e5f529bdd72fea15d1a62434165e
size 176114
oid sha256:488d95a4a96d38c3c0633f183334498d9e247bdf66ce3a4bcc836f80e8320432
size 176705

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-03 16:51+0800\n"
"POT-Creation-Date: 2024-04-07 14:23+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -1362,13 +1362,13 @@ msgstr "アプリケーション"
msgid "Can match application"
msgstr "アプリケーションを一致させることができます"
#: assets/api/asset/asset.py:181
#: assets/api/asset/asset.py:180
msgid "Cannot create asset directly, you should create a host or other"
msgstr ""
"資産を直接作成することはできません。ホストまたはその他を作成する必要がありま"
"す"
#: assets/api/domain.py:68
#: assets/api/domain.py:67
msgid "Number required"
msgstr "必要な数"
@ -4137,11 +4137,24 @@ msgstr "タスクは存在しません"
msgid "Task {} args or kwargs error"
msgstr "タスク実行パラメータエラー"
#: ops/api/job.py:146
msgid ""
"Asset ({asset}) must have at least one of the following protocols added: "
"SSH, SFTP, or WinRM"
msgstr ""
"資産({asset})には、少なくともSSH、SFTP、WinRMのいずれか一つのプロトコルを追加す"
"る必要があります"
msgid "Asset ({asset}) authorization is missing SSH, SFTP, or WinRM protocol"
msgstr "資産({asset})の認証にはSSH、SFTP、またはWinRMプロトコルが不足しています"
msgid "Asset ({asset}) authorization lacks upload permissions"
msgstr "資産({asset})の認証にはアップロード権限が不足しています"
#: ops/api/job.py:168
msgid "Duplicate file exists"
msgstr "重複したファイルが存在する"
#: ops/api/job.py:151
#: ops/api/job.py:173
#, python-brace-format
msgid ""
"File size exceeds maximum limit. Please select a file smaller than {limit}MB"
@ -4149,7 +4162,7 @@ msgstr ""
"ファイルサイズが最大制限を超えています。{limit}MB より小さいファイルを選択し"
"てください。"
#: ops/api/job.py:215
#: ops/api/job.py:237
msgid ""
"The task is being created and cannot be interrupted. Please try again later."
msgstr "タスクを作成中で、中断できません。後でもう一度お試しください。"
@ -4537,18 +4550,18 @@ msgstr "ジョブのID"
msgid "Name of the job"
msgstr "ジョブの名前"
#: orgs/api.py:62
#: orgs/api.py:61
msgid "The current organization ({}) cannot be deleted"
msgstr "現在の組織 ({}) は削除できません"
#: orgs/api.py:67
#: orgs/api.py:66
msgid ""
"LDAP synchronization is set to the current organization. Please switch to "
"another organization before deleting"
msgstr ""
"LDAP 同期は現在の組織に設定されます。削除する前に別の組織に切り替えてください"
#: orgs/api.py:77
#: orgs/api.py:76
msgid "The organization have resource ({}) cannot be deleted"
msgstr "組織のリソース ({}) は削除できません"
@ -6531,11 +6544,11 @@ msgstr "これはエンタープライズ版アプレットです"
msgid "Not found protocol query params"
msgstr "プロトコルクエリパラメータが見つかりません"
#: terminal/api/component/storage.py:30
#: terminal/api/component/storage.py:31
msgid "Deleting the default storage is not allowed"
msgstr "デフォルトのストレージの削除は許可されていません"
#: terminal/api/component/storage.py:33
#: terminal/api/component/storage.py:34
msgid "Cannot delete storage that is being used"
msgstr "使用中のストレージを削除できません"
@ -6547,15 +6560,15 @@ msgstr "コマンドストア"
msgid "Invalid"
msgstr "無効"
#: terminal/api/component/storage.py:131 terminal/tasks.py:149
#: terminal/api/component/storage.py:130 terminal/tasks.py:149
msgid "Test failure: {}"
msgstr "テスト失敗: {}"
#: terminal/api/component/storage.py:134
#: terminal/api/component/storage.py:133
msgid "Test successful"
msgstr "テスト成功"
#: terminal/api/component/storage.py:136
#: terminal/api/component/storage.py:135
msgid "Test failure: Please check configuration"
msgstr "テストに失敗しました:構成を確認してください"
@ -7890,11 +7903,11 @@ msgstr "無効な承認アクション"
msgid "This user is not authorized to approve this ticket"
msgstr "このユーザーはこの作業指示を承認する権限がありません"
#: users/api/user.py:137
#: users/api/user.py:136
msgid "Can not invite self"
msgstr "自分自身を招待することはできません"
#: users/api/user.py:190
#: users/api/user.py:189
msgid "Could not reset self otp, use profile reset instead"
msgstr "自己otpをリセットできませんでした、代わりにプロファイルリセットを使用"
@ -9311,6 +9324,3 @@ msgstr "エンタープライズプロフェッショナル版"
#: xpack/plugins/license/models.py:86
msgid "Ultimate edition"
msgstr "エンタープライズ・フラッグシップ・エディション"
#~ msgid "Reopen"
#~ msgstr "再オープン"

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:91ad10be95fda19937a09d07806d05f21057a1a79f40428350127d1162c7655d
size 144168
oid sha256:bd99d1b6018567413cefe5fe188a19019e09da46934c05ae9ce229943f712859
size 144595

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: JumpServer 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-04-03 16:51+0800\n"
"POT-Creation-Date: 2024-04-07 14:23+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"
@ -1354,11 +1354,11 @@ msgstr "应用程序"
msgid "Can match application"
msgstr "匹配应用"
#: assets/api/asset/asset.py:181
#: assets/api/asset/asset.py:180
msgid "Cannot create asset directly, you should create a host or other"
msgstr "不能直接创建资产, 你应该创建主机或其他资产"
#: assets/api/domain.py:68
#: assets/api/domain.py:67
msgid "Number required"
msgstr "需要为数字"
@ -4086,17 +4086,28 @@ msgstr "任务 {} 不存在"
msgid "Task {} args or kwargs error"
msgstr "任务 {} 执行参数错误"
#: ops/api/job.py:146
msgid ""
"Asset ({asset}) must have at least one of the following protocols added: "
"SSH, SFTP, or WinRM"
msgstr "资产({asset})至少要添加ssh,sftp,winrm其中一种协议"
msgid "Asset ({asset}) authorization is missing SSH, SFTP, or WinRM protocol"
msgstr "资产({asset})授权缺少ssh,sftp或winrm协议"
msgid "Asset ({asset}) authorization lacks upload permissions"
msgstr "资产({asset})授权缺少上传权限"
#: ops/api/job.py:168
msgid "Duplicate file exists"
msgstr "存在同名文件"
#: ops/api/job.py:151
#: ops/api/job.py:173
#, python-brace-format
msgid ""
"File size exceeds maximum limit. Please select a file smaller than {limit}MB"
msgstr "文件大小超过最大限制。请选择小于 {limit}MB 的文件。"
#: ops/api/job.py:215
#: ops/api/job.py:237
msgid ""
"The task is being created and cannot be interrupted. Please try again later."
msgstr "正在创建任务,无法中断,请稍后重试。"
@ -4484,17 +4495,17 @@ msgstr "Job ID"
msgid "Name of the job"
msgstr "Job 名称"
#: orgs/api.py:62
#: orgs/api.py:61
msgid "The current organization ({}) cannot be deleted"
msgstr "当前组织 ({}) 不能被删除"
#: orgs/api.py:67
#: orgs/api.py:66
msgid ""
"LDAP synchronization is set to the current organization. Please switch to "
"another organization before deleting"
msgstr "LDAP 同步设置组织为当前组织,请切换其他组织后再进行删除操作"
#: orgs/api.py:77
#: orgs/api.py:76
msgid "The organization have resource ({}) cannot be deleted"
msgstr "组织存在资源 ({}) 不能被删除"
@ -6435,11 +6446,11 @@ msgstr "企业版远程应用,在社区版中不能使用"
msgid "Not found protocol query params"
msgstr "未发现 protocol 查询参数"
#: terminal/api/component/storage.py:30
#: terminal/api/component/storage.py:31
msgid "Deleting the default storage is not allowed"
msgstr "不允许删除默认存储配置"
#: terminal/api/component/storage.py:33
#: terminal/api/component/storage.py:34
msgid "Cannot delete storage that is being used"
msgstr "不允许删除正在使用的存储配置"
@ -6451,15 +6462,15 @@ msgstr "命令存储"
msgid "Invalid"
msgstr "无效"
#: terminal/api/component/storage.py:131 terminal/tasks.py:149
#: terminal/api/component/storage.py:130 terminal/tasks.py:149
msgid "Test failure: {}"
msgstr "测试失败: {}"
#: terminal/api/component/storage.py:134
#: terminal/api/component/storage.py:133
msgid "Test successful"
msgstr "测试成功"
#: terminal/api/component/storage.py:136
#: terminal/api/component/storage.py:135
msgid "Test failure: Please check configuration"
msgstr "测试失败:请检查配置"
@ -7781,11 +7792,11 @@ msgstr "无效的审批动作"
msgid "This user is not authorized to approve this ticket"
msgstr "此用户无权审批此工单"
#: users/api/user.py:137
#: users/api/user.py:136
msgid "Can not invite self"
msgstr "不能邀请自己"
#: users/api/user.py:190
#: users/api/user.py:189
msgid "Could not reset self otp, use profile reset instead"
msgstr "不能在该页面重置 MFA 多因子认证, 请去个人信息页面重置"
@ -9182,6 +9193,3 @@ msgstr "企业专业版"
#: xpack/plugins/license/models.py:86
msgid "Ultimate edition"
msgstr "企业旗舰版"
#~ msgid "Reopen"
#~ msgstr "重新打开"

@ -32,6 +32,9 @@ from ops.variables import JMS_JOB_VARIABLE_HELP
from orgs.mixins.api import OrgBulkModelViewSet
from orgs.utils import tmp_to_org, get_current_org
from accounts.models import Account
from assets.const import Protocol
from perms.const import ActionChoices
from perms.utils.asset_perm import PermAssetDetailUtil
from perms.models import PermNode
from perms.utils import UserPermAssetUtil
from jumpserver.settings import get_file_md5
@ -72,6 +75,22 @@ class JobViewSet(OrgBulkModelViewSet):
return self.permission_denied(request, "Command execution disabled")
return super().check_permissions(request)
def check_upload_permission(self, assets, account_name):
protocols_required = {Protocol.ssh, Protocol.sftp, Protocol.winrm}
error_msg_missing_protocol = _(
"Asset ({asset}) must have at least one of the following protocols added: SSH, SFTP, or WinRM")
error_msg_auth_missing_protocol = _("Asset ({asset}) authorization is missing SSH, SFTP, or WinRM protocol")
error_msg_auth_missing_upload = _("Asset ({asset}) authorization lacks upload permissions")
for asset in assets:
protocols = asset.protocols.values_list("name", flat=True)
if not set(protocols).intersection(protocols_required):
self.permission_denied(self.request, error_msg_missing_protocol.format(asset=asset.name))
util = PermAssetDetailUtil(self.request.user, asset)
if not util.check_perm_protocols(protocols_required):
self.permission_denied(self.request, error_msg_auth_missing_protocol.format(asset=asset.name))
if not util.check_perm_actions(account_name, [ActionChoices.upload.value]):
self.permission_denied(self.request, error_msg_auth_missing_upload.format(asset=asset.name))
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset \
@ -89,6 +108,9 @@ class JobViewSet(OrgBulkModelViewSet):
assets = serializer.validated_data.get('assets')
assets = merge_nodes_and_assets(node_ids, assets, self.request.user)
serializer.validated_data['assets'] = assets
if serializer.validated_data.get('type') == Types.upload_file:
account_name = serializer.validated_data.get('runas')
self.check_upload_permission(assets, account_name)
instance = serializer.save()
if instance.instant or run_after_save:

@ -42,6 +42,10 @@ class ActionChoices(BitChoices):
def contains(cls, total, action_value):
return action_value & total == action_value
@classmethod
def contains_all(cls, total, action_values):
return all(cls.contains(total, action) for action in action_values)
@classmethod
def display(cls, value):
return ', '.join([str(c.label) for c in cls if c.value & value == c.value])

@ -6,6 +6,7 @@ from assets.models import Asset
from common.utils import lazyproperty
from orgs.utils import tmp_to_org, tmp_to_root_org
from .permission import AssetPermissionUtil
from perms.const import ActionChoices
__all__ = ['PermAssetDetailUtil']
@ -137,3 +138,23 @@ class PermAssetDetailUtil:
account.date_expired = max(cleaned_accounts_expired[account])
accounts.append(account)
return accounts
def check_perm_protocols(self, protocols):
"""
检查用户是否有某些协议权限
:param protocols: set
"""
perms_protocols = self.get_permed_protocols_for_user(only_name=True)
if "all" in perms_protocols:
return True
return protocols.intersection(perms_protocols)
def check_perm_actions(self, account_name, actions):
"""
检查用户是否有某个账号的某个资产操作权限
:param account_name: str
:param actions: list
"""
perms = self.user_asset_perms
action_bit_mapper, __ = self.parse_alias_action_date_expire(perms, self.asset)
return ActionChoices.contains_all(action_bit_mapper.get(account_name, 0), actions)

Loading…
Cancel
Save