mirror of https://github.com/jumpserver/jumpserver
commit
d672122c79
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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')
|
||||
)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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': '',
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:01a52223f421d736b00a600f623d28ac4a43e97a30f5e9cbebc3e6d18ed4527e
|
||||
size 127324
|
||||
oid sha256:843b6dffe6af09073053e21f65be4c8264e6dee05509b375c8191dde8c9079b6
|
||||
size 127386
|
||||
|
|
|
@ -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 <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\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 "名前が一意ではない"
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e4a00b4e1a3bc944c968987fd3c65798fb39fa552e91457693ec8fcb597820f0
|
||||
size 105225
|
||||
oid sha256:a78975a5a6669bfcc0f99bc4d47811be82a0620e873e51e4a17d06548e3b1e7f
|
||||
size 105269
|
||||
|
|
|
@ -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 <ibuler@qq.com>\n"
|
||||
"Language-Team: JumpServer team<ibuler@qq.com>\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 "名称重复"
|
||||
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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"):
|
||||
|
|
Loading…
Reference in New Issue