From d675b1d4fc3c310b5e7874cdedb4f5bcceaa5ec7 Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 17 May 2022 16:53:15 +0800 Subject: [PATCH 1/6] =?UTF-8?q?fix:=20k8s=20token=20=E8=A7=A3=E5=AF=86=20(?= =?UTF-8?q?#8252)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: feng626 <1304903146@qq.com> --- apps/assets/serializers/system_user.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/assets/serializers/system_user.py b/apps/assets/serializers/system_user.py index 850870762..ab07533d0 100644 --- a/apps/assets/serializers/system_user.py +++ b/apps/assets/serializers/system_user.py @@ -4,6 +4,7 @@ from django.db.models import Count from common.mixins.serializers import BulkSerializerMixin from common.utils import ssh_pubkey_gen +from common.drf.fields import EncryptedField from common.validators import alphanumeric_re, alphanumeric_cn_re, alphanumeric_win_re from orgs.mixins.serializers import BulkOrgResourceModelSerializer from ..models import SystemUser, Asset @@ -26,6 +27,9 @@ class SystemUserSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): auto_generate_key = serializers.BooleanField(initial=True, required=False, write_only=True) type_display = serializers.ReadOnlyField(source='get_type_display', label=_('Type display')) ssh_key_fingerprint = serializers.ReadOnlyField(label=_('SSH key fingerprint')) + token = EncryptedField( + label=_('Token'), required=False, write_only=True, style={'base_template': 'textarea.html'} + ) applications_amount = serializers.IntegerField( source='apps_amount', read_only=True, label=_('Apps amount') ) From 07779c5a7a59984b534e28ef7df5f853cd48ebbb Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 17 May 2022 18:57:04 +0800 Subject: [PATCH 2/6] =?UTF-8?q?perf:=20=E5=B7=A5=E5=8D=95=E5=90=AF?= =?UTF-8?q?=E7=94=A8=20(#8254)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: ibuler Co-authored-by: Jiangjie.Bai <32935519+BaiJiangJie@users.noreply.github.com> --- apps/jumpserver/conf.py | 2 + apps/jumpserver/settings/custom.py | 1 + apps/locale/ja/LC_MESSAGES/django.mo | 4 +- apps/locale/ja/LC_MESSAGES/django.po | 65 +++++++++++++++------------- apps/locale/zh/LC_MESSAGES/django.mo | 4 +- apps/locale/zh/LC_MESSAGES/django.po | 65 +++++++++++++++------------- apps/settings/serializers/basic.py | 1 + apps/settings/serializers/public.py | 4 +- 8 files changed, 83 insertions(+), 63 deletions(-) diff --git a/apps/jumpserver/conf.py b/apps/jumpserver/conf.py index 18b998ab2..6f84397ac 100644 --- a/apps/jumpserver/conf.py +++ b/apps/jumpserver/conf.py @@ -389,6 +389,8 @@ class Config(dict): 'FTP_LOG_KEEP_DAYS': 200, 'CLOUD_SYNC_TASK_EXECUTION_KEEP_DAYS': 30, + 'TICKETS_ENABLED': True, + # 废弃的 'DEFAULT_ORG_SHOW_ALL_USERS': True, 'ORG_CHANGE_TO_URL': '', diff --git a/apps/jumpserver/settings/custom.py b/apps/jumpserver/settings/custom.py index c4dfdcc24..b2768f2d8 100644 --- a/apps/jumpserver/settings/custom.py +++ b/apps/jumpserver/settings/custom.py @@ -119,6 +119,7 @@ CHANGE_AUTH_PLAN_SECURE_MODE_ENABLED = CONFIG.CHANGE_AUTH_PLAN_SECURE_MODE_ENABL DATETIME_DISPLAY_FORMAT = '%Y-%m-%d %H:%M:%S' +TICKETS_ENABLED = CONFIG.TICKETS_ENABLED REFERER_CHECK_ENABLED = CONFIG.REFERER_CHECK_ENABLED CONNECTION_TOKEN_ENABLED = CONFIG.CONNECTION_TOKEN_ENABLED diff --git a/apps/locale/ja/LC_MESSAGES/django.mo b/apps/locale/ja/LC_MESSAGES/django.mo index c78d49bb5..b6af2bdf7 100644 --- a/apps/locale/ja/LC_MESSAGES/django.mo +++ b/apps/locale/ja/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:01a52223f421d736b00a600f623d28ac4a43e97a30f5e9cbebc3e6d18ed4527e -size 127324 +oid sha256:843b6dffe6af09073053e21f65be4c8264e6dee05509b375c8191dde8c9079b6 +size 127386 diff --git a/apps/locale/ja/LC_MESSAGES/django.po b/apps/locale/ja/LC_MESSAGES/django.po index 287e88567..6b97b95d0 100644 --- a/apps/locale/ja/LC_MESSAGES/django.po +++ b/apps/locale/ja/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-05-16 17:43+0800\n" +"POT-Creation-Date: 2022-05-17 18:02+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -758,10 +758,12 @@ msgstr "接続性" msgid "Date verified" msgstr "確認済みの日付" -#: assets/models/base.py:177 audits/signal_handlers.py:48 +#: assets/models/base.py:177 assets/serializers/base.py:14 +#: assets/serializers/base.py:36 audits/signal_handlers.py:48 #: authentication/forms.py:32 #: authentication/templates/authentication/login.html:182 -#: settings/serializers/auth/ldap.py:46 users/forms/profile.py:22 +#: settings/serializers/auth/ldap.py:25 settings/serializers/auth/ldap.py:46 +#: users/forms/profile.py:22 users/serializers/user.py:92 #: users/templates/users/_msg_user_created.html:13 #: users/templates/users/user_password_verify.html:18 #: xpack/plugins/change_auth_plan/models/base.py:42 @@ -771,7 +773,8 @@ msgstr "確認済みの日付" msgid "Password" msgstr "パスワード" -#: assets/models/base.py:178 xpack/plugins/change_auth_plan/models/asset.py:53 +#: assets/models/base.py:178 assets/serializers/base.py:39 +#: xpack/plugins/change_auth_plan/models/asset.py:53 #: xpack/plugins/change_auth_plan/models/asset.py:130 #: xpack/plugins/change_auth_plan/models/asset.py:206 msgid "SSH private key" @@ -1120,11 +1123,15 @@ msgstr "定期的なパフォーマンス" msgid "Currently only mail sending is supported" msgstr "現在、メール送信のみがサポートされています" -#: assets/serializers/base.py:39 +#: assets/serializers/base.py:15 users/models/user.py:689 +msgid "Private key" +msgstr "ssh秘密鍵" + +#: assets/serializers/base.py:43 msgid "Key password" msgstr "キーパスワード" -#: assets/serializers/base.py:52 +#: assets/serializers/base.py:56 msgid "private key invalid or passphrase error" msgstr "秘密鍵が無効またはpassphraseエラー" @@ -2102,7 +2109,7 @@ msgstr "バインディングリマインダー" #: perms/serializers/application/permission.py:20 #: perms/serializers/application/permission.py:41 #: perms/serializers/asset/permission.py:19 -#: perms/serializers/asset/permission.py:45 users/serializers/user.py:143 +#: perms/serializers/asset/permission.py:45 users/serializers/user.py:145 msgid "Is valid" msgstr "有効です" @@ -3063,7 +3070,7 @@ msgstr "Organization {} のアプリケーション権限" #: perms/serializers/application/permission.py:40 #: perms/serializers/asset/permission.py:20 #: perms/serializers/asset/permission.py:44 users/serializers/user.py:87 -#: users/serializers/user.py:145 +#: users/serializers/user.py:147 msgid "Is expired" msgstr "期限切れです" @@ -3773,6 +3780,10 @@ msgstr "アナウンスの有効化" msgid "Announcement" msgstr "発表" +#: settings/serializers/basic.py:46 +msgid "Enable tickets" +msgstr "チケットを有効にする" + #: settings/serializers/cleaning.py:10 msgid "Login log keep days" msgstr "ログインログは日数を保持します" @@ -5640,7 +5651,7 @@ msgstr "強制有効" msgid "Local" msgstr "ローカル" -#: users/models/user.py:673 users/serializers/user.py:144 +#: users/models/user.py:673 users/serializers/user.py:146 msgid "Is service account" msgstr "サービスアカウントです" @@ -5652,10 +5663,6 @@ msgstr "アバター" msgid "Wechat" msgstr "微信" -#: users/models/user.py:689 -msgid "Private key" -msgstr "ssh秘密鍵" - #: users/models/user.py:711 msgid "Source" msgstr "ソース" @@ -5739,7 +5746,7 @@ msgstr "新しいパスワードを最後の {} 個のパスワードにする msgid "The newly set password is inconsistent" msgstr "新しく設定されたパスワードが一致しない" -#: users/serializers/profile.py:147 users/serializers/user.py:142 +#: users/serializers/profile.py:147 users/serializers/user.py:144 msgid "Is first login" msgstr "最初のログインです" @@ -5777,63 +5784,63 @@ msgstr "ログインブロック" msgid "Can public key authentication" msgstr "公開鍵認証が可能" -#: users/serializers/user.py:146 +#: users/serializers/user.py:148 msgid "Avatar url" msgstr "アバターURL" -#: users/serializers/user.py:148 +#: users/serializers/user.py:150 msgid "Groups name" msgstr "グループ名" -#: users/serializers/user.py:149 +#: users/serializers/user.py:151 msgid "Source name" msgstr "ソース名" -#: users/serializers/user.py:150 +#: users/serializers/user.py:152 msgid "Organization role name" msgstr "組織の役割名" -#: users/serializers/user.py:151 +#: users/serializers/user.py:153 msgid "Super role name" msgstr "スーパーロール名" -#: users/serializers/user.py:152 +#: users/serializers/user.py:154 msgid "Total role name" msgstr "合計ロール名" -#: users/serializers/user.py:154 +#: users/serializers/user.py:156 msgid "Is wecom bound" msgstr "企業の微信をバインドしているかどうか" -#: users/serializers/user.py:155 +#: users/serializers/user.py:157 msgid "Is dingtalk bound" msgstr "ピンをバインドしているかどうか" -#: users/serializers/user.py:156 +#: users/serializers/user.py:158 msgid "Is feishu bound" msgstr "飛本を縛ったかどうか" -#: users/serializers/user.py:157 +#: users/serializers/user.py:159 msgid "Is OTP bound" msgstr "仮想MFAがバインドされているか" -#: users/serializers/user.py:159 +#: users/serializers/user.py:161 msgid "System role name" msgstr "システムロール名" -#: users/serializers/user.py:199 +#: users/serializers/user.py:201 msgid "User cannot self-update fields: {}" msgstr "ユーザーは自分のフィールドを更新できません: {}" -#: users/serializers/user.py:256 +#: users/serializers/user.py:258 msgid "Select users" msgstr "ユーザーの選択" -#: users/serializers/user.py:257 +#: users/serializers/user.py:259 msgid "For security, only list several users" msgstr "セキュリティのために、複数のユーザーのみをリストします" -#: users/serializers/user.py:292 +#: users/serializers/user.py:294 msgid "name not unique" msgstr "名前が一意ではない" diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index 3a91677a1..88b5034ea 100644 --- a/apps/locale/zh/LC_MESSAGES/django.mo +++ b/apps/locale/zh/LC_MESSAGES/django.mo @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e4a00b4e1a3bc944c968987fd3c65798fb39fa552e91457693ec8fcb597820f0 -size 105225 +oid sha256:a78975a5a6669bfcc0f99bc4d47811be82a0620e873e51e4a17d06548e3b1e7f +size 105269 diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index feda0fbe7..20a071d1c 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: 2022-05-16 17:43+0800\n" +"POT-Creation-Date: 2022-05-17 18:02+0800\n" "PO-Revision-Date: 2021-05-20 10:54+0800\n" "Last-Translator: ibuler \n" "Language-Team: JumpServer team\n" @@ -753,10 +753,12 @@ msgstr "可连接性" msgid "Date verified" msgstr "校验日期" -#: assets/models/base.py:177 audits/signal_handlers.py:48 +#: assets/models/base.py:177 assets/serializers/base.py:14 +#: assets/serializers/base.py:36 audits/signal_handlers.py:48 #: authentication/forms.py:32 #: authentication/templates/authentication/login.html:182 -#: settings/serializers/auth/ldap.py:46 users/forms/profile.py:22 +#: settings/serializers/auth/ldap.py:25 settings/serializers/auth/ldap.py:46 +#: users/forms/profile.py:22 users/serializers/user.py:92 #: users/templates/users/_msg_user_created.html:13 #: users/templates/users/user_password_verify.html:18 #: xpack/plugins/change_auth_plan/models/base.py:42 @@ -766,7 +768,8 @@ msgstr "校验日期" msgid "Password" msgstr "密码" -#: assets/models/base.py:178 xpack/plugins/change_auth_plan/models/asset.py:53 +#: assets/models/base.py:178 assets/serializers/base.py:39 +#: xpack/plugins/change_auth_plan/models/asset.py:53 #: xpack/plugins/change_auth_plan/models/asset.py:130 #: xpack/plugins/change_auth_plan/models/asset.py:206 msgid "SSH private key" @@ -1112,11 +1115,15 @@ msgstr "定时执行" msgid "Currently only mail sending is supported" msgstr "当前只支持邮件发送" -#: assets/serializers/base.py:39 +#: assets/serializers/base.py:15 users/models/user.py:689 +msgid "Private key" +msgstr "ssh私钥" + +#: assets/serializers/base.py:43 msgid "Key password" msgstr "密钥密码" -#: assets/serializers/base.py:52 +#: assets/serializers/base.py:56 msgid "private key invalid or passphrase error" msgstr "密钥不合法或密钥密码错误" @@ -2081,7 +2088,7 @@ msgstr "绑定提醒" #: perms/serializers/application/permission.py:20 #: perms/serializers/application/permission.py:41 #: perms/serializers/asset/permission.py:19 -#: perms/serializers/asset/permission.py:45 users/serializers/user.py:143 +#: perms/serializers/asset/permission.py:45 users/serializers/user.py:145 msgid "Is valid" msgstr "账号是否有效" @@ -3027,7 +3034,7 @@ msgstr "组织 ({}) 的应用授权" #: perms/serializers/application/permission.py:40 #: perms/serializers/asset/permission.py:20 #: perms/serializers/asset/permission.py:44 users/serializers/user.py:87 -#: users/serializers/user.py:145 +#: users/serializers/user.py:147 msgid "Is expired" msgstr "已过期" @@ -3733,6 +3740,10 @@ msgstr "启用公告" msgid "Announcement" msgstr "公告" +#: settings/serializers/basic.py:46 +msgid "Enable tickets" +msgstr "启用工单" + #: settings/serializers/cleaning.py:10 msgid "Login log keep days" msgstr "登录日志" @@ -5562,7 +5573,7 @@ msgstr "强制启用" msgid "Local" msgstr "数据库" -#: users/models/user.py:673 users/serializers/user.py:144 +#: users/models/user.py:673 users/serializers/user.py:146 msgid "Is service account" msgstr "服务账号" @@ -5574,10 +5585,6 @@ msgstr "头像" msgid "Wechat" msgstr "微信" -#: users/models/user.py:689 -msgid "Private key" -msgstr "ssh私钥" - #: users/models/user.py:711 msgid "Source" msgstr "来源" @@ -5661,7 +5668,7 @@ msgstr "新密码不能是最近 {} 次的密码" msgid "The newly set password is inconsistent" msgstr "两次密码不一致" -#: users/serializers/profile.py:147 users/serializers/user.py:142 +#: users/serializers/profile.py:147 users/serializers/user.py:144 msgid "Is first login" msgstr "首次登录" @@ -5699,63 +5706,63 @@ msgstr "登录被阻塞" msgid "Can public key authentication" msgstr "能否公钥认证" -#: users/serializers/user.py:146 +#: users/serializers/user.py:148 msgid "Avatar url" msgstr "头像路径" -#: users/serializers/user.py:148 +#: users/serializers/user.py:150 msgid "Groups name" msgstr "用户组名" -#: users/serializers/user.py:149 +#: users/serializers/user.py:151 msgid "Source name" msgstr "用户来源名" -#: users/serializers/user.py:150 +#: users/serializers/user.py:152 msgid "Organization role name" msgstr "组织角色名称" -#: users/serializers/user.py:151 +#: users/serializers/user.py:153 msgid "Super role name" msgstr "超级角色名称" -#: users/serializers/user.py:152 +#: users/serializers/user.py:154 msgid "Total role name" msgstr "汇总角色名称" -#: users/serializers/user.py:154 +#: users/serializers/user.py:156 msgid "Is wecom bound" msgstr "是否绑定了企业微信" -#: users/serializers/user.py:155 +#: users/serializers/user.py:157 msgid "Is dingtalk bound" msgstr "是否绑定了钉钉" -#: users/serializers/user.py:156 +#: users/serializers/user.py:158 msgid "Is feishu bound" msgstr "是否绑定了飞书" -#: users/serializers/user.py:157 +#: users/serializers/user.py:159 msgid "Is OTP bound" msgstr "是否绑定了虚拟 MFA" -#: users/serializers/user.py:159 +#: users/serializers/user.py:161 msgid "System role name" msgstr "系统角色名称" -#: users/serializers/user.py:199 +#: users/serializers/user.py:201 msgid "User cannot self-update fields: {}" msgstr "用户不能更新自己的字段: {}" -#: users/serializers/user.py:256 +#: users/serializers/user.py:258 msgid "Select users" msgstr "选择用户" -#: users/serializers/user.py:257 +#: users/serializers/user.py:259 msgid "For security, only list several users" msgstr "为了安全,仅列出几个用户" -#: users/serializers/user.py:292 +#: users/serializers/user.py:294 msgid "name not unique" msgstr "名称重复" diff --git a/apps/settings/serializers/basic.py b/apps/settings/serializers/basic.py index e0672f0df..3208ad1be 100644 --- a/apps/settings/serializers/basic.py +++ b/apps/settings/serializers/basic.py @@ -43,6 +43,7 @@ class BasicSettingSerializer(serializers.Serializer): ) ANNOUNCEMENT_ENABLED = serializers.BooleanField(label=_('Enable announcement'), default=True) ANNOUNCEMENT = AnnouncementSerializer(label=_("Announcement")) + TICKETS_ENABLED = serializers.BooleanField(required=False, default=True, label=_("Enable tickets")) @staticmethod def validate_SITE_URL(s): diff --git a/apps/settings/serializers/public.py b/apps/settings/serializers/public.py index afc4fbec2..fed540bc0 100644 --- a/apps/settings/serializers/public.py +++ b/apps/settings/serializers/public.py @@ -40,4 +40,6 @@ class PrivateSettingSerializer(PublicSettingSerializer): TERMINAL_KOKO_SSH_ENABLED = serializers.BooleanField() ANNOUNCEMENT_ENABLED = serializers.BooleanField() - ANNOUNCEMENT = serializers.DictField() + ANNOUNCEMENT = serializers.CharField() + + TICKETS_ENABLED = serializers.BooleanField() From 0fc5a33983fe9ad8970bd0dc2875b7ee6eeaf79e Mon Sep 17 00:00:00 2001 From: "Jiangjie.Bai" Date: Tue, 17 May 2022 18:50:16 +0800 Subject: [PATCH 3/6] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E5=BE=AE=E4=BF=A1=E3=80=81=E9=92=89=E9=92=89=E3=80=81=E9=A3=9E?= =?UTF-8?q?=E4=B9=A6=E7=99=BB=E5=BD=95=E8=B7=B3=E8=BD=AC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/authentication/views/dingtalk.py | 5 +++-- apps/authentication/views/feishu.py | 7 ++++--- apps/authentication/views/wecom.py | 6 +++--- apps/users/utils.py | 12 +++++++----- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/apps/authentication/views/dingtalk.py b/apps/authentication/views/dingtalk.py index 0ca03749e..e97424aee 100644 --- a/apps/authentication/views/dingtalk.py +++ b/apps/authentication/views/dingtalk.py @@ -205,12 +205,13 @@ class DingTalkQRLoginView(DingTalkQRMixin, METAMixin, View): permission_classes = (AllowAny,) def get(self, request: HttpRequest): - redirect_url = request.GET.get('redirect_url') + redirect_url = request.GET.get('redirect_url') or reverse('index') + next_url = self.get_next_url_from_meta() or reverse('index') redirect_uri = reverse('authentication:dingtalk-qr-login-callback', external=True) redirect_uri += '?' + urlencode({ 'redirect_url': redirect_url, - 'next': self.get_next_url_from_meta() + 'next': next_url, }) url = self.get_qr_url(redirect_uri) diff --git a/apps/authentication/views/feishu.py b/apps/authentication/views/feishu.py index 88ba6636e..172aa2603 100644 --- a/apps/authentication/views/feishu.py +++ b/apps/authentication/views/feishu.py @@ -170,10 +170,11 @@ class FeiShuQRLoginView(FeiShuQRMixin, View): permission_classes = (AllowAny,) def get(self, request: HttpRequest): - redirect_url = request.GET.get('redirect_url') - + redirect_url = request.GET.get('redirect_url') or reverse('index') redirect_uri = reverse('authentication:feishu-qr-login-callback', external=True) - redirect_uri += '?' + urlencode({'redirect_url': redirect_url}) + redirect_uri += '?' + urlencode({ + 'redirect_url': redirect_url, + }) url = self.get_qr_url(redirect_uri) return HttpResponseRedirect(url) diff --git a/apps/authentication/views/wecom.py b/apps/authentication/views/wecom.py index 5546bf619..9b7963de8 100644 --- a/apps/authentication/views/wecom.py +++ b/apps/authentication/views/wecom.py @@ -201,12 +201,12 @@ class WeComQRLoginView(WeComQRMixin, METAMixin, View): permission_classes = (AllowAny,) def get(self, request: HttpRequest): - redirect_url = request.GET.get('redirect_url') - + redirect_url = request.GET.get('redirect_url') or reverse('index') + next_url = self.get_next_url_from_meta() or reverse('index') redirect_uri = reverse('authentication:wecom-qr-login-callback', external=True) redirect_uri += '?' + urlencode({ 'redirect_url': redirect_url, - 'next': self.get_next_url_from_meta() + 'next': next_url, }) url = self.get_qr_url(redirect_uri) diff --git a/apps/users/utils.py b/apps/users/utils.py index f11d233e4..a2fb9afac 100644 --- a/apps/users/utils.py +++ b/apps/users/utils.py @@ -46,11 +46,13 @@ def get_user_or_pre_auth_user(request): def redirect_user_first_login_or_index(request, redirect_field_name): - url_in_post = request.POST.get(redirect_field_name) - if url_in_post: - return url_in_post - url_in_get = request.GET.get(redirect_field_name, reverse('index')) - return url_in_get + url = request.POST.get(redirect_field_name) + if not url: + url = request.GET.get(redirect_field_name) + # 防止 next 地址为 None + if not url or url.lower() in ['none']: + url = reverse('index') + return url def generate_otp_uri(username, otp_secret_key=None, issuer="JumpServer"): From 7eec50804c1901390784bf05adf49c802e172f3b Mon Sep 17 00:00:00 2001 From: ibuler Date: Tue, 17 May 2022 19:34:15 +0800 Subject: [PATCH 4/6] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=20encrypted=20fi?= =?UTF-8?q?eld?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/common/drf/fields.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/common/drf/fields.py b/apps/common/drf/fields.py index abddeca01..f97925f43 100644 --- a/apps/common/drf/fields.py +++ b/apps/common/drf/fields.py @@ -27,8 +27,10 @@ class ReadableHiddenField(serializers.HiddenField): class EncryptedField(serializers.CharField): - def __init__(self, **kwargs): - kwargs['write_only'] = True + def __init__(self, write_only=None, **kwargs): + if write_only is None: + write_only = True + kwargs['write_only'] = write_only super().__init__(**kwargs) def to_internal_value(self, value): From 14710e9c9ee263e0e9d3b4ee231ec916125765a1 Mon Sep 17 00:00:00 2001 From: feng626 <1304903146@qq.com> Date: Tue, 17 May 2022 20:32:36 +0800 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20=E5=B7=A5=E5=8D=95=E5=AE=A1?= =?UTF-8?q?=E6=89=B9=E4=BA=BA=E4=B8=AD=E5=8E=BB=E9=99=A4=E7=94=B3=E8=AF=B7?= =?UTF-8?q?=E4=BA=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/acls/models/login_acl.py | 6 ++++-- apps/acls/models/login_asset_acl.py | 2 +- apps/assets/models/cmd_filter.py | 6 ++++-- apps/tickets/api/ticket.py | 7 ++++--- apps/tickets/models/ticket.py | 15 ++++++++++++--- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/apps/acls/models/login_acl.py b/apps/acls/models/login_acl.py index 6e1fbff73..f9b24e426 100644 --- a/apps/acls/models/login_acl.py +++ b/apps/acls/models/login_acl.py @@ -123,6 +123,8 @@ class LoginACL(BaseACL): 'org_id': Organization.ROOT_ID, } ticket = Ticket.objects.create(**data) - ticket.create_process_map_and_node(self.reviewers.all()) - ticket.open(self.user) + applicant = self.user + assignees = self.reviewers.all() + ticket.create_process_map_and_node(assignees, applicant) + ticket.open(applicant) return ticket diff --git a/apps/acls/models/login_asset_acl.py b/apps/acls/models/login_asset_acl.py index 0bde3c14f..dda9d97c1 100644 --- a/apps/acls/models/login_asset_acl.py +++ b/apps/acls/models/login_asset_acl.py @@ -97,7 +97,7 @@ class LoginAssetACL(BaseACL, OrgModelMixin): 'org_id': org_id, } ticket = Ticket.objects.create(**data) - ticket.create_process_map_and_node(assignees) + ticket.create_process_map_and_node(assignees, user) ticket.open(applicant=user) return ticket diff --git a/apps/assets/models/cmd_filter.py b/apps/assets/models/cmd_filter.py index 82fd50e89..c92a25109 100644 --- a/apps/assets/models/cmd_filter.py +++ b/apps/assets/models/cmd_filter.py @@ -181,8 +181,10 @@ class CommandFilterRule(OrgModelMixin): 'org_id': org_id, } ticket = Ticket.objects.create(**data) - ticket.create_process_map_and_node(self.reviewers.all()) - ticket.open(applicant=session.user_obj) + applicant = session.user_obj + assignees = self.reviewers.all() + ticket.create_process_map_and_node(assignees, applicant) + ticket.open(applicant) return ticket @classmethod diff --git a/apps/tickets/api/ticket.py b/apps/tickets/api/ticket.py index 8e7923e8e..586188898 100644 --- a/apps/tickets/api/ticket.py +++ b/apps/tickets/api/ticket.py @@ -53,9 +53,10 @@ class TicketViewSet(CommonApiMixin, viewsets.ModelViewSet): def perform_create(self, serializer): instance = serializer.save() - instance.create_related_node() - instance.process_map = instance.create_process_map() - instance.open(applicant=self.request.user) + applicant = self.request.user + instance.create_related_node(applicant) + instance.process_map = instance.create_process_map(applicant) + instance.open(applicant) @action(detail=False, methods=[POST], permission_classes=[RBACPermission, ]) def open(self, request, *args, **kwargs): diff --git a/apps/tickets/models/ticket.py b/apps/tickets/models/ticket.py index aa536584d..c05fa8b3b 100644 --- a/apps/tickets/models/ticket.py +++ b/apps/tickets/models/ticket.py @@ -188,22 +188,30 @@ class Ticket(CommonModelMixin, StatusMixin, OrgModelMixin): .exclude(state=ProcessStatus.notified).first() return processor.assignee if processor else None - def create_related_node(self): + def ignore_applicant(self, assignees, applicant=None): + applicant = applicant if applicant else self.applicant + if len(assignees) != 1: + assignees = set(assignees) - {applicant, } + return list(assignees) + + def create_related_node(self, applicant=None): org_id = self.flow.org_id approval_rule = self.get_current_ticket_flow_approve() ticket_step = TicketStep.objects.create(ticket=self, level=self.approval_step) ticket_assignees = [] assignees = approval_rule.get_assignees(org_id=org_id) + assignees = self.ignore_applicant(assignees, applicant) for assignee in assignees: ticket_assignees.append(TicketAssignee(step=ticket_step, assignee=assignee)) TicketAssignee.objects.bulk_create(ticket_assignees) - def create_process_map(self): + def create_process_map(self, applicant=None): org_id = self.flow.org_id approval_rules = self.flow.rules.order_by('level') nodes = list() for node in approval_rules: assignees = node.get_assignees(org_id=org_id) + assignees = self.ignore_applicant(assignees, applicant) assignee_ids = [assignee.id for assignee in assignees] assignees_display = [str(assignee) for assignee in assignees] nodes.append( @@ -217,7 +225,8 @@ class Ticket(CommonModelMixin, StatusMixin, OrgModelMixin): return nodes # TODO 兼容不存在流的工单 - def create_process_map_and_node(self, assignees): + def create_process_map_and_node(self, assignees, applicant): + assignees = self.ignore_applicant(assignees, applicant) self.process_map = [{ 'approval_level': 1, 'state': 'notified', From 0c71190337c0959bc7bfe9eac7d181b4fe085a0c Mon Sep 17 00:00:00 2001 From: fit2bot <68588906+fit2bot@users.noreply.github.com> Date: Tue, 17 May 2022 21:12:59 +0800 Subject: [PATCH 6/6] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=20EncryptedField?= =?UTF-8?q?=20=E5=AD=97=E6=AE=B5=E7=9A=84=20write=5Fonly=20=E5=B1=9E?= =?UTF-8?q?=E6=80=A7=20(#8259)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 修改 EncryptedField 字段的 write_only 属性 fix: 修改 EncryptedField 字段的 write_only 属性 * fix: 修改 EncryptedField 字段的 write_only 属性 Co-authored-by: Jiangjie.Bai Co-authored-by: Jiangjie.Bai <32935519+BaiJiangJie@users.noreply.github.com> --- apps/applications/serializers/application.py | 4 ++-- apps/assets/serializers/account.py | 3 ++- apps/common/drf/serializers.py | 21 +++++++++++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/apps/applications/serializers/application.py b/apps/applications/serializers/application.py index 9b62d1dc1..35a07e262 100644 --- a/apps/applications/serializers/application.py +++ b/apps/applications/serializers/application.py @@ -5,7 +5,7 @@ from django.utils.translation import ugettext_lazy as _ from orgs.mixins.serializers import BulkOrgResourceModelSerializer from assets.serializers.base import AuthSerializerMixin -from common.drf.serializers import MethodSerializer +from common.drf.serializers import MethodSerializer, SecretReadableMixin from .attrs import ( category_serializer_classes_mapping, type_serializer_classes_mapping, @@ -152,7 +152,7 @@ class AppAccountSerializer(AppSerializerMixin, AuthSerializerMixin, BulkOrgResou return super().to_representation(instance) -class AppAccountSecretSerializer(AppAccountSerializer): +class AppAccountSecretSerializer(SecretReadableMixin, AppAccountSerializer): class Meta(AppAccountSerializer.Meta): fields_backup = [ 'id', 'app_display', 'attrs', 'username', 'password', 'private_key', diff --git a/apps/assets/serializers/account.py b/apps/assets/serializers/account.py index daa7f38f8..bc4bea563 100644 --- a/apps/assets/serializers/account.py +++ b/apps/assets/serializers/account.py @@ -7,6 +7,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 +from common.drf.serializers import SecretReadableMixin class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): @@ -70,7 +71,7 @@ class AccountSerializer(AuthSerializerMixin, BulkOrgResourceModelSerializer): return super().to_representation(instance) -class AccountSecretSerializer(AccountSerializer): +class AccountSecretSerializer(SecretReadableMixin, AccountSerializer): class Meta(AccountSerializer.Meta): fields_backup = [ 'hostname', 'ip', 'platform', 'protocols', 'username', 'password', diff --git a/apps/common/drf/serializers.py b/apps/common/drf/serializers.py index 4beb59fe7..1dde4a77e 100644 --- a/apps/common/drf/serializers.py +++ b/apps/common/drf/serializers.py @@ -8,10 +8,12 @@ from common.mixins import BulkListSerializerMixin from django.utils.functional import cached_property from rest_framework.utils.serializer_helpers import BindingDict from common.mixins.serializers import BulkSerializerMixin +from common.drf.fields import EncryptedField __all__ = [ 'MethodSerializer', - 'EmptySerializer', 'BulkModelSerializer', 'AdaptedBulkListSerializer', 'CeleryTaskSerializer' + 'EmptySerializer', 'BulkModelSerializer', 'AdaptedBulkListSerializer', 'CeleryTaskSerializer', + 'SecretReadableMixin' ] @@ -83,3 +85,20 @@ class CeleryTaskSerializer(serializers.Serializer): task = serializers.CharField(read_only=True) +class SecretReadableMixin(serializers.Serializer): + """ 加密字段 (EncryptedField) 可读性 """ + + def __init__(self, *args, **kwargs): + super(SecretReadableMixin, self).__init__(*args, **kwargs) + if not hasattr(self, 'Meta') or not hasattr(self.Meta, 'extra_kwargs'): + return + extra_kwargs = self.Meta.extra_kwargs + for field_name, serializer_field in self.fields.items(): + if not isinstance(serializer_field, EncryptedField): + continue + if field_name not in extra_kwargs: + continue + field_extra_kwargs = extra_kwargs[field_name] + if 'write_only' not in field_extra_kwargs: + continue + serializer_field.write_only = field_extra_kwargs['write_only']