diff --git a/apps/assets/forms/domain.py b/apps/assets/forms/domain.py index 5a88a1dd7..90db16fd0 100644 --- a/apps/assets/forms/domain.py +++ b/apps/assets/forms/domain.py @@ -64,7 +64,7 @@ class GatewayForm(PasswordAndKeyAuthForm, OrgModelForm): model = Gateway fields = [ 'name', 'ip', 'port', 'username', 'protocol', 'domain', 'password', - 'private_key_file', 'is_active', 'comment', + 'private_key', 'is_active', 'comment', ] help_texts = { 'protocol': _("SSH gateway support proxy SSH,RDP,VNC") diff --git a/apps/assets/forms/user.py b/apps/assets/forms/user.py index 34a9e3c52..b0096c2f0 100644 --- a/apps/assets/forms/user.py +++ b/apps/assets/forms/user.py @@ -26,39 +26,39 @@ class PasswordAndKeyAuthForm(forms.ModelForm): label=_("Password"), ) # Need use upload private key file except paste private key content - private_key_file = forms.FileField(required=False, label=_("Private key")) + private_key = forms.FileField(required=False, label=_("Private key")) - def clean_private_key_file(self): - private_key_file = self.cleaned_data['private_key_file'] + def clean_private_key(self): + private_key_f = self.cleaned_data['private_key'] password = self.cleaned_data['password'] - if private_key_file: - key_string = private_key_file.read() - private_key_file.seek(0) + if private_key_f: + key_string = private_key_f.read() + private_key_f.seek(0) key_string = key_string.decode() if not validate_ssh_private_key(key_string, password): msg = _('Invalid private key, Only support ' 'RSA/DSA format key') raise forms.ValidationError(msg) - return private_key_file + return private_key_f def validate_password_key(self): password = self.cleaned_data['password'] - private_key_file = self.cleaned_data.get('private_key_file', '') + private_key_f = self.cleaned_data.get('private_key', '') - if not password and not private_key_file: + if not password and not private_key_f: raise forms.ValidationError(_( 'Password and private key file must be input one' )) def gen_keys(self): password = self.cleaned_data.get('password', '') or None - private_key_file = self.cleaned_data['private_key_file'] + private_key_f = self.cleaned_data['private_key'] public_key = private_key = None - if private_key_file: - private_key = private_key_file.read().strip().decode('utf-8') + if private_key_f: + private_key = private_key_f.read().strip().decode('utf-8') public_key = ssh_pubkey_gen(private_key=private_key, password=password) return private_key, public_key @@ -69,7 +69,7 @@ class AdminUserForm(PasswordAndKeyAuthForm): class Meta: model = AdminUser - fields = ['name', 'username', 'password', 'private_key_file', 'comment'] + fields = ['name', 'username', 'password', 'private_key', 'comment'] widgets = { 'name': forms.TextInput(attrs={'placeholder': _('Name')}), 'username': forms.TextInput(attrs={'placeholder': _('Username')}), @@ -87,7 +87,7 @@ class SystemUserForm(OrgModelForm, PasswordAndKeyAuthForm): model = SystemUser fields = [ 'name', 'username', 'protocol', 'auto_generate_key', - 'password', 'private_key_file', 'auto_push', 'sudo', + 'password', 'private_key', 'auto_push', 'sudo', 'comment', 'shell', 'priority', 'login_mode', 'cmd_filters', ] widgets = { diff --git a/apps/assets/serializers/base.py b/apps/assets/serializers/base.py index 257bb95ab..5e853219b 100644 --- a/apps/assets/serializers/base.py +++ b/apps/assets/serializers/base.py @@ -40,6 +40,10 @@ class AuthSerializerMixin: def validate_private_key(self, private_key): if not private_key: return + if 'OPENSSH' in private_key: + msg = _("Not support openssh format key, using " + "ssh-keygen -t rsa -m pem to generate") + raise serializers.ValidationError(msg) password = self.initial_data.get("password") valid = validate_ssh_private_key(private_key, password) if not valid: diff --git a/apps/assets/templates/assets/_system_user.html b/apps/assets/templates/assets/_system_user.html index 5cc3e04ba..1f34f3f55 100644 --- a/apps/assets/templates/assets/_system_user.html +++ b/apps/assets/templates/assets/_system_user.html @@ -53,7 +53,7 @@ </div> <div class="auth-fields"> {% bootstrap_field form.password layout="horizontal" %} - {% bootstrap_field form.private_key_file layout="horizontal" %} + {% bootstrap_field form.private_key layout="horizontal" %} </div> <div class="form-group"> <label for="{{ form.auto_push.id_for_label }}" class="col-sm-2 control-label">{% trans 'Auto push' %}</label> @@ -90,7 +90,7 @@ var login_mode_id = '#' + '{{ form.login_mode.id_for_label }}'; var auto_generate_key = '#'+'{{ form.auto_generate_key.id_for_label }}'; var password_id = '#' + '{{ form.password.id_for_label }}'; -var private_key_id = '#' + '{{ form.private_key_file.id_for_label }}'; +var private_key_id = '#' + '{{ form.private_key.id_for_label }}'; var auto_push_id = '#' + '{{ form.auto_push.id_for_label }}'; var sudo_id = '#' + '{{ form.sudo.id_for_label }}'; var shell_id = '#' + '{{ form.shell.id_for_label }}'; @@ -230,7 +230,7 @@ $(document).ready(function () { objectAttrsIsList(data, ['cmd_filters']); objectAttrsIsBool(data, ["auto_generate_key", "auto_push"]); - data["private_key"] = $("#id_private_key_file").data('file'); + data["private_key"] = $("#id_private_key").data('file'); var props = { url: the_url, @@ -240,9 +240,9 @@ $(document).ready(function () { redirect_to: redirect_to }; formSubmit(props); -}).on('change', '#id_private_key_file', function () { +}).on('change', '#id_private_key', function () { readFile($(this)).on("onload", function (evt, data) { - $(this).attr("data-file", data) + $(this).data("file", data) }) }) diff --git a/apps/assets/templates/assets/admin_user_create_update.html b/apps/assets/templates/assets/admin_user_create_update.html index 8d32d16ab..5a2f3d6c9 100644 --- a/apps/assets/templates/assets/admin_user_create_update.html +++ b/apps/assets/templates/assets/admin_user_create_update.html @@ -37,7 +37,7 @@ {% bootstrap_field form.name layout="horizontal" %} {% bootstrap_field form.username layout="horizontal" %} {% bootstrap_field form.password layout="horizontal" %} - {% bootstrap_field form.private_key_file layout="horizontal" %} + {% bootstrap_field form.private_key layout="horizontal" %} {% bootstrap_field form.comment layout="horizontal" %} <div class="form-group"> @@ -70,8 +70,9 @@ $(document).ready(function () { {% endif %} var form = $("form"); var data = form.serializeObject(); + console.log($("#id_private_key").data("file")); - data["private_key"] = $("#id_private_key_file").data('file'); + data["private_key"] = $("#id_private_key").data('file'); var props = { url: the_url, @@ -82,9 +83,9 @@ $(document).ready(function () { }; formSubmit(props); }) -.on('change', '#id_private_key_file', function () { +.on('change', '#id_private_key', function () { readFile($(this)).on("onload", function (evt, data) { - $(this).attr("data-file", data) + $(this).data("file", data) }) }) </script> diff --git a/apps/assets/templates/assets/gateway_create_update.html b/apps/assets/templates/assets/gateway_create_update.html index a22428087..315302b6f 100644 --- a/apps/assets/templates/assets/gateway_create_update.html +++ b/apps/assets/templates/assets/gateway_create_update.html @@ -46,7 +46,7 @@ <div class="auth-fields"> {% bootstrap_field form.username layout="horizontal" %} {% bootstrap_field form.password layout="horizontal" %} - {% bootstrap_field form.private_key_file layout="horizontal" %} + {% bootstrap_field form.private_key layout="horizontal" %} </div> {% endblock %} @@ -70,7 +70,7 @@ {% block custom_foot_js %} <script> var protocol_id = '#' + '{{ form.protocol.id_for_label }}'; -var private_key_id = '#' + '{{ form.private_key_file.id_for_label }}'; +var private_key_id = '#' + '{{ form.private_key.id_for_label }}'; var port = '#' + '{{ form.port.id_for_label }}'; var username = '#' + '{{ form.username.id_for_label }}'; var password = '#' + '{{ form.password.id_for_label }}'; @@ -99,7 +99,7 @@ $(document).ready(function(){ evt.preventDefault(); var form = $("form"); var data = form.serializeObject(); - data["private_key"] = $("#id_private_key_file").data('file'); + data["private_key"] = $("#id_private_key").data('file'); var method = "POST"; var the_url = '{% url "api-assets:gateway-list" %}'; var redirect_to = '{% url "assets:domain-gateway-list" pk=DEFAULT_PK %}'.replace("{{ DEFAULT_PK }}", data.domain); @@ -116,9 +116,9 @@ $(document).ready(function(){ }; formSubmit(props); }) -.on('change', '#id_private_key_file', function () { +.on('change', '#id_private_key', function () { readFile($(this)).on("onload", function (evt, data) { - $(this).attr("data-file", data) + $(this).data("file", data) }) }) .on('change', protocol_id, function(){ diff --git a/apps/assets/templates/assets/system_user_update.html b/apps/assets/templates/assets/system_user_update.html index 4414d3dcf..0a60d3e70 100644 --- a/apps/assets/templates/assets/system_user_update.html +++ b/apps/assets/templates/assets/system_user_update.html @@ -5,7 +5,7 @@ {% block auth %} {% bootstrap_field form.password layout="horizontal" %} - {% bootstrap_field form.private_key_file layout="horizontal" %} + {% bootstrap_field form.private_key layout="horizontal" %} <div class="form-group"> <label for="{{ form.as_push.id_for_label }}" class="col-sm-2 control-label">{% trans 'Auto push' %}</label> <div class="col-sm-8"> diff --git a/apps/locale/zh/LC_MESSAGES/django.mo b/apps/locale/zh/LC_MESSAGES/django.mo index a19a73d5b..9784c66ae 100644 Binary files a/apps/locale/zh/LC_MESSAGES/django.mo and b/apps/locale/zh/LC_MESSAGES/django.mo differ diff --git a/apps/locale/zh/LC_MESSAGES/django.po b/apps/locale/zh/LC_MESSAGES/django.po index fe50f06d6..d08c2b282 100644 --- a/apps/locale/zh/LC_MESSAGES/django.po +++ b/apps/locale/zh/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Jumpserver 0.3.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2019-07-16 17:04+0800\n" +"POT-Creation-Date: 2019-07-17 13:09+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: ibuler <ibuler@qq.com>\n" "Language-Team: Jumpserver team<ibuler@qq.com>\n" @@ -695,7 +695,7 @@ msgstr "如果有多个的互相隔离的网络,设置资产属于的网域, msgid "Select assets" msgstr "选择资产" -#: assets/forms/cmd_filter.py:38 assets/serializers/cmd_filter.py:43 +#: assets/forms/cmd_filter.py:38 assets/serializers/cmd_filter.py:44 msgid "Content should not be contain: {}" msgstr "内容不能包含: {}" @@ -1230,6 +1230,11 @@ msgid "Public key" msgstr "ssh公钥" #: assets/serializers/base.py:44 +msgid "" +"Not support openssh format key, using ssh-keygen -t rsa -m pem to generate" +msgstr "暂不支持OPENSSH格式的密钥,使用 ssh-keygen -t rsa -m pem生成" + +#: assets/serializers/base.py:50 msgid "private key invalid" msgstr "密钥不合法" @@ -1249,86 +1254,86 @@ msgstr "自动登录模式,必须填写用户名" msgid "Password or private key required" msgstr "密码或密钥密码需要一个" -#: assets/tasks.py:34 +#: assets/tasks.py:33 msgid "Asset has been disabled, skipped: {}" msgstr "资产或许不支持ansible, 跳过: {}" -#: assets/tasks.py:38 +#: assets/tasks.py:37 msgid "Asset may not be support ansible, skipped: {}" msgstr "资产或许不支持ansible, 跳过: {}" -#: assets/tasks.py:51 +#: assets/tasks.py:50 msgid "No assets matched, stop task" msgstr "没有匹配到资产,结束任务" -#: assets/tasks.py:61 +#: assets/tasks.py:60 msgid "No assets matched related system user protocol, stop task" msgstr "没有匹配到与系统用户协议相关的资产,结束任务" -#: assets/tasks.py:87 +#: assets/tasks.py:86 msgid "Get asset info failed: {}" msgstr "获取资产信息失败:{}" -#: assets/tasks.py:137 +#: assets/tasks.py:136 msgid "Update some assets hardware info" msgstr "更新资产硬件信息" -#: assets/tasks.py:154 +#: assets/tasks.py:153 msgid "Update asset hardware info: {}" msgstr "更新资产硬件信息: {}" -#: assets/tasks.py:179 +#: assets/tasks.py:178 msgid "Test assets connectivity" msgstr "测试资产可连接性" -#: assets/tasks.py:233 +#: assets/tasks.py:232 msgid "Test assets connectivity: {}" msgstr "测试资产可连接性: {}" -#: assets/tasks.py:275 +#: assets/tasks.py:274 msgid "Test admin user connectivity period: {}" msgstr "定期测试管理账号可连接性: {}" -#: assets/tasks.py:282 +#: assets/tasks.py:281 msgid "Test admin user connectivity: {}" msgstr "测试管理行号可连接性: {}" -#: assets/tasks.py:350 +#: assets/tasks.py:349 msgid "Test system user connectivity: {}" msgstr "测试系统用户可连接性: {}" -#: assets/tasks.py:357 +#: assets/tasks.py:356 msgid "Test system user connectivity: {} => {}" msgstr "测试系统用户可连接性: {} => {}" -#: assets/tasks.py:370 +#: assets/tasks.py:369 msgid "Test system user connectivity period: {}" msgstr "定期测试系统用户可连接性: {}" -#: assets/tasks.py:471 assets/tasks.py:557 +#: assets/tasks.py:470 assets/tasks.py:556 #: xpack/plugins/change_auth_plan/models.py:522 msgid "The asset {} system platform {} does not support run Ansible tasks" msgstr "资产 {} 系统平台 {} 不支持运行 Ansible 任务" -#: assets/tasks.py:483 +#: assets/tasks.py:482 msgid "" "Push system user task skip, auto push not enable or protocol is not ssh or " "rdp: {}" msgstr "推送系统用户任务跳过,自动推送没有打开,或协议不是ssh或rdp: {}" -#: assets/tasks.py:490 +#: assets/tasks.py:489 msgid "For security, do not push user {}" msgstr "为了安全,禁止推送用户 {}" -#: assets/tasks.py:518 assets/tasks.py:532 +#: assets/tasks.py:517 assets/tasks.py:531 msgid "Push system users to assets: {}" msgstr "推送系统用户到入资产: {}" -#: assets/tasks.py:524 +#: assets/tasks.py:523 msgid "Push system users to asset: {} => {}" msgstr "推送系统用户到入资产: {} => {}" -#: assets/tasks.py:604 +#: assets/tasks.py:603 msgid "Test asset user connectivity: {}" msgstr "测试资产用户可连接性: {}"