\n" +" \n" +" Username: %(username)s.\n" +" \n" +" \n" +" click here to set your password\n" +" \n" +" \n" +" This link is valid for 1 hour. After it expires, request new one\n" -"\n" -" \n" -" ---\n" -"\n" -" \n" -" Login direct\n" -"\n" -" \n" -" " +" \n" +" \n" +" Login direct\n" +" \n" +"
\n" +" " msgstr "" "\n" -" 你好 %(name)s:\n" -" \n" -" 恭喜您,您的账号已经创建成功 \n" -" 用户名: %(username)s\n" -" \n" -" 请点击这" -"里设置密码 \n" -" 这个链接有效期1小时, 超过时间您可以 重新申请\n" -"\n" -" \n" -" ---\n" -"\n" -" \n" -" Login direct\n" -"\n" -" \n" +" \n" +"\n" +" \n" +" 用户名: %(username)s.\n" +" \n" +" \n" +" " +"请点击这里设置密码\n" +" \n" +" \n" +" 这个链接有效期1小时, 超过时间您可以 重新申请\n" +" \n" +" \n" +" ---登录页面\n" +" \n" +"
\n" " " -#: users/utils.py:79 +#: users/utils.py:73 +msgid "Create account successfully" +msgstr "创建账户成功" + +#: users/utils.py:77 +#, python-format +msgid "Hello %(name)s" +msgstr "您好 %(name)s" + +#: users/utils.py:100 #, python-format msgid "" "\n" @@ -4985,11 +5048,11 @@ msgstr "" " \n" " " -#: users/utils.py:110 +#: users/utils.py:131 msgid "Security notice" msgstr "安全通知" -#: users/utils.py:112 +#: users/utils.py:133 #, python-format msgid "" "\n" @@ -5038,11 +5101,11 @@ msgstr "" " \n" " " -#: users/utils.py:148 +#: users/utils.py:169 msgid "SSH Key Reset" msgstr "重置ssh密钥" -#: users/utils.py:150 +#: users/utils.py:171 #, python-format msgid "" "\n" @@ -5067,15 +5130,15 @@ msgstr "" " \n" " " -#: users/utils.py:183 +#: users/utils.py:204 msgid "User not exist" msgstr "用户不存在" -#: users/utils.py:185 +#: users/utils.py:206 msgid "Disabled or expired" msgstr "禁用或失效" -#: users/utils.py:198 +#: users/utils.py:219 msgid "Password or SSH public key invalid" msgstr "密码或密钥不合法" @@ -5341,7 +5404,7 @@ msgid "Run plan manually" msgstr "手动执行计划" #: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:179 -#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:102 +#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:101 msgid "Execute failed" msgstr "执行失败" @@ -5427,7 +5490,7 @@ msgid "Unavailable" msgstr "无效" #: xpack/plugins/cloud/models.py:50 -#: xpack/plugins/cloud/templates/cloud/account_detail.html:54 +#: xpack/plugins/cloud/templates/cloud/account_detail.html:56 #: xpack/plugins/cloud/templates/cloud/account_list.html:13 msgid "Provider" msgstr "云服务商" @@ -5453,7 +5516,7 @@ msgid "Instances" msgstr "实例" #: xpack/plugins/cloud/models.py:126 -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:73 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:75 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:17 msgid "Date last sync" msgstr "最后同步日期" @@ -5472,7 +5535,7 @@ msgstr "" #: xpack/plugins/cloud/models.py:173 xpack/plugins/cloud/models.py:189 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:71 -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:66 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:68 msgid "Date sync" msgstr "同步日期" @@ -5489,8 +5552,8 @@ msgid "Sync instance task history" msgstr "同步实例任务历史" #: xpack/plugins/cloud/models.py:185 -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:89 -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:61 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:91 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:63 msgid "Instance" msgstr "实例" @@ -5510,7 +5573,7 @@ msgstr "AWS (国际)" msgid "Qcloud" msgstr "腾讯云" -#: xpack/plugins/cloud/templates/cloud/account_detail.html:20 +#: xpack/plugins/cloud/templates/cloud/account_detail.html:22 #: xpack/plugins/cloud/views.py:72 msgid "Account detail" msgstr "账户详情" @@ -5528,23 +5591,23 @@ msgstr "加载中..." msgid "Load failed" msgstr "加载失败" -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:20 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:22 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:25 -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:21 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:23 #: xpack/plugins/cloud/views.py:122 msgid "Sync task detail" msgstr "同步任务详情" -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:23 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:25 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:28 -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:24 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:26 #: xpack/plugins/cloud/views.py:137 msgid "Sync task history" msgstr "同步历史列表" -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:26 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:28 #: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:31 -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:27 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:29 #: xpack/plugins/cloud/views.py:188 msgid "Sync instance list" msgstr "同步实例列表" @@ -5577,7 +5640,7 @@ msgstr "执行次数" msgid "Instance count" msgstr "实例个数" -#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:93 +#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:92 msgid "Sync success" msgstr "同步成功" @@ -5661,7 +5724,6 @@ msgid "This will restore default Settings of the interface !!!" msgstr "您确定要恢复默认初始化吗?" #: xpack/plugins/interface/templates/interface/interface.html:107 -#: xpack/plugins/interface/views.py:53 msgid "Restore default successfully." msgstr "恢复默认成功!" @@ -5674,9 +5736,13 @@ msgid "Interface" msgstr "界面" #: xpack/plugins/interface/views.py:49 -msgid "It is already in the default setting state!" +msgid "It is already in the default setting state!" msgstr "当前已经是初始化状态!" +#: xpack/plugins/interface/views.py:53 +msgid "Restore default successfully!" +msgstr "恢复默认成功!" + #: xpack/plugins/license/meta.py:11 xpack/plugins/license/models.py:94 #: xpack/plugins/license/templates/license/license_detail.html:50 #: xpack/plugins/license/templates/license/license_detail.html:55 @@ -5817,6 +5883,45 @@ msgstr "更新组织" #~ msgid "Update user groups" #~ msgstr "更新用户组" +# msgid "Update user" +# msgstr "更新用户" +#~ msgid "" +#~ "\n" +#~ " \n" +#~ "\n" +#~ " \n" +#~ " click here to set your password\n" +#~ " \n" +#~ " \n" +#~ " This link is valid for 1 hour. After it expires, request new one\n" +#~ " \n" +#~ " \n" +#~ " Login direct\n" +#~ " \n" +#~ "
\n" +#~ " " +#~ msgstr "" +#~ "\n" +#~ " \n" +#~ "\n" +#~ " \n" +#~ " 请点击这里设置密码\n" +#~ " \n" +#~ " \n" +#~ " 这个链接有效期1小时, 超过时间您可以, 重新申请\n" +#~ " \n" +#~ " \n" +#~ " Login direct\n" +#~ " \n" +#~ "
\n" +#~ " " + #~ msgid "Template" #~ msgstr "模板" @@ -5851,9 +5956,6 @@ msgstr "更新组织" #~ msgid "Select host" #~ msgstr "选择资产" -#~ msgid "Restore default successfully!" -#~ msgstr "恢复默认成功!" - #~ msgid "Beijing Duizhan Tech, Inc." #~ msgstr "北京堆栈科技有限公司" diff --git a/apps/perms/api/user_permission.py b/apps/perms/api/user_permission.py index 7c934340e..377bd735c 100644 --- a/apps/perms/api/user_permission.py +++ b/apps/perms/api/user_permission.py @@ -512,6 +512,7 @@ class UserGrantedRemoteAppsAsTreeApi(ListAPIView): class ValidateUserRemoteAppPermissionApi(APIView): + permission_classes = (IsOrgAdminOrAppUser,) def get(self, request, *args, **kwargs): user_id = request.query_params.get('user_id', '') diff --git a/apps/settings/api.py b/apps/settings/api.py index a65df113d..f2b3eb558 100644 --- a/apps/settings/api.py +++ b/apps/settings/api.py @@ -79,7 +79,7 @@ class LDAPTestingAPI(APIView): util = self.get_ldap_util(serializer) try: - users = util.get_search_user_items() + users = util.search_user_items() except Exception as e: return Response({"error": str(e)}, status=401) @@ -95,7 +95,7 @@ class LDAPUserListApi(APIView): def get(self, request): util = LDAPUtil() try: - users = util.get_search_user_items() + users = util.search_user_items() except Exception as e: users = [] logger.error(e, exc_info=True) @@ -108,11 +108,11 @@ class LDAPUserSyncAPI(APIView): permission_classes = (IsOrgAdmin,) def post(self, request): - user_names = request.data.get('user_names', '') + username_list = request.data.get('username_list', []) util = LDAPUtil() try: - result = util.sync_users(username_set=user_names) + result = util.sync_users(username_list) except Exception as e: logger.error(e, exc_info=True) return Response({'error': str(e)}, status=401) diff --git a/apps/settings/forms.py b/apps/settings/forms.py index d87845ea9..0ca565434 100644 --- a/apps/settings/forms.py +++ b/apps/settings/forms.py @@ -242,3 +242,26 @@ class SecuritySettingForm(BaseForm): 'and resets must contain special characters') ) + +class EmailContentSettingForm(BaseForm): + EMAIL_CUSTOM_USER_CREATED_SUBJECT = forms.CharField( + max_length=1024, required=False, label=_("Create user email subject"), + help_text=_("Tips: When creating a user, send the subject of the email" + " (eg:Create account successfully)") + ) + EMAIL_CUSTOM_USER_CREATED_HONORIFIC = forms.CharField( + max_length=1024, required=False, label=_("Create user honorific"), + help_text=_("Tips: When creating a user, send the honorific of the " + "email (eg:Hello)") + ) + EMAIL_CUSTOM_USER_CREATED_BODY = forms.CharField( + max_length=4096, required=False, widget=forms.Textarea(), + label=_('Create user email content'), + help_text=_('Tips:When creating a user, send the content of the email') + ) + EMAIL_CUSTOM_USER_CREATED_SIGNATURE = forms.CharField( + max_length=512, required=False, label=_("Signature"), + help_text=_("Tips: Email signature (eg:jumpserver)") + ) + + diff --git a/apps/settings/templates/settings/_ldap_list_users_modal.html b/apps/settings/templates/settings/_ldap_list_users_modal.html index 2009e9b58..9609d80ce 100644 --- a/apps/settings/templates/settings/_ldap_list_users_modal.html +++ b/apps/settings/templates/settings/_ldap_list_users_modal.html @@ -58,6 +58,9 @@ function initLdapUsersTable() { ele: $('#ldap_list_users_table'), ajax_url: '{% url "api-settings:ldap-user-list" %}', columnDefs: [ + {targets: 0, createdCell: function (td, cellData, rowData) { + $(td).html("".replace("ID_USERNAME", cellData)) + }}, {targets: 4, createdCell: function (td, cellData, rowData) { if(cellData){ $(td).html('') diff --git a/apps/settings/templates/settings/basic_setting.html b/apps/settings/templates/settings/basic_setting.html index 17c8057bc..4c26e8bb3 100644 --- a/apps/settings/templates/settings/basic_setting.html +++ b/apps/settings/templates/settings/basic_setting.html @@ -17,6 +17,9 @@+ + Username: %(username)s. + + + click here to set your password + + + This link is valid for 1 hour. After it expires, request new one + + + Login direct + +
+ """) % { 'username': user.username, 'rest_password_url': reverse('users:reset-password', external=True), 'rest_password_token': user.generate_reset_token(), @@ -64,6 +59,32 @@ def send_user_created_mail(user): 'email': user.email, 'login_url': reverse('authentication:login', external=True), } + + if settings.EMAIL_CUSTOM_USER_CREATED_BODY: + custom_body = '' + settings.EMAIL_CUSTOM_USER_CREATED_BODY + '
' + else: + custom_body = '' + body = custom_body + default_body + return body + + +def send_user_created_mail(user): + recipient_list = [user.email] + subject = _('Create account successfully') + if settings.EMAIL_CUSTOM_USER_CREATED_SUBJECT: + subject = settings.EMAIL_CUSTOM_USER_CREATED_SUBJECT + + honorific = '' + _('Hello %(name)s') % {'name': user.name} + ':
' + if settings.EMAIL_CUSTOM_USER_CREATED_HONORIFIC: + honorific = '' + settings.EMAIL_CUSTOM_USER_CREATED_HONORIFIC + ':
' + + body = construct_user_created_email_body(user) + + signature = 'jumpserver
' + if settings.EMAIL_CUSTOM_USER_CREATED_SIGNATURE: + signature = '' + settings.EMAIL_CUSTOM_USER_CREATED_SIGNATURE + '
' + + message = honorific + body + signature if settings.DEBUG: try: print(message) @@ -313,3 +334,13 @@ def is_need_unblock(key_block): if not cache.get(key_block): return False return True + + +def construct_user_email(username, email): + if '@' not in email: + if '@' in username: + email = username + else: + email = '{}@{}'.format(username, settings.EMAIL_SUFFIX) + return email +