From 5139f9c4b9b39152b71ec602b315d18a1f37b93e Mon Sep 17 00:00:00 2001 From: jiangweidong Date: Tue, 14 Dec 2021 17:13:24 +0800 Subject: [PATCH 01/10] =?UTF-8?q?feat:=20saml2=E8=AE=A4=E8=AF=81=E6=94=AF?= =?UTF-8?q?=E6=8C=81https=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/backends/saml2/views.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/authentication/backends/saml2/views.py b/apps/authentication/backends/saml2/views.py index 9841fcd1d..f1affb8af 100644 --- a/apps/authentication/backends/saml2/views.py +++ b/apps/authentication/backends/saml2/views.py @@ -1,5 +1,7 @@ import copy +from urllib import parse + from django.views import View from django.contrib import auth as auth from django.urls import reverse @@ -23,9 +25,13 @@ logger = get_logger(__file__) class PrepareRequestMixin: @staticmethod - def prepare_django_request(request): + def is_secure(): + url_result = parse.urlparse(settings.SITE_URL) + return 'on' if url_result.scheme == 'https' else 'off' + + def prepare_django_request(self, request): result = { - 'https': 'on' if request.is_secure() else 'off', + 'https': self.is_secure(), 'http_host': request.META['HTTP_HOST'], 'script_name': request.META['PATH_INFO'], 'get_data': request.GET.copy(), From fa5c433c7c6fdae08d09e60b4cf9e8b6a048a8f4 Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 14 Dec 2021 17:03:08 +0800 Subject: [PATCH 02/10] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E8=84=9A=E6=9C=AC=EF=BC=8C=E9=81=BF=E5=85=8D=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E8=B6=85=E6=97=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../commands/services/services/base.py | 2 +- jms | 116 +++++++++--------- 2 files changed, 57 insertions(+), 61 deletions(-) diff --git a/apps/common/management/commands/services/services/base.py b/apps/common/management/commands/services/services/base.py index 0fb6cb1b3..7b36c9723 100644 --- a/apps/common/management/commands/services/services/base.py +++ b/apps/common/management/commands/services/services/base.py @@ -170,7 +170,7 @@ class BaseService(object): def _restart(self): if self.retry > self.max_retry: - logging.info("Service start failed, exit: ", self.name) + logging.info("Service start failed, exit: {}".format(self.name)) self.EXIT_EVENT.set() return self.retry += 1 diff --git a/jms b/jms index 9c36788c3..f67bff662 100755 --- a/jms +++ b/jms @@ -2,20 +2,27 @@ # coding: utf-8 import os -import subprocess import logging import logging.handlers import time import argparse import sys +import django +from django.core import management +from django.db.utils import OperationalError BASE_DIR = os.path.dirname(os.path.abspath(__file__)) -sys.path.insert(0, BASE_DIR) +APP_DIR = os.path.join(BASE_DIR, 'apps') + +os.chdir(APP_DIR) +sys.path.insert(0, APP_DIR) +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "jumpserver.settings") +django.setup() logging.basicConfig(level=logging.DEBUG, format="%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S") try: - from apps.jumpserver import const + from jumpserver import const __version__ = const.VERSION except ImportError as e: print("Not found __version__: {}".format(e)) @@ -25,7 +32,7 @@ except ImportError as e: sys.exit(1) try: - from apps.jumpserver.const import CONFIG + from jumpserver.const import CONFIG except ImportError as e: print("Import error: {}".format(e)) print("Could not find config file, `cp config_example.yml config.yml`") @@ -48,56 +55,45 @@ except: def check_database_connection(): - os.chdir(os.path.join(BASE_DIR, 'apps')) for i in range(60): - logging.info("Check database connection ...") - _code = subprocess.call("python manage.py showmigrations users ", shell=True) - if _code == 0: + logging.info(f"Check database connection: {i}") + try: + management.call_command('check', '--database', 'default') logging.info("Database connect success") return + except OperationalError: + logging.info('Database not setup, retry') + except Exception as e: + logging.error('Unexpect error occur: {}'.format(str(e))) time.sleep(1) logging.error("Connection database failed, exit") sys.exit(10) -def check_migrations(): - _apps_dir = os.path.join(BASE_DIR, 'apps') - _cmd = "python manage.py showmigrations | grep '\[.\]' | grep -v '\[X\]'" - _code = subprocess.call(_cmd, shell=True, cwd=_apps_dir) - - if _code == 1: - return - # for i in range(3): - # print("!!! Warning: Has SQL migrations not perform, 有 SQL 变更没有执行") - # print("You should run `./PROC upgrade_db` first, 请先运行 ./PROC upgrade_db, 进行表结构变更") - # sys.exit(1) - - def expire_caches(): - _apps_dir = os.path.join(BASE_DIR, 'apps') - _code = subprocess.call("python manage.py expire_caches", shell=True, cwd=_apps_dir) - - if _code == 1: - return + try: + management.call_command('expire_caches') + except: + pass def perform_db_migrate(): logging.info("Check database structure change ...") - os.chdir(os.path.join(BASE_DIR, 'apps')) logging.info("Migrate model change to database ...") - _code = subprocess.call('python3 manage.py migrate', shell=True) - if _code == 0: - return - logging.error('Perform migrate failed, exit') - sys.exit(11) + try: + management.call_command('migrate') + except Exception: + logging.error('Perform migrate failed, exit') + sys.exit(11) def collect_static(): logging.info("Collect static files") - os.chdir(os.path.join(BASE_DIR, 'apps')) - _cmd = 'python3 manage.py collectstatic --no-input -c &> /dev/null ' - subprocess.call(_cmd, shell=True) - logging.info("Collect static files done") + try: + management.call_command('collectstatic', '--no-input', '-c', verbosity=0, interactive=False) + logging.info("Collect static files done") + except: + pass def compile_i81n_file(): @@ -105,8 +101,7 @@ def compile_i81n_file(): if os.path.exists(django_mo_file): return os.chdir(os.path.join(BASE_DIR, 'apps')) - _cmd = 'python3 manage.py compilemessages --no-input -c &> /dev/null ' - subprocess.call(_cmd, shell=True) + management.call_command('compilemessages', verbosity=0, interactive=False) logging.info("Compile i18n files done") @@ -116,13 +111,33 @@ def upgrade_db(): def prepare(): - # installer(check) & k8s(no check) check_database_connection() - check_migrations() upgrade_db() expire_caches() +def start_services(): + services = args.services if isinstance(args.services, list) else [args.services] + if action == 'start' and {'all', 'web'} & set(services): + prepare() + + services_string = ' '.join(services) + cmd = f'{args.action} {services_string}' + if args.daemon: + cmd += ' --daemon' + if args.worker: + cmd += f' --worker {args.worker}' + if args.force: + cmd += ' --force' + + lines = cmd.split() + try: + management.call_command(*lines) + except Exception as e: + logging.error("Start service error {}: {}".format(lines[0], e)) + time.sleep(2) + + if __name__ == '__main__': parser = argparse.ArgumentParser( description=""" @@ -155,23 +170,4 @@ if __name__ == '__main__': elif action == "collect_static": collect_static() else: - services = args.services if isinstance(args.services, list) else [args.services] - if action == 'start' and {'all', 'web'} & set(services): - prepare() - - services_string = ' '.join(services) - cmd = f'python manage.py {args.action} {services_string}' - if args.daemon: - cmd += ' --daemon' - if args.worker: - cmd += f' --worker {args.worker}' - if args.force: - cmd += ' --force' - apps_dir = os.path.join(BASE_DIR, 'apps') - - try: - # processes: main(3s) -> call(0.25s) -> service -> sub-process - code = subprocess.call(cmd, shell=True, cwd=apps_dir) - except KeyboardInterrupt: - time.sleep(2) - pass + start_services() From 0020343ae069ec5bd539b8a2479ac3462deec86a Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 14 Dec 2021 17:41:53 +0800 Subject: [PATCH 03/10] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E8=BF=90?= =?UTF-8?q?=E8=A1=8C=E7=9A=84=E5=91=BD=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jms | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/jms b/jms index f67bff662..cf69a0348 100755 --- a/jms +++ b/jms @@ -121,20 +121,21 @@ def start_services(): if action == 'start' and {'all', 'web'} & set(services): prepare() - services_string = ' '.join(services) - cmd = f'{args.action} {services_string}' + start_args = [] if args.daemon: - cmd += ' --daemon' + start_args.append('--daemon') if args.worker: - cmd += f' --worker {args.worker}' + start_args.extend(['--worker', str(args.worker)]) if args.force: - cmd += ' --force' + start_args.append('--force') - lines = cmd.split() try: - management.call_command(*lines) + management.call_command(action, *services, *start_args) + except KeyboardInterrupt: + logging.info('Cancel ...') + time.sleep(2) except Exception as e: - logging.error("Start service error {}: {}".format(lines[0], e)) + logging.error("Start service error {}: {}".format(services, e)) time.sleep(2) From 19ecc7fef62586e78f8aa3ff1f6d42c02cb519ec Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 14 Dec 2021 11:10:32 +0800 Subject: [PATCH 04/10] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=20otp=20?= =?UTF-8?q?=E8=BF=94=E5=9B=9E=E6=97=B6=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/users/views/profile/otp.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/users/views/profile/otp.py b/apps/users/views/profile/otp.py index b26af285a..fec3055e6 100644 --- a/apps/users/views/profile/otp.py +++ b/apps/users/views/profile/otp.py @@ -39,7 +39,8 @@ class UserOtpEnableStartView(AuthMixin, TemplateView): try: self.get_user_from_session() except SessionEmptyError: - return redirect('authentication:login') + '?_=otp_enable_start' + url = reverse('authentication:login') + '?_=otp_enable_start' + return redirect(url) return super().get(request, *args, **kwargs) @@ -72,8 +73,8 @@ class UserOtpEnableBindView(AuthMixin, TemplateView, FormView): def _pre_check_can_bind(self): try: user = self.get_user_from_session() - except: - verify_url = reverse('authentication:user-otp-enable-start') + except Exception as e: + verify_url = reverse('authentication:user-otp-enable-start') + f'?e={e}' return HttpResponseRedirect(verify_url) if user.otp_secret_key: From 0c2e5f3f2a55994b190fea7bb28ef502f8fbf97f Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 14 Dec 2021 17:57:39 +0800 Subject: [PATCH 05/10] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20saml2=20i18n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/locale/zh/LC_MESSAGES/django.po | 90 +++++++++++++------------ apps/settings/serializers/auth/saml2.py | 10 +-- 2 files changed, 53 insertions(+), 47 deletions(-) diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index 32096ba67..7a2257f19 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: JumpServer 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2021-12-09 20:32+0800\n" +"POT-Creation-Date: 2021-12-14 17:54+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -343,7 +343,7 @@ msgstr "类别名称" #: perms/serializers/application/permission.py:17 #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:33 #: tickets/serializers/ticket/ticket.py:22 -#: tickets/serializers/ticket/ticket.py:168 +#: tickets/serializers/ticket/ticket.py:169 msgid "Type display" msgstr "类型名称" @@ -384,10 +384,10 @@ msgstr "应用路径" #: applications/serializers/attrs/application_category/remote_app.py:45 #: assets/serializers/system_user.py:159 -#: xpack/plugins/change_auth_plan/serializers/asset.py:65 -#: xpack/plugins/change_auth_plan/serializers/asset.py:68 -#: xpack/plugins/change_auth_plan/serializers/asset.py:71 -#: xpack/plugins/change_auth_plan/serializers/asset.py:87 +#: xpack/plugins/change_auth_plan/serializers/asset.py:64 +#: xpack/plugins/change_auth_plan/serializers/asset.py:67 +#: xpack/plugins/change_auth_plan/serializers/asset.py:70 +#: xpack/plugins/change_auth_plan/serializers/asset.py:101 #: xpack/plugins/cloud/serializers/account_attrs.py:52 msgid "This field is required." msgstr "该字段是必填项。" @@ -586,6 +586,7 @@ msgid "Ok" msgstr "成功" #: assets/models/base.py:32 audits/models.py:102 +#: xpack/plugins/change_auth_plan/task_handlers/base/manager.py:121 #: xpack/plugins/cloud/const.py:29 msgid "Failed" msgstr "失败" @@ -1169,6 +1170,7 @@ msgid "Filename" msgstr "文件名" #: audits/models.py:42 audits/models.py:101 terminal/models/sharing.py:84 +#: xpack/plugins/change_auth_plan/task_handlers/base/manager.py:119 msgid "Success" msgstr "成功" @@ -1326,12 +1328,12 @@ msgstr "" msgid "Auth Token" msgstr "认证令牌" -#: audits/signals_handler.py:68 authentication/views/login.py:183 +#: audits/signals_handler.py:68 authentication/views/login.py:164 #: notifications/backends/__init__.py:11 users/models/user.py:607 msgid "WeCom" msgstr "企业微信" -#: audits/signals_handler.py:69 authentication/views/login.py:189 +#: audits/signals_handler.py:69 authentication/views/login.py:170 #: notifications/backends/__init__.py:12 users/models/user.py:608 msgid "DingTalk" msgstr "钉钉" @@ -1899,7 +1901,7 @@ msgstr "代码错误" #: authentication/templates/authentication/_msg_reset_password.html:3 #: authentication/templates/authentication/_msg_rest_password_success.html:2 #: authentication/templates/authentication/_msg_rest_public_key_success.html:2 -#: jumpserver/conf.py:282 +#: jumpserver/conf.py:293 #: perms/templates/perms/_msg_item_permissions_expire.html:3 #: perms/templates/perms/_msg_permed_items_expire.html:3 #: users/templates/users/_msg_account_expire_reminder.html:4 @@ -2107,24 +2109,24 @@ msgstr "没有绑定飞书" msgid "Please login with a password and then bind the FeiShu" msgstr "请使用密码登录,然后绑定飞书" -#: authentication/views/login.py:89 +#: authentication/views/login.py:70 msgid "Redirecting" msgstr "跳转中" -#: authentication/views/login.py:90 +#: authentication/views/login.py:71 msgid "Redirecting to {} authentication" msgstr "正在跳转到 {} 认证" -#: authentication/views/login.py:116 +#: authentication/views/login.py:94 msgid "Please enable cookies and try again." msgstr "设置你的浏览器支持cookie" -#: authentication/views/login.py:195 notifications/backends/__init__.py:14 +#: authentication/views/login.py:176 notifications/backends/__init__.py:14 #: users/models/user.py:609 msgid "FeiShu" msgstr "飞书" -#: authentication/views/login.py:284 +#: authentication/views/login.py:265 msgid "" "Wait for {} confirm, You also can copy link to her/him
\n" " Don't close this page" @@ -2132,15 +2134,15 @@ msgstr "" "等待 {} 确认, 你也可以复制链接发给他/她
\n" " 不要关闭本页面" -#: authentication/views/login.py:289 +#: authentication/views/login.py:270 msgid "No ticket found" msgstr "没有发现工单" -#: authentication/views/login.py:323 +#: authentication/views/login.py:304 msgid "Logout success" msgstr "退出登录成功" -#: authentication/views/login.py:324 +#: authentication/views/login.py:305 msgid "Logout success, return login page" msgstr "退出登录成功,返回到登录页面" @@ -2339,11 +2341,11 @@ msgstr "不能包含特殊字符" msgid "The mobile phone number format is incorrect" msgstr "手机号格式不正确" -#: jumpserver/conf.py:281 +#: jumpserver/conf.py:292 msgid "Create account successfully" msgstr "创建账户成功" -#: jumpserver/conf.py:283 +#: jumpserver/conf.py:294 msgid "Your account has been created successfully" msgstr "你的账户已创建成功" @@ -2859,7 +2861,7 @@ msgstr "服务端地址" msgid "Proxy server url" msgstr "回调地址" -#: settings/serializers/auth/cas.py:14 settings/serializers/auth/saml2.py:29 +#: settings/serializers/auth/cas.py:14 settings/serializers/auth/saml2.py:32 msgid "Logout completely" msgstr "同步注销" @@ -2871,7 +2873,7 @@ msgstr "用户名属性" msgid "Enable attributes map" msgstr "启用属性映射" -#: settings/serializers/auth/cas.py:18 settings/serializers/auth/saml2.py:28 +#: settings/serializers/auth/cas.py:18 settings/serializers/auth/saml2.py:31 msgid "Rename attr" msgstr "映射属性" @@ -3031,7 +3033,7 @@ msgstr "使用状态" msgid "Use nonce" msgstr "临时使用" -#: settings/serializers/auth/oidc.py:76 settings/serializers/auth/saml2.py:30 +#: settings/serializers/auth/oidc.py:76 settings/serializers/auth/saml2.py:33 msgid "Always update user" msgstr "总是更新用户信息" @@ -3048,20 +3050,24 @@ msgid "Enable SAML2 Auth" msgstr "启用 SAML2 认证" #: settings/serializers/auth/saml2.py:15 -msgid "IDP Metadata URL" +msgid "IDP metadata URL" msgstr "" #: settings/serializers/auth/saml2.py:18 -msgid "IDP Metadata XML" +msgid "IDP metadata XML" msgstr "" -#: settings/serializers/auth/saml2.py:22 -msgid "SP Private Key" -msgstr "" +#: settings/serializers/auth/saml2.py:21 +msgid "SP advanced settings" +msgstr "高级设置" -#: settings/serializers/auth/saml2.py:26 -msgid "SP Public Cert" -msgstr "" +#: settings/serializers/auth/saml2.py:25 +msgid "SP private key" +msgstr "SP 密钥" + +#: settings/serializers/auth/saml2.py:29 +msgid "SP cert" +msgstr "SP 证书" #: settings/serializers/auth/sms.py:10 msgid "Enable SMS" @@ -4784,11 +4790,11 @@ msgstr "内容" msgid "Approve level" msgstr "审批级别" -#: tickets/models/flow.py:25 tickets/serializers/ticket/ticket.py:140 +#: tickets/models/flow.py:25 tickets/serializers/ticket/ticket.py:141 msgid "Approve strategy" msgstr "审批策略" -#: tickets/models/flow.py:30 tickets/serializers/ticket/ticket.py:141 +#: tickets/models/flow.py:30 tickets/serializers/ticket/ticket.py:142 msgid "Assignees" msgstr "受理人" @@ -4876,7 +4882,7 @@ msgstr "申请的系统用户名称" #: tickets/serializers/ticket/meta/ticket_type/apply_application.py:71 #: tickets/serializers/ticket/meta/ticket_type/apply_asset.py:73 -#: tickets/serializers/ticket/ticket.py:127 +#: tickets/serializers/ticket/ticket.py:128 msgid "Permission named `{}` already exists" msgstr "授权名称 `{}` 已存在" @@ -4936,7 +4942,7 @@ msgid "From cmd filter" msgstr "来自命令过滤规则" #: tickets/serializers/ticket/meta/ticket_type/common.py:11 -#: tickets/serializers/ticket/ticket.py:122 +#: tickets/serializers/ticket/ticket.py:123 msgid "Created by ticket ({}-{})" msgstr "通过工单创建 ({}-{})" @@ -4962,15 +4968,15 @@ msgid "" "request url (`{}`)" msgstr "提交数据中的类型 (`{}`) 与请求URL地址中的类型 (`{}`) 不一致" -#: tickets/serializers/ticket/ticket.py:115 +#: tickets/serializers/ticket/ticket.py:116 msgid "The ticket flow `{}` does not exist" msgstr "工单流程 `{}` 不存在" -#: tickets/serializers/ticket/ticket.py:162 +#: tickets/serializers/ticket/ticket.py:163 msgid "Please select the Assignees" msgstr "请选择受理人" -#: tickets/serializers/ticket/ticket.py:188 +#: tickets/serializers/ticket/ticket.py:189 msgid "The current organization type already exists" msgstr "当前组织已存在该类型" @@ -5633,7 +5639,7 @@ msgid "Replace (The key generated by JumpServer) " msgstr "替换 (由 JumpServer 生成的密钥)" #: xpack/plugins/change_auth_plan/models/asset.py:50 -#: xpack/plugins/change_auth_plan/serializers/asset.py:34 +#: xpack/plugins/change_auth_plan/serializers/asset.py:33 msgid "SSH Key strategy" msgstr "SSH 密钥策略" @@ -5722,11 +5728,11 @@ msgstr "" "{} - 改密任务已完成: 未设置加密密码 - 请前往个人信息 -> 文件加密密码中设置加" "密密码" -#: xpack/plugins/change_auth_plan/serializers/asset.py:31 +#: xpack/plugins/change_auth_plan/serializers/asset.py:30 msgid "Change Password" msgstr "更改密码" -#: xpack/plugins/change_auth_plan/serializers/asset.py:32 +#: xpack/plugins/change_auth_plan/serializers/asset.py:31 msgid "Change SSH Key" msgstr "修改 SSH Key" @@ -5811,8 +5817,8 @@ msgid "Qingyun Private Cloud" msgstr "青云私有云" #: xpack/plugins/cloud/const.py:19 -msgid "OpenStack Cloud" -msgstr "OpenStack Cloud" +msgid "OpenStack" +msgstr "OpenStack" #: xpack/plugins/cloud/const.py:20 msgid "Google Cloud Platform" diff --git a/apps/settings/serializers/auth/saml2.py b/apps/settings/serializers/auth/saml2.py index ca102bf0e..d061c4936 100644 --- a/apps/settings/serializers/auth/saml2.py +++ b/apps/settings/serializers/auth/saml2.py @@ -12,21 +12,21 @@ class SAML2SettingSerializer(serializers.Serializer): default=False, required=False, label=_('Enable SAML2 Auth') ) SAML2_IDP_METADATA_URL = serializers.URLField( - allow_blank=True, required=False, label=_('IDP Metadata URL') + allow_blank=True, required=False, label=_('IDP metadata URL') ) SAML2_IDP_METADATA_XML = serializers.CharField( - allow_blank=True, required=False, label=_('IDP Metadata XML') + allow_blank=True, required=False, label=_('IDP metadata XML') ) SAML2_SP_ADVANCED_SETTINGS = serializers.JSONField( - required=False, label=_('SP ADVANCED SETTINGS') + required=False, label=_('SP advanced settings') ) SAML2_SP_KEY_CONTENT = serializers.CharField( allow_blank=True, required=False, - write_only=True, label=_('SP Private Key') + write_only=True, label=_('SP private key') ) SAML2_SP_CERT_CONTENT = serializers.CharField( allow_blank=True, required=False, - write_only=True, label=_('SP Public Cert') + write_only=True, label=_('SP cert') ) SAML2_RENAME_ATTRIBUTES = serializers.DictField(required=False, label=_('Rename attr')) SAML2_LOGOUT_COMPLETELY = serializers.BooleanField(required=False, label=_('Logout completely')) From 4f889cfe36d16dd86f1eb9d20af741ad4b64a0e4 Mon Sep 17 00:00:00 2001 From: xinwen Date: Tue, 14 Dec 2021 16:46:35 +0800 Subject: [PATCH 06/10] =?UTF-8?q?fix:=20=E5=B8=A6=20ad=5Fdomain=20?= =?UTF-8?q?=E7=9A=84=E7=B3=BB=E7=BB=9F=E7=94=A8=E6=88=B7=E4=B8=8D=E5=BA=94?= =?UTF-8?q?=E8=AF=A5=E6=94=AF=E6=8C=81=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/tasks/push_system_user.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/assets/tasks/push_system_user.py b/apps/assets/tasks/push_system_user.py index a741e173c..2be740eca 100644 --- a/apps/assets/tasks/push_system_user.py +++ b/apps/assets/tasks/push_system_user.py @@ -138,7 +138,7 @@ def get_push_unixlike_system_user_tasks(system_user, username=None): return tasks -def get_push_windows_system_user_tasks(system_user, username=None): +def get_push_windows_system_user_tasks(system_user: SystemUser, username=None): if username is None: username = system_user.username password = system_user.password @@ -151,6 +151,11 @@ def get_push_windows_system_user_tasks(system_user, username=None): if not password: logger.error("Error: no password found") return tasks + + if system_user.ad_domain: + logger.error('System user with AD domain do not support push.') + return tasks + task = { 'name': 'Add user {}'.format(username), 'action': { From 4cbf6dd5e6f024f94910b186b4a23dcd7acf29c4 Mon Sep 17 00:00:00 2001 From: Michael Bai Date: Tue, 14 Dec 2021 19:00:28 +0800 Subject: [PATCH 07/10] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E7=B3=BB=E7=BB=9F=E7=94=A8=E6=88=B7=E8=AE=A4=E8=AF=81?= =?UTF-8?q?=E4=BF=A1=E6=81=AFAPI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/api/system_user.py | 3 ++- apps/assets/models/user.py | 11 ++++++++++- apps/authentication/api/connection_token.py | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/assets/api/system_user.py b/apps/assets/api/system_user.py index 581800bec..912630b79 100644 --- a/apps/assets/api/system_user.py +++ b/apps/assets/api/system_user.py @@ -138,7 +138,8 @@ class SystemUserAppAuthInfoApi(generics.RetrieveAPIView): instance = super().get_object() app_id = self.kwargs.get('app_id') user_id = self.request.query_params.get("user_id") - instance.load_app_more_auth(app_id, user_id) + username = self.request.query_params.get("username") + instance.load_app_more_auth(app_id, username, user_id) return instance diff --git a/apps/assets/models/user.py b/apps/assets/models/user.py index 5e0384d01..7677c3f08 100644 --- a/apps/assets/models/user.py +++ b/apps/assets/models/user.py @@ -129,12 +129,21 @@ class AuthMixin: if password: self.password = password - def load_app_more_auth(self, app_id=None, user_id=None): + def load_app_more_auth(self, app_id=None, username=None, user_id=None): self._clean_auth_info_if_manual_login_mode() # 加载临时认证信息 if self.login_mode == self.LOGIN_MANUAL: self._load_tmp_auth_if_has(app_id, user_id) return + # 更新用户名 + from users.models import User + user = get_object_or_none(User, pk=user_id) if user_id else None + if self.username_same_with_user: + if user and not username: + _username = user.username + else: + _username = username + self.username = _username def load_asset_special_auth(self, asset, username=''): """ diff --git a/apps/authentication/api/connection_token.py b/apps/authentication/api/connection_token.py index 9001e8650..4adaa1942 100644 --- a/apps/authentication/api/connection_token.py +++ b/apps/authentication/api/connection_token.py @@ -294,7 +294,7 @@ class SecretDetailMixin: data.update(asset_detail) else: app_detail = self._get_application_secret_detail(app) - system_user.load_app_more_auth(app.id, user.id) + system_user.load_app_more_auth(app.id, user.username, user.id) data['type'] = 'application' data.update(app_detail) From ff9632d6da3e2d39a441e7f76959029dc73e0f42 Mon Sep 17 00:00:00 2001 From: xinwen Date: Tue, 14 Dec 2021 19:28:05 +0800 Subject: [PATCH 08/10] =?UTF-8?q?fix:=20LDAP=20=E6=B5=8B=E8=AF=95=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/settings/api/ldap.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/settings/api/ldap.py b/apps/settings/api/ldap.py index ea90e7970..1a35fb491 100644 --- a/apps/settings/api/ldap.py +++ b/apps/settings/api/ldap.py @@ -6,6 +6,7 @@ from rest_framework import generics from rest_framework.views import Response, APIView from orgs.models import Organization from django.utils.translation import ugettext_lazy as _ +from django.conf import settings from ..utils import ( LDAPServerUtil, LDAPCacheUtil, LDAPImportUtil, LDAPSyncUtil, @@ -47,6 +48,10 @@ class LDAPTestingConfigAPI(APIView): search_filter = serializer.validated_data["AUTH_LDAP_SEARCH_FILTER"] attr_map = serializer.validated_data["AUTH_LDAP_USER_ATTR_MAP"] auth_ldap = serializer.validated_data.get('AUTH_LDAP', False) + + if not password: + password = settings.AUTH_LDAP_BIND_PASSWORD + config = { 'server_uri': server_uri, 'bind_dn': bind_dn, From 303102d40bdcf2dd0e25736b41701822b32efb1a Mon Sep 17 00:00:00 2001 From: Michael Bai Date: Tue, 14 Dec 2021 18:16:43 +0800 Subject: [PATCH 09/10] =?UTF-8?q?fix:=20=E5=88=A0=E9=99=A4=E4=B8=80?= =?UTF-8?q?=E4=BA=9B=E5=90=AF=E5=8A=A8=E6=97=B6=E5=A4=A7=E9=87=8F=E8=BE=93?= =?UTF-8?q?=E5=87=BA=E7=9A=84debug=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/signals_handler/node_assets_mapping.py | 8 -------- apps/common/cache.py | 1 - 2 files changed, 9 deletions(-) diff --git a/apps/assets/signals_handler/node_assets_mapping.py b/apps/assets/signals_handler/node_assets_mapping.py index 5c2439005..da7e8fab5 100644 --- a/apps/assets/signals_handler/node_assets_mapping.py +++ b/apps/assets/signals_handler/node_assets_mapping.py @@ -40,10 +40,6 @@ def expire_node_assets_mapping_for_memory(org_id): root_org_id = Organization.ROOT_ID # 当前进程清除(cache 数据) - logger.debug( - "Expire node assets id mapping from cache of org={}, pid={}" - "".format(org_id, os.getpid()) - ) Node.expire_node_all_asset_ids_mapping_from_cache(org_id) Node.expire_node_all_asset_ids_mapping_from_cache(root_org_id) @@ -81,10 +77,6 @@ def subscribe_node_assets_mapping_expire(sender, **kwargs): root_org_id = Organization.ROOT_ID Node.expire_node_all_asset_ids_mapping_from_memory(org_id) Node.expire_node_all_asset_ids_mapping_from_memory(root_org_id) - logger.debug( - "Expire node assets id mapping from memory of org={}, pid={}" - "".format(str(org_id), os.getpid()) - ) def keep_subscribe_node_assets_relation(): node_assets_mapping_for_memory_pub_sub.keep_handle_msg(handle_node_relation_change) diff --git a/apps/common/cache.py b/apps/common/cache.py index aad069c47..168f9e9d3 100644 --- a/apps/common/cache.py +++ b/apps/common/cache.py @@ -173,7 +173,6 @@ class Cache(metaclass=CacheType): def expire(self, *fields): self._data = None if not fields: - logger.debug(f'Delete cached key: key={self.key}') self.redis.delete(self.key) else: self.redis.hdel(self.key, *fields) From 27588f48d8d464a2cb95952587158f119e7532f0 Mon Sep 17 00:00:00 2001 From: xinwen Date: Tue, 14 Dec 2021 16:00:59 +0800 Subject: [PATCH 10/10] =?UTF-8?q?fix:=20authbook=20=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=E6=B2=A1=E6=9C=89=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E6=8E=A8=E9=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/assets/tasks/common.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/apps/assets/tasks/common.py b/apps/assets/tasks/common.py index 06b656e24..b6c2326e9 100644 --- a/apps/assets/tasks/common.py +++ b/apps/assets/tasks/common.py @@ -13,16 +13,24 @@ __all__ = ['add_nodes_assets_to_system_users'] @tmp_to_root_org() def add_nodes_assets_to_system_users(nodes_keys, system_users): from ..models import Node + from assets.tasks import push_system_user_to_assets + nodes = Node.objects.filter(key__in=nodes_keys) assets = Node.get_nodes_all_assets(*nodes) for system_user in system_users: """ 解决资产和节点进行关联时,已经关联过的节点不会触发 authbook post_save 信号, 无法更新节点下所有资产的管理用户的问题 """ + need_push_asset_ids = [] for asset in assets: defaults = {'asset': asset, 'systemuser': system_user, 'org_id': asset.org_id} instance, created = AuthBook.objects.update_or_create( defaults=defaults, asset=asset, systemuser=system_user ) + if created: + need_push_asset_ids.append(asset.id) # # 不再自动更新资产管理用户,只允许用户手动指定。 # 只要关联都需要更新资产的管理用户 # instance.update_asset_admin_user_if_need() + + if need_push_asset_ids: + push_system_user_to_assets.delay(system_user.id, need_push_asset_ids)