From d2aa6dee359b04115ab4b0e5cfb4b2a5bb82ff19 Mon Sep 17 00:00:00 2001 From: crayon <873217631@qq.com> Date: Thu, 3 Aug 2023 15:03:25 +0800 Subject: [PATCH 01/17] =?UTF-8?q?feature:=20=E5=9B=BD=E5=AF=86=E6=94=B9?= =?UTF-8?q?=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config/default.py | 36 ++++++++++++++++++ config/sites/community/ver_settings.py | 23 +++++++++++- config/sites/enterprise/ver_settings.py | 25 ++++++++++++- env.py | 4 ++ env_v2.py | 2 + env_v3.py | 2 + .../desktop/src/assets/html/index-dev.html | 3 ++ frontend/desktop/src/assets/html/index.html | 3 ++ gcloud/core/context_processors.py | 11 +++++- gcloud/utils/crypto.py | 37 ++++++++++++++++++- .../atoms/nodeman/create_task/v4_0.js | 2 + pipeline_plugins/components/utils/common.py | 16 +------- .../variables/collections/common.py | 13 ++++--- requirements.txt | 1 + 14 files changed, 153 insertions(+), 25 deletions(-) diff --git a/config/default.py b/config/default.py index 8c01f8bdd3..5d302cd9e9 100644 --- a/config/default.py +++ b/config/default.py @@ -16,6 +16,8 @@ from urllib.parse import urlparse from bamboo_engine.config import Settings as BambooSettings +from bkcrypto.asymmetric.options import RSAAsymmetricOptions +from bkcrypto.symmetric.options import AESSymmetricOptions, SM4SymmetricOptions from blueapps.conf.default_settings import * # noqa from blueapps.conf.log import get_logging_config_dict from blueapps.opentelemetry.utils import inject_logging_trace_info @@ -25,6 +27,8 @@ import env from gcloud.exceptions import ApiRequestError +from bkcrypto import constants as bkcrypto_constants + # 这里是默认的 INSTALLED_APPS,大部分情况下,不需要改动 # 如果你已经了解每个默认 APP 的作用,确实需要去掉某些 APP,请去掉下面的注释,然后修改 # INSTALLED_APPS = ( @@ -789,3 +793,35 @@ def check_engine_admin_permission(request, *args, **kwargs): PIPELINE_ENGINE_ADMIN_API_PERMISSION = "config.default.check_engine_admin_permission" + + +BKCRYPTO = { + "ASYMMETRIC_CIPHERS": { + "default": { + "get_key_config": "gcloud.utils.crypto.get_default_asymmetric_key_config", + "cipher_options": { + bkcrypto_constants.AsymmetricCipherType.RSA.value: RSAAsymmetricOptions( + padding=bkcrypto_constants.RSACipherPadding.PKCS1_v1_5 + ) + }, + }, + }, +} + +# 加密 +if env.BKAPP_CRYPTO_TYPE == "SHANGMI": + BKCRYPTO_ASYMMETRIC_CIPHER_TYPE = bkcrypto_constants.AsymmetricCipherType.SM2.value + BKCRYPTO.update( + { + "ASYMMETRIC_CIPHER_TYPE": BKCRYPTO_ASYMMETRIC_CIPHER_TYPE, + "SYMMETRIC_CIPHER_TYPE": bkcrypto_constants.SymmetricCipherType.SM4.value, + } + ) +else: + BKCRYPTO_ASYMMETRIC_CIPHER_TYPE = bkcrypto_constants.AsymmetricCipherType.RSA.value + BKCRYPTO.update( + { + "ASYMMETRIC_CIPHER_TYPE": BKCRYPTO_ASYMMETRIC_CIPHER_TYPE, + "SYMMETRIC_CIPHER_TYPE": bkcrypto_constants.SymmetricCipherType.AES.value, + } + ) diff --git a/config/sites/community/ver_settings.py b/config/sites/community/ver_settings.py index f799638d9a..307c7af1ba 100644 --- a/config/sites/community/ver_settings.py +++ b/config/sites/community/ver_settings.py @@ -37,7 +37,6 @@ LOah9mmRwLJdcfa3Js+jw2lOCmxzqauYZHVHg/hH7g== -----END RSA PRIVATE KEY----- """ -RSA_PRIV_KEY = base64.b64decode(env.RSA_PRIV_KEY).decode("utf-8") if env.RSA_PRIV_KEY else DEFAULT_RSA_PRIV_KEY # PUB_KEY for frontend, which can not use three quotes DEFAULT_RSA_PUB_KEY = ( @@ -49,8 +48,30 @@ + "-----END PUBLIC KEY-----" ) +RSA_PRIV_KEY = base64.b64decode(env.RSA_PRIV_KEY).decode("utf-8") if env.RSA_PRIV_KEY else DEFAULT_RSA_PRIV_KEY RSA_PUB_KEY = base64.b64decode(env.RSA_PUB_KEY).decode("utf-8") if env.RSA_PUB_KEY else DEFAULT_RSA_PUB_KEY + +DEFAULT_SM2_PRIV_KEY = """ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEICI+zMQDiQ5/xXmnGxGqLSD++Cp+I601cIFLKRd2yrGBoAoGCCqBHM9V +AYItoUQDQgAE95+i3TAfODAzb9QhJmyUmxH/HocisveqkrafHJ25NO/uCtkb2yXH +vrZcCDmoxeO+z5vp88jN/ulVsl9qEqm6vQ== +-----END EC PRIVATE KEY----- +""" + + +DEFAULT_SM2_PUB_KEY = ( + "-----BEGIN PUBLIC KEY-----\\n" + + "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE95+i3TAfODAzb9QhJmyUmxH/Hoci\\n" + + "sveqkrafHJ25NO/uCtkb2yXHvrZcCDmoxeO+z5vp88jN/ulVsl9qEqm6vQ==\\n" + + "-----END PUBLIC KEY-----" +) + + +SM2_PRIV_KEY = base64.b64decode(env.RSA_PRIV_KEY).decode("utf-8") if env.RSA_PRIV_KEY else DEFAULT_RSA_PRIV_KEY +SM2_PUB_KEY = base64.b64decode(env.RSA_PUB_KEY).decode("utf-8") if env.RSA_PUB_KEY else DEFAULT_SM2_PUB_KEY + # APIGW Auth APIGW_APP_CODE_KEY = "bk_app_code" APIGW_USER_USERNAME_KEY = "bk_username" diff --git a/config/sites/enterprise/ver_settings.py b/config/sites/enterprise/ver_settings.py index 4270ab010c..d109cf0de2 100644 --- a/config/sites/enterprise/ver_settings.py +++ b/config/sites/enterprise/ver_settings.py @@ -37,7 +37,6 @@ T8ow3nMSbvx5X28wOjbk04tmfM/kVqcVhFWhDHjHZzlt -----END RSA PRIVATE KEY----- """ -RSA_PRIV_KEY = base64.b64decode(env.RSA_PRIV_KEY).decode("utf-8") if env.RSA_PRIV_KEY else DEFAULT_RSA_PRIV_KEY # PUB_KEY for frontend, which can not use three quotes DEFAULT_RSA_PUB_KEY = ( @@ -48,7 +47,31 @@ + "iymoAVK67gfTOTvckQIDAQAB\\n" + "-----END PUBLIC KEY-----" ) + RSA_PUB_KEY = base64.b64decode(env.RSA_PUB_KEY).decode("utf-8") if env.RSA_PUB_KEY else DEFAULT_RSA_PUB_KEY +RSA_PRIV_KEY = base64.b64decode(env.RSA_PRIV_KEY).decode("utf-8") if env.RSA_PRIV_KEY else DEFAULT_RSA_PRIV_KEY + + +DEFAULT_SM2_PRIV_KEY = """ +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIIn5SYKHr3+m/XyC/ECzDJYuwUoTQHDUkIueKFXTjhSBoAoGCCqBHM9V +AYItoUQDQgAEYxBE08d8yEEK2+DZ7F5RsNrUvCZ578lkYsXFDC1fW2IcRecNz8LG +ZWSZGFfgYMeK1f3fIuYBAJVuna/V3FP4tA== +-----END EC PRIVATE KEY----- +""" + + +DEFAULT_SM2_PUB_KEY = ( + "-----BEGIN PUBLIC KEY-----\\n" + + "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEYxBE08d8yEEK2+DZ7F5RsNrUvCZ5\\n" + + "78lkYsXFDC1fW2IcRecNz8LGZWSZGFfgYMeK1f3fIuYBAJVuna/V3FP4tA==\\n" + + "-----END PUBLIC KEY-----" +) + + +SM2_PRIV_KEY = base64.b64decode(env.SM2_PRIV_KEY).decode("utf-8") if env.SM2_PRIV_KEY else DEFAULT_SM2_PRIV_KEY +SM2_PUB_KEY = base64.b64decode(env.SM2_PUB_KEY).decode("utf-8") if env.SM2_PUB_KEY else DEFAULT_SM2_PUB_KEY + # APIGW Auth APIGW_APP_CODE_KEY = "bk_app_code" diff --git a/env.py b/env.py index f77124aabd..43db006dd3 100644 --- a/env.py +++ b/env.py @@ -108,3 +108,7 @@ # 获取 PaaS 注入的蓝鲸域名 BKPAAS_BK_DOMAIN = os.getenv("BKPAAS_BK_DOMAIN", "") or os.getenv("BK_DOMAIN", "") + + +# 获取加密类型 +BKAPP_CRYPTO_TYPE = os.getenv("BK_CRYPTO_TYPE") or os.getenv("BKAPP_CRYPTO_TYPE") or "CLASSIC" diff --git a/env_v2.py b/env_v2.py index 1e1c3d88d2..5d772a65cd 100644 --- a/env_v2.py +++ b/env_v2.py @@ -136,6 +136,8 @@ # RSA KEYS, 保存的是密钥的base64加密形式, 使用base64.b64encode(KEY.encode("utf-8"))进行处理后保存为环境变量 RSA_PRIV_KEY = os.getenv("BKAPP_RSA_PRIV_KEY", None) RSA_PUB_KEY = os.getenv("BKAPP_RSA_PUB_KEY", None) +SM2_PRIV_KEY = os.getenv("BKAPP_SM2_PRIV_KEY", None) +SM2_PUB_KEY = os.getenv("BKAPP_SM2_PUB_KEY", None) # 单业务下最大周期任务数量 PERIODIC_TASK_PROJECT_MAX_NUMBER = int(os.getenv("BKAPP_PERIODIC_TASK_PROJECT_MAX_NUMBER", 50)) diff --git a/env_v3.py b/env_v3.py index a3132e3f4a..44a0965753 100644 --- a/env_v3.py +++ b/env_v3.py @@ -167,6 +167,8 @@ # RSA KEYS, 保存的是密钥的base64加密形式, 使用base64.b64encode(KEY.encode("utf-8"))进行处理后保存为环境变量 RSA_PRIV_KEY = os.getenv("BKAPP_RSA_PRIV_KEY", None) RSA_PUB_KEY = os.getenv("BKAPP_RSA_PUB_KEY", None) +SM2_PRIV_KEY = os.getenv("BKAPP_SM2_PRIV_KEY", None) +SM2_PUB_KEY = os.getenv("BKAPP_SM2_PUB_KEY", None) # 单业务下最大周期任务数量 PERIODIC_TASK_PROJECT_MAX_NUMBER = int(os.getenv("BKAPP_PERIODIC_TASK_PROJECT_MAX_NUMBER", 50)) diff --git a/frontend/desktop/src/assets/html/index-dev.html b/frontend/desktop/src/assets/html/index-dev.html index 3723ea0d09..27058461c2 100644 --- a/frontend/desktop/src/assets/html/index-dev.html +++ b/frontend/desktop/src/assets/html/index-dev.html @@ -32,6 +32,9 @@ // 是否开启导入 V1 模板的入口 var IMPORT_V1_FLAG = Number('0'); var RSA_PUB_KEY = ''; + var ASYMMETRIC_CIPHER_TYPE = ''; + var ASYMMETRIC_PUBLIC_KEY = ''; + var ASYMMETRIC_PREFIX = ''; var APP_CODE = 'bk_sops'; var FILE_UPLOAD_ENTRY = '/package/upload/'; var MAX_NODE_EXECUTE_TIMEOUT = 6000; diff --git a/frontend/desktop/src/assets/html/index.html b/frontend/desktop/src/assets/html/index.html index f0ef4bcb16..829cbe110d 100644 --- a/frontend/desktop/src/assets/html/index.html +++ b/frontend/desktop/src/assets/html/index.html @@ -42,6 +42,9 @@ // 是否开启导入 V1 模板的入口 var IMPORT_V1_FLAG ={{import_v1_flag}}; var RSA_PUB_KEY = '{{RSA_PUB_KEY}}'; + var ASYMMETRIC_CIPHER_TYPE = '{{ASYMMETRIC_CIPHER_TYPE}}'; + var ASYMMETRIC_PUBLIC_KEY = '{{ASYMMETRIC_PUBLIC_KEY}}'; + var ASYMMETRIC_PREFIX = '{{ASYMMETRIC_PREFIX}}'; var APP_CODE = '{{APP_CODE}}'; var FILE_UPLOAD_ENTRY = '{{FILE_UPLOAD_ENTRY}}'; var MEMBER_SELECTOR_DATA_HOST = '{{MEMBER_SELECTOR_DATA_HOST}}'; diff --git a/gcloud/core/context_processors.py b/gcloud/core/context_processors.py index c3d1720bc1..e7b14a986a 100644 --- a/gcloud/core/context_processors.py +++ b/gcloud/core/context_processors.py @@ -13,9 +13,10 @@ context_processor for common(setting) ** 除setting外的其他context_processor内容,均采用组件的方式(string) """ - +import json import logging +from bkcrypto.asymmetric.configs import KeyConfig as AsymmetricKeyConfig from django.utils.translation import ugettext_lazy as _ import env @@ -23,6 +24,7 @@ from gcloud.core.api_adapter import is_user_auditor, is_user_functor from gcloud.core.models import EnvironmentVariables from gcloud.core.project import get_default_project_for_user +from gcloud.utils.crypto import get_default_asymmetric_key_config logger = logging.getLogger("root") @@ -56,6 +58,9 @@ def mysetting(request): project_timezone = request.session.get("blueking_timezone", settings.TIME_ZONE) cur_pos = get_cur_pos_from_url(request) frontend_entry_url = "{}bk_sops".format(settings.STATIC_URL) if settings.RUN_VER == "open" else "/static/bk_sops" + default_asymmetric_key_config: AsymmetricKeyConfig = get_default_asymmetric_key_config( + settings.BKCRYPTO_ASYMMETRIC_CIPHER_TYPE + ) ctx = { "MEDIA_URL": settings.MEDIA_URL, # MEDIA_URL "STATIC_URL": settings.STATIC_URL, # 本地静态文件访问 @@ -90,6 +95,10 @@ def mysetting(request): "NICK": request.user.username, # 用户昵称 "AVATAR": request.session.get("avatar", ""), # 用户头像 "CUR_POS": cur_pos, + "ASYMMETRIC_CIPHER_TYPE": settings.BKCRYPTO_ASYMMETRIC_CIPHER_TYPE, + "ASYMMETRIC_PUBLIC_KEY": json.dumps(default_asymmetric_key_config.public_key_string)[1:-1], + "ASYMMETRIC_PREFIX": f"{settings.BKCRYPTO_ASYMMETRIC_CIPHER_TYPE.lower()}_str:::", + # TODO 等待移除 "RSA_PUB_KEY": settings.RSA_PUB_KEY, "STATIC_VER": settings.STATIC_VER[settings.RUN_MODE], "import_v1_flag": 1 if settings.IMPORT_V1_TEMPLATE_FLAG else 0, diff --git a/gcloud/utils/crypto.py b/gcloud/utils/crypto.py index b50266cbde..822a44446d 100644 --- a/gcloud/utils/crypto.py +++ b/gcloud/utils/crypto.py @@ -11,10 +11,44 @@ specific language governing permissions and limitations under the License. """ import base64 +import json +from bkcrypto import constants as crypto_constants +from bkcrypto.asymmetric.configs import KeyConfig as AsymmetricKeyConfig +from Crypto import Util from Crypto.Cipher import PKCS1_v1_5 as PKCS1_v1_5_cipher from Crypto.PublicKey import RSA -from Crypto import Util +from django.conf import settings + + +def get_default_asymmetric_key_config(cipher_type: str) -> AsymmetricKeyConfig: + """ + 获取项目默认非对称加密配置 + :param cipher_type: + :return: + """ + + if cipher_type == crypto_constants.AsymmetricCipherType.SM2.value: + private_key_string: str = settings.SM2_PRIV_KEY + public_key_string: str = json.loads(f'"{settings.SM2_PUB_KEY}"') + elif cipher_type == crypto_constants.AsymmetricCipherType.RSA.value: + private_key_string: str = settings.RSA_PRIV_KEY + public_key_string: str = json.loads(f'"{settings.RSA_PUB_KEY}"') + else: + raise NotImplementedError(f"cipher_type -> {cipher_type}") + + return AsymmetricKeyConfig( + private_key_string=private_key_string.strip("\n"), public_key_string=public_key_string.strip("\n") + ) + + +def get_nodeman_asymmetric_key_config(cipher_type: str) -> AsymmetricKeyConfig: + """ + 获取节点管理非对称加密配置 + :param cipher_type: + :return: + """ + pass def _get_block_size(key_obj, is_encrypt=True) -> int: @@ -68,6 +102,7 @@ def decrypt_auth_key(encrypt_message, private_key): @param private_key: rsa私钥 @return: 解密后的信息 """ + # TODO 要改的 decrypt_message_bytes = b"" private_key_obj = RSA.importKey(private_key.strip("\n")) encrypt_message_bytes = base64.b64decode(encrypt_message) diff --git a/pipeline_plugins/components/static/components/atoms/nodeman/create_task/v4_0.js b/pipeline_plugins/components/static/components/atoms/nodeman/create_task/v4_0.js index d0457cf9bf..cd1f2d3668 100644 --- a/pipeline_plugins/components/static/components/atoms/nodeman/create_task/v4_0.js +++ b/pipeline_plugins/components/static/components/atoms/nodeman/create_task/v4_0.js @@ -502,6 +502,8 @@ { tag_code: "auth_key", type: "textarea", + // TODO 能不能加一个动态选项?如果具有加密前缀,默认展示 * 脱敏 + // TODO 如果重新输入保存,可以拉公钥去做加密 attrs: { name: gettext("认证密钥"), width: "400px", diff --git a/pipeline_plugins/components/utils/common.py b/pipeline_plugins/components/utils/common.py index eb29058bea..35a15c8ccd 100644 --- a/pipeline_plugins/components/utils/common.py +++ b/pipeline_plugins/components/utils/common.py @@ -11,15 +11,13 @@ specific language governing permissions and limitations under the License. """ import logging +import random import re import time -import random from copy import deepcopy from django.utils.translation import ugettext_lazy as _ -from pipeline.conf import settings -from pipeline.utils.crypt import rsa_decrypt_password from api.utils.thread import ThreadPool logger = logging.getLogger("root") @@ -43,18 +41,6 @@ def loose_strip(data): return data -def try_decrypt_password(password): - """ - @summary: 尝试解密操作,成功返回明文密码,错误则说明用户使用明文的密码,返回 - @param password: - @return: - """ - try: - return rsa_decrypt_password(password, settings.RSA_PRIV_KEY) - except Exception: - return password - - def chunk_table_data(column_dict, break_line): """ @summary: 表格参数值支持以break_line为分隔符分隔的多条数据,对一行数据,当有一列有多条数据时(包含换行符),其他列要么也有相等个数的 diff --git a/pipeline_plugins/variables/collections/common.py b/pipeline_plugins/variables/collections/common.py index 4e8d6494b7..1090af6caa 100644 --- a/pipeline_plugins/variables/collections/common.py +++ b/pipeline_plugins/variables/collections/common.py @@ -12,23 +12,23 @@ """ import datetime -import logging import json +import logging from typing import List from django.conf import settings -from django.utils.translation import ugettext_lazy as _ from django.utils import timezone +from django.utils.translation import ugettext_lazy as _ +from pipeline.core.data.var import LazyVariable, RegisterVariableMeta, SpliceVariable +from pipeline.core.flow.io import IntItemSchema, StringItemSchema +from gcloud.conf import settings as gcloud_settings from gcloud.constants import Type from gcloud.core.models import StaffGroupSet from gcloud.exceptions import ApiRequestError from gcloud.utils.cmdb import get_notify_receivers -from gcloud.conf import settings as gcloud_settings -from pipeline.core.data.var import SpliceVariable, LazyVariable, RegisterVariableMeta -from pipeline.core.flow.io import StringItemSchema, IntItemSchema from pipeline_plugins.base.utils.inject import supplier_account_for_business -from pipeline_plugins.variables.base import SelfExplainVariable, FieldExplain +from pipeline_plugins.variables.base import FieldExplain, SelfExplainVariable logger = logging.getLogger("root") get_client_by_user = gcloud_settings.ESB_GET_CLIENT_BY_USER @@ -92,6 +92,7 @@ def _self_explain(cls, **kwargs) -> List[FieldExplain]: class Password(LazyVariable, SelfExplainVariable): + # TODO 需要改的 code = "password" name = _("密码") type = "general" diff --git a/requirements.txt b/requirements.txt index 48efaa1641..4959f8957d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,6 +19,7 @@ django-nose==1.4.5 coverage==4.5.1 python-magic==0.4.15 cryptography==3.3.2 +bk-crypto-python-sdk==1.0.4 gitdb2==2.0.6 GitPython==2.1.11 PyJWT==1.7.1 From b985013d92c595e83dd922374280b6f62a1597c0 Mon Sep 17 00:00:00 2001 From: Luo Fan <44999219+luofann@users.noreply.github.com> Date: Fri, 4 Aug 2023 17:42:40 +0800 Subject: [PATCH 02/17] =?UTF-8?q?feature:=20=E6=A0=87=E5=87=86=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=89=8D=E7=AB=AF=E5=9B=BD=E5=AF=86=E6=94=B9=E9=80=A0?= =?UTF-8?q?=20(#6965)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/develop/tag_usage_dev.md | 1 + en_docs/develop/tag_usage_dev.md | 2 + frontend/desktop/package.json | 3 +- .../components/common/RenderForm/FormItem.vue | 10 +- .../common/RenderForm/RenderForm.vue | 10 +- .../common/RenderForm/tags/TagPassword.vue | 197 +++++++++++++----- frontend/desktop/src/config/i18n/cn.js | 4 +- frontend/desktop/src/config/i18n/en.js | 4 +- frontend/desktop/src/store/index.js | 1 - 9 files changed, 177 insertions(+), 55 deletions(-) diff --git a/docs/develop/tag_usage_dev.md b/docs/develop/tag_usage_dev.md index 2c43424dab..2f1451f674 100644 --- a/docs/develop/tag_usage_dev.md +++ b/docs/develop/tag_usage_dev.md @@ -313,6 +313,7 @@ ip 选择器,支持静态 ip 或动态 ip 的单选和多选。 - `pubKey`: 加密公钥 - `disabled`:设置是否禁用组件 + - `canUseVar`: 是否可以使用全局变量,默认为true - `value`:加密后的密码值 **方法** diff --git a/en_docs/develop/tag_usage_dev.md b/en_docs/develop/tag_usage_dev.md index c79e80508f..cc9649b9a7 100644 --- a/en_docs/develop/tag_usage_dev.md +++ b/en_docs/develop/tag_usage_dev.md @@ -313,7 +313,9 @@ Password input box. **Attributes** + - `pubKey`: crypto public key - `disabled`: set whether this component is disabled. + - `canUseVar`: whether global variables can be used, which defaults to true - `value`: the encrypted password value **Methods** diff --git a/frontend/desktop/package.json b/frontend/desktop/package.json index 3fff3b3e8f..475b52a17d 100644 --- a/frontend/desktop/package.json +++ b/frontend/desktop/package.json @@ -12,8 +12,9 @@ "license": "ISC", "dependencies": { "@blueking/bkcharts": "^2.0.11-alpha.5", - "@blueking/user-selector": "^1.0.5-beta.2", "@blueking/bkui-form": "0.0.35", + "@blueking/crypto-js-sdk": "0.0.5", + "@blueking/user-selector": "^1.0.5-beta.2", "@vue/babel-preset-jsx": "^1.3.0", "ajv": "^6.10.2", "art-template": "^4.13.0", diff --git a/frontend/desktop/src/components/common/RenderForm/FormItem.vue b/frontend/desktop/src/components/common/RenderForm/FormItem.vue index da957c04b7..92a8f2a1f5 100644 --- a/frontend/desktop/src/components/common/RenderForm/FormItem.vue +++ b/frontend/desktop/src/components/common/RenderForm/FormItem.vue @@ -369,7 +369,6 @@ case 'radio': case 'text': case 'datetime': - case 'password': case 'memberSelector': case 'logDisplay': case 'code_editor': @@ -465,6 +464,15 @@ } } break + case 'password': + valueFormat = { + type: ['String', 'Object'], + value: { + tag: 'value', + value: '' + } + } + break default: valueFormat = { type: 'String', diff --git a/frontend/desktop/src/components/common/RenderForm/RenderForm.vue b/frontend/desktop/src/components/common/RenderForm/RenderForm.vue index 0a6a6467c6..8404f68c22 100644 --- a/frontend/desktop/src/components/common/RenderForm/RenderForm.vue +++ b/frontend/desktop/src/components/common/RenderForm/RenderForm.vue @@ -233,7 +233,6 @@ case 'radio': case 'text': case 'datetime': - case 'password': case 'member_selector': case 'section': case 'code_editor': @@ -291,6 +290,15 @@ separator: ',' } break + case 'password': + val = { + type: 'object', + value: { + tag: 'value', + value: '' + } + } + break default: val = '' } diff --git a/frontend/desktop/src/components/common/RenderForm/tags/TagPassword.vue b/frontend/desktop/src/components/common/RenderForm/tags/TagPassword.vue index 23a4efe4ff..863b55d139 100644 --- a/frontend/desktop/src/components/common/RenderForm/tags/TagPassword.vue +++ b/frontend/desktop/src/components/common/RenderForm/tags/TagPassword.vue @@ -11,25 +11,32 @@ */ - + diff --git a/frontend/desktop/src/config/i18n/cn.js b/frontend/desktop/src/config/i18n/cn.js index a25f04a413..eea6b3c4d1 100644 --- a/frontend/desktop/src/config/i18n/cn.js +++ b/frontend/desktop/src/config/i18n/cn.js @@ -1749,7 +1749,9 @@ const cn = { '添加默认方案成功': '添加默认方案成功', '取消默认方案成功': '取消默认方案成功', '确认删除执行方案【n】?': '确认删除执行方案【{n}】?', - '取消设为默认方案': '取消设为默认方案' + '取消设为默认方案': '取消设为默认方案', + 'password_手动输入': '手动输入', + 'password_使用密码变量': '使用密码变量' } export default cn diff --git a/frontend/desktop/src/config/i18n/en.js b/frontend/desktop/src/config/i18n/en.js index 87da068c89..cb6a2d0e6f 100644 --- a/frontend/desktop/src/config/i18n/en.js +++ b/frontend/desktop/src/config/i18n/en.js @@ -1782,7 +1782,9 @@ const en = { '添加默认方案成功': 'Default Node-Group Added', '取消默认方案成功': 'Default Node-Group Cancelled', '确认删除执行方案【n】?': 'Confirm to delete node-group [ {n} ] ?', - '取消设为默认方案': 'Unset as Default' + '取消设为默认方案': 'Unset as Default', + 'password_手动输入': 'custom input', + 'password_使用密码变量': 'use password var.' } export default en diff --git a/frontend/desktop/src/store/index.js b/frontend/desktop/src/store/index.js index 81ead32516..06c684759b 100644 --- a/frontend/desktop/src/store/index.js +++ b/frontend/desktop/src/store/index.js @@ -38,7 +38,6 @@ const store = new Vuex.Store({ components: [], isSuperUser: window.IS_SUPERUSER === 1, v1_import_flag: window.IMPORT_V1_FLAG, - rsa_pub_key: window.RSA_PUB_KEY, permissionMeta: { system: [], resources: [], From f15b60387af76c56bfb0d12b813a5771a60f11aa Mon Sep 17 00:00:00 2001 From: luofann Date: Mon, 14 Aug 2023 11:49:58 +0800 Subject: [PATCH 03/17] =?UTF-8?q?optimization:=20password=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E6=94=AF=E6=8C=81texarea=E6=A8=A1=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/develop/tag_usage_dev.md | 1 + en_docs/develop/tag_usage_dev.md | 1 + .../common/RenderForm/RenderForm.vue | 7 +- .../common/RenderForm/tags/TagPassword.vue | 66 +++++++++++++++---- 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/docs/develop/tag_usage_dev.md b/docs/develop/tag_usage_dev.md index 2f1451f674..91d69ab65f 100644 --- a/docs/develop/tag_usage_dev.md +++ b/docs/develop/tag_usage_dev.md @@ -314,6 +314,7 @@ ip 选择器,支持静态 ip 或动态 ip 的单选和多选。 - `pubKey`: 加密公钥 - `disabled`:设置是否禁用组件 - `canUseVar`: 是否可以使用全局变量,默认为true + - `textareaMode`: 手动输入密码时,表单类型为textarea,默认为false - `value`:加密后的密码值 **方法** diff --git a/en_docs/develop/tag_usage_dev.md b/en_docs/develop/tag_usage_dev.md index cc9649b9a7..2d0568e069 100644 --- a/en_docs/develop/tag_usage_dev.md +++ b/en_docs/develop/tag_usage_dev.md @@ -316,6 +316,7 @@ Password input box. - `pubKey`: crypto public key - `disabled`: set whether this component is disabled. - `canUseVar`: whether global variables can be used, which defaults to true + - `textareaMode`: When entering a password manually, the form type is textarea and the default is false - `value`: the encrypted password value **Methods** diff --git a/frontend/desktop/src/components/common/RenderForm/RenderForm.vue b/frontend/desktop/src/components/common/RenderForm/RenderForm.vue index 8404f68c22..07aff3fa97 100644 --- a/frontend/desktop/src/components/common/RenderForm/RenderForm.vue +++ b/frontend/desktop/src/components/common/RenderForm/RenderForm.vue @@ -292,11 +292,8 @@ break case 'password': val = { - type: 'object', - value: { - tag: 'value', - value: '' - } + tag: 'value', + value: '' } break default: diff --git a/frontend/desktop/src/components/common/RenderForm/tags/TagPassword.vue b/frontend/desktop/src/components/common/RenderForm/tags/TagPassword.vue index 863b55d139..4f77febd5c 100644 --- a/frontend/desktop/src/components/common/RenderForm/tags/TagPassword.vue +++ b/frontend/desktop/src/components/common/RenderForm/tags/TagPassword.vue @@ -16,15 +16,28 @@ - + @@ -51,6 +64,11 @@ required: false, default: true }, + textareaMode: { + type: Boolean, + required: false, + default: false + }, disabled: { type: Boolean, required: false, @@ -125,6 +143,12 @@ this.localVal.value = e.target.value this.inputPlaceholder = '' }, + handleTextareaInput (e) { + console.log('textarea input: ', e.target.value) + this.localVal.value = e.target.value + this.inputPlaceholder = '' + e.target.value = e.target.value.replace(/[^\n]/g, '·') + }, handleFocus () { if (this.localVal.value.length > 0) { this.inputPlaceholder = i18n.t('要修改密码请点击后重新输入密码') @@ -135,7 +159,7 @@ }, // 输入框失焦后执行加密逻辑 handleBlur () { - this.inputText = this.localVal.value + this.inputText = this.textareaMode ? this.localVal.value.replace(/[^\n]/g, '·') : this.localVal.value const encryptedVal = this.encryptPassword() this.localVal.value = encryptedVal this.change() @@ -171,7 +195,7 @@