Unverified Commit 3855fecc authored by 老广's avatar 老广 Committed by GitHub

Password message (#2702)

* [Update] 密码信封

* [Update]  查看密码

* [Update] 支持查看密码

* [Update] 修改语言翻译

* [Update] 迁移ansible到2.8版本

* [Update] 修改auth book的可连接性

* [Update] 删除不使用的方法
parent 466b922e
......@@ -78,7 +78,7 @@ class AuthBook(AssetUser):
if host == self.asset.hostname:
_connectivity = self.UNREACHABLE
for host in value.get('contacted', {}).keys():
for host in value.get('contacted', []):
if host == self.asset.hostname:
_connectivity = self.REACHABLE
......
{% extends '_modal.html' %}
{% load i18n %}
{% load static %}
{% block modal_id %}asset_user_auth_view{% endblock %}
{% block modal_title%}{% trans "Asset user auth" %}{% endblock %}
{% block modal_body %}
<style>
.inmodal .modal-body {
background: #fff;
}
</style>
<form class="form-horizontal" action="" style="padding-top: 20px">
<div class="form-group mfa-field">
<label for="mfa" class="col-sm-2 control-label">{% trans 'MFA' %}</label>
<div class="col-sm-8">
<input type="text" id="mfa" class="form-control input-sm" name="mfa">
<span id="mfa_error" class="help-block">{% trans "Need otp auth for view auth" %}</span>
</div>
<div class="col-sm-2">
<a class="btn btn-primary btn-sm btn-mfa">{% trans "Confirm" %}</a>
</div>
</div>
<div hidden class="auth-field">
<div class="form-group">
<label for="" class="col-sm-2 control-label">{% trans 'Hostname' %}</label>
<div class="col-sm-8">
<p class="form-control-static" id="id_hostname_view"></p>
</div>
</div>
<div class="form-group">
<label for="" class="col-sm-2 control-label">{% trans 'Username' %}</label>
<div class="col-sm-8" >
<p class="form-control-static" id="id_username_view"></p>
</div>
</div>
<div class="form-group">
<label for="" class="col-sm-2 control-label">{% trans 'Password' %}</label>
<div class="col-sm-8">
<input id="id_password_view" type="password" class="form-control" value="" readonly style="border: none;padding-left: 0;background-color: #fff;width: 100%">
</div>
<div class="col-sm-2" style="padding-left: 2px">
<a class="btn btn-white btn-sm btn-show-password"><i class="fa fa-eye"></i></a>
<a class="btn btn-white btn-sm btn-copy-password"><i class="fa fa-copy"></i></a>
</div>
</div>
</div>
</form>
<script src="{% static "js/plugins/clipboard/clipboard.min.js" %}"></script>
<script>
var showPassword = false;
var lastMFATime = "{{ request.session.OTP_LAST_VERIFY_TIME }}";
var asset_id = "";
var host = "";
var username = "";
function initClipboard() {
var clipboard = new Clipboard('.btn-copy-password', {
text: function (trigger) {
return $("#id_password_view").val()
}
});
clipboard.on("success", function (e) {
toastr.success("{% trans "Copy success" %}")
})
}
function showAuth() {
$(".mfa-field").hide();
$(".auth-field").show();
var url = "{% url "api-assets:asset-user-auth-info" %}?asset_id=" + asset_id + "&username=" + username;
$("#id_username_view").html(username);
$("#id_hostname_view").html(host);
var success = function (data) {
var password = data.password;
$("#id_password_view").val(password);
};
var error = function() {
var msg = "{% trans 'Get auth info error' %}";
toastr.error(msg)
};
APIUpdateAttr({
url: url,
method: "GET",
success: success,
flash_message: false,
error: error
})
}
function showMFA() {
$(".mfa-field").show();
$(".auth-field").hide();
}
$(document).ready(function () {
initClipboard();
}).on("click", ".btn-show-password", function () {
showPassword = !showPassword;
if (showPassword) {
$("#id_password_view").attr("type", "text")
} else {
$("#id_password_view").attr("type", "password")
}
}).on("show.bs.modal", "#asset_user_auth_view", function () {
var now = new Date();
if (lastMFATime === "") {
lastMFATime = 0
}
var nowTime = now.getTime() / 1000;
if (nowTime - lastMFATime < 60*10 ) {
showAuth();
}
}).on("click", ".btn-mfa", function () {
var url = "{% url 'api-auth:user-otp-verify' %}";
var data = {
code: $("#mfa").val()
};
var success = function () {
var now = new Date();
lastMFATime = now.getTime() / 1000;
showAuth()
};
var error = function () {
$("#mfa_error").addClass("error").html("Code error");
};
APIUpdateAttr({
url: url,
method: "POST",
body: JSON.stringify(data),
success: success,
flash_message: false,
error: error
})
})
</script>
{% endblock %}
{% block modal_button %}
<button data-dismiss="modal" class="btn btn-white close_btn2" type="button">{% trans "Close" %}</button>
{% endblock %}
......@@ -85,6 +85,7 @@
</div>
</div>
{% include 'assets/_asset_user_auth_modal.html' %}
{% include 'assets/_asset_user_view_auth_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
<script>
......@@ -112,9 +113,12 @@ function initTable() {
}
}},
{targets: 4, createdCell: function (td, cellData, rowData) {
var btn = ' <a class="btn btn-xs btn-primary btn-update-asset-user-auth" data-aid="{{ DEFAULT_PK }}" data-hostname="hostname777">{% trans "Update auth" %}</a>'.replace("{{ DEFAULT_PK }}", cellData).replace("hostname777", rowData.hostname);
var view_btn = ' <a class="btn btn-xs btn-primary btn-view-auth" data-aid="{{ DEFAULT_PK }}" data-hostname="hostname777">{% trans "View auth" %}</a>'.replace("{{ DEFAULT_PK }}", cellData).replace("hostname777", rowData.hostname);
var test_btn = ' <a class="btn btn-xs btn-info btn-test-asset" data-uid="{{ DEFAULT_PK }}" >{% trans "Test" %}</a>'.replace("{{ DEFAULT_PK }}", cellData);
var update_auth_btn = ' <a class="btn btn-xs btn-primary btn-update-asset-user-auth" data-aid="{{ DEFAULT_PK }}" data-hostname="hostname777">{% trans "Update auth" %}</a>'.replace("{{ DEFAULT_PK }}", cellData).replace("hostname777", rowData.hostname);
$(td).html(test_btn + update_auth_btn);
btn += view_btn;
btn += test_btn;
$(td).html(btn);
}}
],
......@@ -201,5 +205,11 @@ $(document).ready(function () {
$('#id_password').parent().addClass('has-error');
}
})
.on("click", ".btn-view-auth", function (evt) {
asset_id = $(this).data("aid") ;
host = $(this).data("hostname");
username = "{{ admin_user.username }}";
$("#asset_user_auth_view").modal();
})
</script>
{% endblock %}
......@@ -2,10 +2,6 @@
{% load common_tags %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
......@@ -87,6 +83,7 @@
</div>
</div>
{% include 'assets/_asset_user_auth_modal.html' %}
{% include 'assets/_asset_user_view_auth_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
<script>
......@@ -117,14 +114,14 @@ function initAssetUserTable() {
$(td).html(cellData.slice(0, -6));
}},
{targets: 5, createdCell: function (td, cellData) {
var update_auth_btn = ' <a class="btn btn-xs btn-primary btn-update-asset-user-auth" data-username="DEFAULT_USERNAME">{% trans "Update auth" %}</a>'.replace("DEFAULT_USERNAME", cellData);
var btn = '<a class="btn btn-xs btn-primary btn-update-asset-user-auth" data-username="DEFAULT_USERNAME">{% trans "Update auth" %}</a>'.replace("DEFAULT_USERNAME", cellData);
var view_btn = ' <a class="btn btn-xs btn-primary btn-view-auth" data-username="DEFAULT_USERNAME">{% trans "View auth" %}</a>'.replace("DEFAULT_USERNAME", cellData);
var test_btn = ' <a class="btn btn-xs btn-info btn-test-connective" data-username="DEFAULT_USERNAME">{% trans "Test" %}</a>'.replace("DEFAULT_USERNAME", cellData);
btn += view_btn;
{% if asset.protocol == 'ssh' %}
var test_btn = ' <a class="btn btn-xs btn-info btn-test-connective" data-username="DEFAULT_USERNAME">{% trans "Test" %}</a>'.replace("DEFAULT_USERNAME", cellData);
$(td).html(test_btn + update_auth_btn);
{% else %}
$(td).html(update_auth_btn);
btn += test_btn;
{% endif %}
{#var check_btn = ' <a class="btn btn-xs btn-info btn-check-asset-user-auth" data-username="DEFAULT_USERNAME">{% trans "Check auth" %}</a>'.replace("DEFAULT_USERNAME", cellData);#}
$(td).html(btn);
}}
],
......@@ -142,17 +139,6 @@ var username;
$(document).ready(function () {
initAssetUserTable();
})
{#.on('click', '.btn-check-asset-user-auth', function(){#}
{# var username = $(this).data('username');#}
{# var the_url = "{% url 'api-assets:asset-user-auth-info' %}" + '?asset_id={{ asset.id }}' + '&username=' + username;#}
{# $.ajax({#}
{# url: the_url,#}
{# method: 'GET',#}
{# success: function (data) {#}
{# alert("Password: " + data.password);#}
{# }#}
{# });#}
{# })#}
.on('click', '.btn-update-asset-user-auth', function() {
username = $(this).data('username');
var hostname = "{{ asset.hostname }}";
......@@ -214,5 +200,11 @@ $(document).ready(function () {
flash_message: false
});
})
.on("click", ".btn-view-auth", function (evt) {
asset_id = "{{ asset.id }}" ;
host = "{{ asset.hostname }}";
username = $(this).data("username");
$("#asset_user_auth_view").modal();
})
</script>
{% endblock %}
\ No newline at end of file
......@@ -133,6 +133,7 @@
</div>
</div>
{% include 'assets/_asset_user_auth_modal.html' %}
{% include 'assets/_asset_user_view_auth_modal.html' %}
{% endblock %}
{% block custom_foot_js %}
<script>
......@@ -160,12 +161,13 @@ function initAssetsTable() {
{targets: 4, createdCell: function (td, cellData, rowData) {
var push_btn = '';
{% if system_user.auto_push %}
push_btn = '<a class="btn btn-xs btn-primary btn-push-asset" data-uid="{{ DEFAULT_PK }}" >{% trans "Push" %}</a>'.replace("{{ DEFAULT_PK }}", cellData);
push_btn = ' <a class="btn btn-xs btn-primary btn-push-asset" data-uid="{{ DEFAULT_PK }}" >{% trans "Push" %}</a>'.replace("{{ DEFAULT_PK }}", cellData);
{% endif %}
var test_btn = ' <a class="btn btn-xs btn-info btn-test-asset" data-uid="{{ DEFAULT_PK }}" >{% trans "Test" %}</a>'.replace("{{ DEFAULT_PK }}", cellData);
var view_btn = ' <a class="btn btn-xs btn-primary btn-view-auth" data-aid="{{ DEFAULT_PK }}" data-hostname="hostname777">{% trans "View auth" %}</a>'.replace("{{ DEFAULT_PK }}", cellData).replace("hostname777", rowData.hostname);
{#var unbound_btn = '<a class="btn btn-xs btn-danger m-l-xs btn-asset-unbound" data-uid="{{ DEFAULT_PK }}">{% trans "Unbound" %}</a>'.replace('{{ DEFAULT_PK }}', cellData);#}
var update_auth_btn = ' <a class="btn btn-xs btn-primary btn-update-asset-user-auth" data-aid="{{ DEFAULT_PK }}" data-hostname="hostname777">{% trans "Update auth" %}</a>'.replace("{{ DEFAULT_PK }}", cellData).replace("hostname777", rowData.hostname);
$(td).html(push_btn + test_btn + update_auth_btn);
$(td).html(update_auth_btn + view_btn + push_btn + test_btn);
}}
],
ajax_url: '{% url "api-assets:system-user-assets" pk=system_user.id %}',
......@@ -360,5 +362,11 @@ $(document).ready(function () {
$('#id_password').parent().addClass('has-error');
}
})
.on("click", ".btn-view-auth", function (evt) {
asset_id = $(this).data("aid") ;
host = $(this).data("hostname");
username = "{{ system_user.username }}";
$("#asset_user_auth_view").modal();
})
</script>
{% endblock %}
......@@ -2,6 +2,7 @@
#
import uuid
import time
from django.core.cache import cache
from django.urls import reverse
......@@ -10,10 +11,11 @@ from django.utils.translation import ugettext as _
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework.generics import CreateAPIView
from rest_framework.views import APIView
from common.utils import get_logger, get_request_ip
from common.permissions import IsOrgAdminOrAppUser
from common.permissions import IsOrgAdminOrAppUser, IsValidUser
from orgs.mixins import RootOrgViewMixin
from users.serializers import UserSerializer
from users.models import User
......@@ -23,12 +25,13 @@ from users.utils import (
check_user_valid, check_otp_code, increase_login_failed_count,
is_block_login, clean_failed_count
)
from ..serializers import OtpVerifySerializer
from ..signals import post_auth_success, post_auth_failed
logger = get_logger(__name__)
__all__ = [
'UserAuthApi', 'UserConnectionTokenApi', 'UserOtpAuthApi',
'UserOtpVerifyApi',
]
......@@ -179,3 +182,20 @@ class UserOtpAuthApi(RootOrgViewMixin, APIView):
sender=self.__class__, username=username,
request=self.request, reason=reason
)
class UserOtpVerifyApi(CreateAPIView):
permission_classes = (IsValidUser,)
serializer_class = OtpVerifySerializer
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
code = serializer.validated_data["code"]
if request.user.check_otp(code):
request.session["OTP_LAST_VERIFY_TIME"] = int(time.time())
return Response({"ok": "1"})
else:
return Response({"error": "Code not valid"}, status=400)
......@@ -14,3 +14,7 @@ class AccessKeySerializer(serializers.ModelSerializer):
model = AccessKey
fields = ['id', 'secret']
read_only_fields = ['id', 'secret']
class OtpVerifySerializer(serializers.Serializer):
code = serializers.CharField(max_length=6, min_length=6)
......@@ -16,5 +16,6 @@ urlpatterns = [
path('connection-token/',
api.UserConnectionTokenApi.as_view(), name='connection-token'),
path('otp/auth/', api.UserOtpAuthApi.as_view(), name='user-otp-auth'),
path('otp/verify/', api.UserOtpVerifyApi.as_view(), name='user-otp-verify'),
]
# -*- coding: utf-8 -*-
#
import time
from rest_framework import permissions
from django.contrib.auth.mixins import UserPassesTestMixin
......
......@@ -144,6 +144,7 @@ def is_uuid(seq):
def get_request_ip(request):
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '').split(',')
if x_forwarded_for and x_forwarded_for[0]:
login_ip = x_forwarded_for[0]
else:
......
......@@ -194,7 +194,7 @@ class Config(dict):
filename = os.path.join(self.root_path, filename)
try:
with open(filename, 'rt', encoding='utf8') as f:
obj = yaml.load(f)
obj = yaml.safe_load(f)
except IOError as e:
if silent and e.errno in (errno.ENOENT, errno.EISDIR):
return False
......
......@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2019-04-29 12:22+0800\n"
"POT-Creation-Date: 2019-05-20 11:19+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"
......@@ -21,15 +21,15 @@ msgstr ""
msgid "Please select assets that need to be updated"
msgstr "请选择需要更新的资产"
#: assets/api/node.py:58
#: assets/api/node.py:60
msgid "You can't update the root node name"
msgstr "不能修改根节点名称"
#: assets/api/node.py:282
#: assets/api/node.py:285
msgid "Update node asset hardware information: {}"
msgstr "更新节点资产硬件信息: {}"
#: assets/api/node.py:296
#: assets/api/node.py:299
msgid "Test if the assets under the node are connectable: {}"
msgstr "测试节点下资产是否可连接: {}"
......@@ -45,7 +45,7 @@ msgstr "节点管理"
#: assets/models/cluster.py:19 assets/models/user.py:91
#: assets/templates/assets/asset_detail.html:80 templates/_nav.html:24
#: xpack/plugins/cloud/models.py:124
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:67
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:65
#: xpack/plugins/orgs/templates/orgs/org_list.html:18
msgid "Admin user"
msgstr "管理用户"
......@@ -81,8 +81,8 @@ msgstr "网域"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_list.html:55
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:15
#: xpack/plugins/cloud/models.py:123
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:63
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:66
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:61
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:64
msgid "Node"
msgstr "节点"
......@@ -136,7 +136,7 @@ msgstr "选择资产"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:13
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:14
#: xpack/plugins/cloud/models.py:187
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:65
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:63
#: xpack/plugins/orgs/templates/orgs/org_list.html:16
msgid "Asset"
msgstr "资产"
......@@ -188,9 +188,9 @@ msgstr "SSH网关,支持代理SSH,RDP和VNC"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:61
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:12
#: xpack/plugins/cloud/models.py:49 xpack/plugins/cloud/models.py:119
#: xpack/plugins/cloud/templates/cloud/account_detail.html:52
#: xpack/plugins/cloud/templates/cloud/account_detail.html:50
#: xpack/plugins/cloud/templates/cloud/account_list.html:12
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:55
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:53
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:12
#: xpack/plugins/orgs/templates/orgs/org_detail.html:52
#: xpack/plugins/orgs/templates/orgs/org_list.html:12
......@@ -200,9 +200,10 @@ msgstr "名称"
#: assets/forms/domain.py:74 assets/forms/user.py:85 assets/forms/user.py:147
#: assets/models/base.py:27
#: assets/templates/assets/_asset_user_auth_modal.html:15
#: assets/templates/assets/_asset_user_view_auth_modal.html:31
#: assets/templates/assets/admin_user_detail.html:60
#: assets/templates/assets/admin_user_list.html:27
#: assets/templates/assets/asset_asset_user_list.html:48
#: assets/templates/assets/asset_asset_user_list.html:44
#: assets/templates/assets/domain_gateway_list.html:71
#: assets/templates/assets/system_user_detail.html:62
#: assets/templates/assets/system_user_list.html:30 audits/models.py:94
......@@ -233,6 +234,7 @@ msgstr "密码或密钥密码"
#: assets/forms/user.py:26 assets/models/base.py:28
#: assets/serializers/asset_user.py:19
#: assets/templates/assets/_asset_user_auth_modal.html:21
#: assets/templates/assets/_asset_user_view_auth_modal.html:37
#: authentication/forms.py:13
#: authentication/templates/authentication/login.html:67
#: authentication/templates/authentication/new_login.html:93
......@@ -313,6 +315,7 @@ msgstr "IP"
#: assets/models/asset.py:75 assets/templates/assets/_asset_list_modal.html:45
#: assets/templates/assets/_asset_user_auth_modal.html:9
#: assets/templates/assets/_asset_user_view_auth_modal.html:25
#: assets/templates/assets/admin_user_assets.html:48
#: assets/templates/assets/asset_detail.html:60
#: assets/templates/assets/asset_list.html:92
......@@ -461,8 +464,8 @@ msgstr "创建者"
#: users/templates/users/user_group_detail.html:63
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:105
#: xpack/plugins/cloud/models.py:56 xpack/plugins/cloud/models.py:128
#: xpack/plugins/cloud/templates/cloud/account_detail.html:68
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:79
#: xpack/plugins/cloud/templates/cloud/account_detail.html:66
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:77
#: xpack/plugins/orgs/templates/orgs/org_detail.html:60
msgid "Date created"
msgstr "创建日期"
......@@ -495,9 +498,9 @@ msgstr "创建日期"
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:117
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:19
#: xpack/plugins/cloud/models.py:54 xpack/plugins/cloud/models.py:125
#: xpack/plugins/cloud/templates/cloud/account_detail.html:72
#: xpack/plugins/cloud/templates/cloud/account_detail.html:70
#: xpack/plugins/cloud/templates/cloud/account_list.html:15
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:71
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:69
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:16
#: xpack/plugins/orgs/templates/orgs/org_detail.html:64
#: xpack/plugins/orgs/templates/orgs/org_list.html:22
......@@ -513,7 +516,7 @@ msgstr "不可达"
#: assets/models/asset.py:118 assets/models/base.py:39
#: assets/templates/assets/admin_user_assets.html:51
#: assets/templates/assets/admin_user_list.html:29
#: assets/templates/assets/asset_asset_user_list.html:50
#: assets/templates/assets/asset_asset_user_list.html:46
#: assets/templates/assets/asset_list.html:95
#: assets/templates/assets/system_user_asset.html:53
#: assets/templates/assets/system_user_list.html:34
......@@ -584,7 +587,7 @@ msgid "Default"
msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:14
#: users/models/user.py:475
#: users/models/user.py:479
msgid "System"
msgstr "系统"
......@@ -665,7 +668,7 @@ msgstr "每行一个命令"
#: assets/models/cmd_filter.py:54
#: assets/templates/assets/admin_user_assets.html:52
#: assets/templates/assets/admin_user_list.html:33
#: assets/templates/assets/asset_asset_user_list.html:52
#: assets/templates/assets/asset_asset_user_list.html:48
#: assets/templates/assets/asset_list.html:96
#: assets/templates/assets/cmd_filter_list.html:28
#: assets/templates/assets/cmd_filter_rule_list.html:63
......@@ -735,7 +738,7 @@ msgstr "默认资产组"
#: terminal/templates/terminal/command_list.html:72
#: terminal/templates/terminal/session_list.html:33
#: terminal/templates/terminal/session_list.html:71 users/forms.py:283
#: users/models/user.py:36 users/models/user.py:463
#: users/models/user.py:36 users/models/user.py:467
#: users/templates/users/user_group_detail.html:78
#: users/templates/users/user_group_list.html:13 users/views/user.py:395
#: xpack/plugins/orgs/forms.py:26
......@@ -757,7 +760,7 @@ msgstr "分类"
msgid "Key"
msgstr "键"
#: assets/models/node.py:128
#: assets/models/node.py:133
msgid "New node"
msgstr "新节点"
......@@ -975,6 +978,61 @@ msgstr "更新资产用户认证信息"
msgid "Please input password"
msgstr "请输入密码"
#: assets/templates/assets/_asset_user_view_auth_modal.html:5
msgid "Asset user auth"
msgstr "资产用户信息"
#: assets/templates/assets/_asset_user_view_auth_modal.html:14
#: assets/templates/assets/_otp_verify_modal.html:8 audits/models.py:99
#: audits/templates/audits/login_log_list.html:56 users/forms.py:142
#: users/models/user.py:83 users/templates/users/first_login.html:45
msgid "MFA"
msgstr "MFA"
#: assets/templates/assets/_asset_user_view_auth_modal.html:17
msgid "Need otp auth for view auth"
msgstr "需要二次认证来查看账号信息"
#: assets/templates/assets/_asset_user_view_auth_modal.html:20
#: assets/templates/assets/admin_user_detail.html:100
#: assets/templates/assets/asset_detail.html:211
#: assets/templates/assets/asset_list.html:637
#: assets/templates/assets/cmd_filter_detail.html:106
#: assets/templates/assets/system_user_asset.html:112
#: assets/templates/assets/system_user_detail.html:182
#: assets/templates/assets/system_user_list.html:144
#: settings/templates/settings/terminal_setting.html:165
#: templates/_modal.html:23 terminal/templates/terminal/session_detail.html:108
#: users/templates/users/user_detail.html:388
#: users/templates/users/user_detail.html:414
#: users/templates/users/user_detail.html:437
#: users/templates/users/user_detail.html:482
#: users/templates/users/user_group_create_update.html:32
#: users/templates/users/user_group_list.html:90
#: users/templates/users/user_list.html:215
#: users/templates/users/user_profile.html:238
#: xpack/plugins/cloud/templates/cloud/account_create_update.html:34
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create.html:36
#: xpack/plugins/interface/templates/interface/interface.html:103
#: xpack/plugins/orgs/templates/orgs/org_create_update.html:33
msgid "Confirm"
msgstr "确认"
#: assets/templates/assets/_asset_user_view_auth_modal.html:63
msgid "Copy success"
msgstr "复制成功"
#: assets/templates/assets/_asset_user_view_auth_modal.html:79
msgid "Get auth info error"
msgstr "获取认证信息错误"
#: assets/templates/assets/_asset_user_view_auth_modal.html:139
#: assets/templates/assets/_user_asset_detail_modal.html:23
#: settings/templates/settings/_ldap_list_users_modal.html:96
#: templates/_modal.html:22
msgid "Close"
msgstr "关闭"
#: assets/templates/assets/_gateway_test_modal.html:4
msgid "Test gateway test connection"
msgstr "测试连接网关"
......@@ -987,6 +1045,10 @@ msgstr "SSH端口"
msgid "If use nat, set the ssh real port"
msgstr "如果使用了nat端口映射,请设置为ssh真实监听的端口"
#: assets/templates/assets/_otp_verify_modal.html:4
msgid "MFA Confirm"
msgstr "确认"
#: assets/templates/assets/_system_user.html:37
#: assets/templates/assets/asset_create.html:16
#: assets/templates/assets/asset_update.html:21
......@@ -1088,17 +1150,11 @@ msgid "Submit"
msgstr "提交"
#: assets/templates/assets/_user_asset_detail_modal.html:11
#: assets/templates/assets/asset_asset_user_list.html:17
#: assets/templates/assets/asset_asset_user_list.html:13
#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:187
msgid "Asset detail"
msgstr "资产详情"
#: assets/templates/assets/_user_asset_detail_modal.html:23
#: settings/templates/settings/_ldap_list_users_modal.html:96
#: templates/_modal.html:22
msgid "Close"
msgstr "关闭"
#: assets/templates/assets/admin_user_assets.html:18
#: assets/templates/assets/admin_user_detail.html:18
#: assets/templates/assets/cmd_filter_detail.html:19
......@@ -1140,41 +1196,47 @@ msgid "Quick update"
msgstr "快速更新"
#: assets/templates/assets/admin_user_assets.html:70
#: assets/templates/assets/asset_asset_user_list.html:71
#: assets/templates/assets/asset_asset_user_list.html:67
#: assets/templates/assets/asset_detail.html:179
msgid "Test connective"
msgstr "测试可连接性"
#: assets/templates/assets/admin_user_assets.html:73
#: assets/templates/assets/admin_user_assets.html:115
#: assets/templates/assets/asset_asset_user_list.html:74
#: assets/templates/assets/asset_asset_user_list.html:122
#: assets/templates/assets/admin_user_assets.html:118
#: assets/templates/assets/asset_asset_user_list.html:70
#: assets/templates/assets/asset_asset_user_list.html:119
#: assets/templates/assets/asset_detail.html:182
#: assets/templates/assets/system_user_asset.html:75
#: assets/templates/assets/system_user_asset.html:165
#: assets/templates/assets/system_user_asset.html:166
#: assets/templates/assets/system_user_detail.html:151
msgid "Test"
msgstr "测试"
#: assets/templates/assets/admin_user_assets.html:116
#: assets/templates/assets/asset_asset_user_list.html:120
#: assets/templates/assets/system_user_asset.html:167
#: assets/templates/assets/asset_asset_user_list.html:117
#: assets/templates/assets/system_user_asset.html:169
msgid "Update auth"
msgstr "更新认证"
#: assets/templates/assets/admin_user_assets.html:192
#: assets/templates/assets/asset_asset_user_list.html:176
#: assets/templates/assets/admin_user_assets.html:117
#: assets/templates/assets/asset_asset_user_list.html:118
#: assets/templates/assets/system_user_asset.html:167
msgid "View auth"
msgstr "查看认证"
#: assets/templates/assets/admin_user_assets.html:196
#: assets/templates/assets/asset_asset_user_list.html:162
#: assets/templates/assets/asset_detail.html:311
#: assets/templates/assets/system_user_asset.html:351
#: assets/templates/assets/system_user_asset.html:353
#: users/templates/users/user_detail.html:307
#: users/templates/users/user_detail.html:334
#: xpack/plugins/interface/views.py:34
msgid "Update successfully!"
msgstr "更新成功"
#: assets/templates/assets/admin_user_assets.html:195
#: assets/templates/assets/asset_asset_user_list.html:179
#: assets/templates/assets/system_user_asset.html:354
#: assets/templates/assets/admin_user_assets.html:199
#: assets/templates/assets/asset_asset_user_list.html:165
#: assets/templates/assets/system_user_asset.html:356
msgid "Update failed!"
msgstr "更新失败"
......@@ -1205,11 +1267,11 @@ msgstr "更新失败"
#: users/templates/users/user_profile.html:187
#: users/templates/users/user_profile.html:196
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:29
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:54
#: xpack/plugins/cloud/templates/cloud/account_detail.html:25
#: xpack/plugins/cloud/templates/cloud/account_list.html:38
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:55
#: xpack/plugins/cloud/templates/cloud/account_detail.html:23
#: xpack/plugins/cloud/templates/cloud/account_list.html:39
#: xpack/plugins/orgs/templates/orgs/org_detail.html:25
#: xpack/plugins/orgs/templates/orgs/org_list.html:85
#: xpack/plugins/orgs/templates/orgs/org_list.html:87
msgid "Update"
msgstr "更新"
......@@ -1239,13 +1301,13 @@ msgstr "更新"
#: users/templates/users/user_list.html:91
#: users/templates/users/user_list.html:95
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:33
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:56
#: xpack/plugins/cloud/templates/cloud/account_detail.html:29
#: xpack/plugins/cloud/templates/cloud/account_list.html:40
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:32
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:54
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:57
#: xpack/plugins/cloud/templates/cloud/account_detail.html:27
#: xpack/plugins/cloud/templates/cloud/account_list.html:41
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:30
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:55
#: xpack/plugins/orgs/templates/orgs/org_detail.html:29
#: xpack/plugins/orgs/templates/orgs/org_list.html:87
#: xpack/plugins/orgs/templates/orgs/org_list.html:89
msgid "Delete"
msgstr "删除"
......@@ -1260,30 +1322,6 @@ msgstr "替换资产的管理员"
msgid "Select nodes"
msgstr "选择节点"
#: assets/templates/assets/admin_user_detail.html:100
#: assets/templates/assets/asset_detail.html:211
#: assets/templates/assets/asset_list.html:637
#: assets/templates/assets/cmd_filter_detail.html:106
#: assets/templates/assets/system_user_asset.html:112
#: assets/templates/assets/system_user_detail.html:182
#: assets/templates/assets/system_user_list.html:144
#: settings/templates/settings/terminal_setting.html:165
#: templates/_modal.html:23 terminal/templates/terminal/session_detail.html:108
#: users/templates/users/user_detail.html:388
#: users/templates/users/user_detail.html:414
#: users/templates/users/user_detail.html:437
#: users/templates/users/user_detail.html:482
#: users/templates/users/user_group_create_update.html:32
#: users/templates/users/user_group_list.html:90
#: users/templates/users/user_list.html:215
#: users/templates/users/user_profile.html:238
#: xpack/plugins/cloud/templates/cloud/account_create_update.html:34
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_create.html:36
#: xpack/plugins/interface/templates/interface/interface.html:103
#: xpack/plugins/orgs/templates/orgs/org_create_update.html:33
msgid "Confirm"
msgstr "确认"
#: assets/templates/assets/admin_user_list.html:10
msgid ""
"Admin users are asset (charged server) on the root, or have NOPASSWD: ALL "
......@@ -1313,26 +1351,26 @@ msgstr "创建管理用户"
msgid "Ratio"
msgstr "比例"
#: assets/templates/assets/asset_asset_user_list.html:20
#: assets/templates/assets/asset_asset_user_list.html:16
#: assets/templates/assets/asset_detail.html:23 assets/views/asset.py:68
msgid "Asset user list"
msgstr "资产用户列表"
#: assets/templates/assets/asset_asset_user_list.html:28
#: assets/templates/assets/asset_asset_user_list.html:24
msgid "Asset users of"
msgstr "资产用户"
#: assets/templates/assets/asset_asset_user_list.html:49
#: assets/templates/assets/asset_asset_user_list.html:45
msgid "Password version"
msgstr "密码版本"
#: assets/templates/assets/asset_asset_user_list.html:51
#: assets/templates/assets/asset_asset_user_list.html:47
#: assets/templates/assets/cmd_filter_detail.html:73
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:109
msgid "Date updated"
msgstr "更新日期"
#: assets/templates/assets/asset_asset_user_list.html:64
#: assets/templates/assets/asset_asset_user_list.html:60
#: assets/templates/assets/asset_detail.html:148
#: terminal/templates/terminal/session_detail.html:81
#: users/templates/users/user_detail.html:138
......@@ -1672,7 +1710,7 @@ msgid "Push system user now"
msgstr "立刻推送系统"
#: assets/templates/assets/system_user_asset.html:84
#: assets/templates/assets/system_user_asset.html:163
#: assets/templates/assets/system_user_asset.html:164
#: assets/templates/assets/system_user_detail.html:142
msgid "Push"
msgstr "推送"
......@@ -1948,12 +1986,6 @@ msgstr "登录城市"
msgid "User agent"
msgstr "Agent"
#: audits/models.py:99 audits/templates/audits/login_log_list.html:56
#: users/forms.py:142 users/models/user.py:83
#: users/templates/users/first_login.html:45
msgid "MFA"
msgstr "MFA"
#: audits/models.py:100 audits/templates/audits/login_log_list.html:57
#: xpack/plugins/change_auth_plan/models.py:413
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_execution_subtask_list.html:15
......@@ -1965,7 +1997,7 @@ msgstr "原因"
#: audits/models.py:101 audits/templates/audits/login_log_list.html:58
#: xpack/plugins/cloud/models.py:171 xpack/plugins/cloud/models.py:188
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:70
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:67
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:65
msgid "Status"
msgstr "状态"
......@@ -2003,7 +2035,7 @@ msgstr "选择用户"
#: terminal/templates/terminal/command_list.html:60
#: terminal/templates/terminal/session_list.html:61
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:52
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:50
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:48
msgid "Search"
msgstr "搜索"
......@@ -2013,7 +2045,7 @@ msgstr "搜索"
#: ops/templates/ops/task_detail.html:56
#: terminal/templates/terminal/session_list.html:70
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:64
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:62
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:60
msgid "ID"
msgstr "ID"
......@@ -2063,25 +2095,25 @@ msgstr "登录日志"
msgid "Command execution log"
msgstr "命令执行"
#: authentication/api/auth.py:46
#: authentication/api/auth.py:49
#: authentication/templates/authentication/login.html:52
#: authentication/templates/authentication/new_login.html:77
msgid "Log in frequently and try again later"
msgstr "登录频繁, 稍后重试"
#: authentication/api/auth.py:64
#: authentication/api/auth.py:67
msgid "The user {} password has expired, please update."
msgstr "用户 {} 密码已经过期,请更新。"
#: authentication/api/auth.py:83
#: authentication/api/auth.py:86
msgid "Please carry seed value and conduct MFA secondary certification"
msgstr "请携带seed值, 进行MFA二次认证"
#: authentication/api/auth.py:163
#: authentication/api/auth.py:166
msgid "Please verify the user name and password first"
msgstr "请先进行用户名和密码验证"
#: authentication/api/auth.py:168
#: authentication/api/auth.py:171
msgid "MFA certification failed"
msgstr "MFA认证失败"
......@@ -2415,7 +2447,7 @@ msgid "Become"
msgstr "Become"
#: ops/models/adhoc.py:166 users/templates/users/user_group_detail.html:59
#: xpack/plugins/cloud/templates/cloud/account_detail.html:64
#: xpack/plugins/cloud/templates/cloud/account_detail.html:62
#: xpack/plugins/orgs/templates/orgs/org_detail.html:56
msgid "Create by"
msgstr "创建者"
......@@ -2661,8 +2693,8 @@ msgstr "版本"
#: ops/templates/ops/task_list.html:63
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_detail.html:137
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:52
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:52
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:53
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:53
msgid "Run"
msgstr "执行"
......@@ -2828,7 +2860,7 @@ msgstr "创建授权规则"
#: perms/templates/perms/asset_permission_list.html:59
#: perms/templates/perms/asset_permission_list.html:73
#: users/templates/users/user_list.html:28 xpack/plugins/cloud/models.py:53
#: xpack/plugins/cloud/templates/cloud/account_detail.html:60
#: xpack/plugins/cloud/templates/cloud/account_detail.html:58
#: xpack/plugins/cloud/templates/cloud/account_list.html:14
msgid "Validity"
msgstr "有效"
......@@ -3283,8 +3315,8 @@ msgstr "端点后缀"
#: settings/templates/settings/replay_storage_create.html:136
#: xpack/plugins/cloud/models.py:186
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:83
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:64
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:81
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:62
msgid "Region"
msgstr "地域"
......@@ -3999,7 +4031,7 @@ msgstr "复制你的公钥到这里"
msgid "Select users"
msgstr "选择用户"
#: users/models/user.py:35 users/models/user.py:471
#: users/models/user.py:35 users/models/user.py:475
msgid "Administrator"
msgstr "管理员"
......@@ -4045,7 +4077,7 @@ msgstr "最后更新密码日期"
msgid "User auth from {}, go there change password"
msgstr "用户认证源来自 {}, 请去相应系统修改密码"
#: users/models/user.py:474
#: users/models/user.py:478
msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员"
......@@ -4064,7 +4096,7 @@ msgstr "安全令牌验证"
#: users/templates/users/_base_otp.html:44 users/templates/users/_user.html:13
#: users/templates/users/user_profile_update.html:51
#: xpack/plugins/cloud/models.py:120
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:59
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:57
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:13
msgid "Account"
msgstr "账户"
......@@ -4947,7 +4979,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:101
#: xpack/plugins/change_auth_plan/templates/change_auth_plan/plan_list.html:102
msgid "Execute failed"
msgstr "执行失败"
......@@ -5033,7 +5065,7 @@ msgid "Unavailable"
msgstr "无效"
#: xpack/plugins/cloud/models.py:50
#: xpack/plugins/cloud/templates/cloud/account_detail.html:56
#: xpack/plugins/cloud/templates/cloud/account_detail.html:54
#: xpack/plugins/cloud/templates/cloud/account_list.html:13
msgid "Provider"
msgstr "云服务商"
......@@ -5059,7 +5091,7 @@ msgid "Instances"
msgstr "实例"
#: xpack/plugins/cloud/models.py:126
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:75
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:73
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:17
msgid "Date last sync"
msgstr "最后同步日期"
......@@ -5078,7 +5110,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:68
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:66
msgid "Date sync"
msgstr "同步日期"
......@@ -5095,8 +5127,8 @@ msgid "Sync instance task history"
msgstr "同步实例任务历史"
#: xpack/plugins/cloud/models.py:185
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:91
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:63
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:89
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:61
msgid "Instance"
msgstr "实例"
......@@ -5116,7 +5148,7 @@ msgstr "AWS (国际)"
msgid "Qcloud"
msgstr "腾讯云"
#: xpack/plugins/cloud/templates/cloud/account_detail.html:22
#: xpack/plugins/cloud/templates/cloud/account_detail.html:20
#: xpack/plugins/cloud/views.py:72
msgid "Account detail"
msgstr "账户详情"
......@@ -5134,23 +5166,23 @@ msgstr "加载中..."
msgid "Load failed"
msgstr "加载失败"
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:22
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:20
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:25
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:23
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:21
#: xpack/plugins/cloud/views.py:122
msgid "Sync task detail"
msgstr "同步任务详情"
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:25
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:23
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:28
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:26
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:24
#: xpack/plugins/cloud/views.py:137
msgid "Sync task history"
msgstr "同步历史列表"
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:28
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_detail.html:26
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_history.html:31
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:29
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_instance.html:27
#: xpack/plugins/cloud/views.py:188
msgid "Sync instance list"
msgstr "同步实例列表"
......@@ -5183,7 +5215,7 @@ msgstr "执行次数"
msgid "Instance count"
msgstr "实例个数"
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:92
#: xpack/plugins/cloud/templates/cloud/sync_instance_task_list.html:93
msgid "Sync success"
msgstr "同步成功"
......@@ -5267,6 +5299,7 @@ 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 "恢复默认成功!"
......@@ -5279,13 +5312,9 @@ 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
......@@ -5423,6 +5452,22 @@ msgstr "创建组织"
msgid "Update org"
msgstr "更新组织"
#~ msgid "Monitor"
#~ msgstr "监控"
#, fuzzy
#~| msgid "Select user"
#~ msgid "Select time"
#~ msgstr "选择用户"
#, fuzzy
#~| msgid "Select Asset"
#~ msgid "Select host"
#~ msgstr "选择资产"
#~ msgid "Restore default successfully!"
#~ msgstr "恢复默认成功!"
#~ msgid "Beijing Duizhan Tech, Inc."
#~ msgstr "北京堆栈科技有限公司"
......@@ -5453,9 +5498,6 @@ msgstr "更新组织"
#~ "object has no attribute 'keys'"
#~ msgstr "导入 {} 个用户成功; 导入 {} 这些用户失败,因为对象没有属性'keys'"
#~ msgid "Monitor"
#~ msgstr "监控"
#~ msgid "Invalid private key"
#~ msgstr "ssh密钥不合法"
......@@ -5549,9 +5591,6 @@ msgstr "更新组织"
#~ "Are you sure to remove authentication information for the system user ?"
#~ msgstr "你确定清除该系统用户的认证信息吗 ?"
#~ msgid "Clear auth"
#~ msgstr "清除认证信息"
#~ msgid "success"
#~ msgstr "成功"
......
......@@ -124,6 +124,9 @@ class AdHocResultCallback(CallbackMixin, CallbackModule, CMDCallBackModule):
def display_ok_hosts(self):
pass
def display_failed_stderr(self):
pass
class CommandResultCallback(AdHocResultCallback):
"""
......
# ~*~ coding: utf-8 ~*~
import os
import shutil
from collections import namedtuple
from ansible import context
from ansible.module_utils.common.collections import ImmutableDict
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.vars.manager import VariableManager
from ansible.parsing.dataloader import DataLoader
......@@ -33,29 +36,18 @@ Options = namedtuple('Options', [
def get_default_options():
options = Options(
listtags=False,
listtasks=False,
listhosts=False,
options = dict(
syntax=False,
timeout=30,
connection='ssh',
module_path='',
forks=10,
remote_user='root',
private_key_file=None,
ssh_common_args="",
ssh_extra_args="",
sftp_extra_args="",
scp_extra_args="",
become=None,
become_method=None,
become_user=None,
verbosity=None,
extra_vars=[],
verbosity=1,
check=False,
playbook_path='/etc/ansible/',
passwords=None,
diff=False,
gathering='implicit',
remote_tmp='/tmp/.ansible'
......@@ -108,9 +100,9 @@ class PlayBookRunner:
inventory=self.inventory,
variable_manager=self.variable_manager,
loader=self.loader,
options=self.options,
passwords=self.passwords
passwords={"conn_pass": self.passwords}
)
context.CLIARGS = ImmutableDict(self.options)
if executor._tqm:
executor._tqm._stdout_callback = self.results_callback
......@@ -185,11 +177,10 @@ class AdHocRunner:
return cleaned_tasks
def update_options(self, options):
_options = {k: v for k, v in self.default_options.items()}
if options and isinstance(options, dict):
options = self.__class__.default_options._replace(**options)
else:
options = self.__class__.default_options
return options
_options.update(options)
return _options
def run(self, tasks, pattern, play_name='Ansible Ad-hoc', gather_facts='no'):
"""
......@@ -202,6 +193,7 @@ class AdHocRunner:
self.check_pattern(pattern)
self.results_callback = self.get_result_callback()
cleaned_tasks = self.clean_tasks(tasks)
context.CLIARGS = ImmutableDict(self.options)
play_source = dict(
name=play_name,
......@@ -220,9 +212,8 @@ class AdHocRunner:
inventory=self.inventory,
variable_manager=self.variable_manager,
loader=self.loader,
options=self.options,
stdout_callback=self.results_callback,
passwords=self.options.passwords,
passwords={"conn_pass": self.options.get("password", "")}
)
try:
tqm.run(play)
......@@ -230,8 +221,9 @@ class AdHocRunner:
except Exception as e:
raise AnsibleError(e)
finally:
tqm.cleanup()
self.loader.cleanup_all_tmp_files()
if tqm is not None:
tqm.cleanup()
shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
class CommandRunner(AdHocRunner):
......
......@@ -15,7 +15,7 @@ class TestAdHocRunner(unittest.TestCase):
host_data = [
{
"hostname": "testserver",
"ip": "192.168.244.168",
"ip": "192.168.244.185",
"port": 22,
"username": "root",
"password": "redhat",
......
......@@ -35,7 +35,6 @@ class JMSBaseInventory(BaseInventory):
info["vars"].update({
label.name: label.value
})
info["groups"].append("{}:{}".format(label.name, label.value))
if asset.domain:
info["vars"].update({
"domain": asset.domain.name,
......
......@@ -715,9 +715,12 @@ String.prototype.format = function(args) {
return result;
};
function setCookie(key, value) {
function setCookie(key, value, time) {
var expires = new Date();
expires.setTime(expires.getTime() + (24 * 60 * 60 * 1000));
if (!time) {
time = expires.getTime() + (24 * 60 * 60 * 1000);
}
expires.setTime(time);
document.cookie = key + '=' + value + ';expires=' + expires.toUTCString() + ';path=/';
}
......
/*!
* clipboard.js v1.5.5
* https://zenorocha.github.io/clipboard.js
*
* Licensed MIT © Zeno Rocha
*/
!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,r){function o(a,c){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!c&&s)return s(a,!0);if(i)return i(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a<r.length;a++)o(r[a]);return o}({1:[function(t,e,n){var r=t("matches-selector");e.exports=function(t,e,n){for(var o=n?t:t.parentNode;o&&o!==document;){if(r(o,e))return o;o=o.parentNode}}},{"matches-selector":2}],2:[function(t,e,n){function r(t,e){if(i)return i.call(t,e);for(var n=t.parentNode.querySelectorAll(e),r=0;r<n.length;++r)if(n[r]==t)return!0;return!1}var o=Element.prototype,i=o.matchesSelector||o.webkitMatchesSelector||o.mozMatchesSelector||o.msMatchesSelector||o.oMatchesSelector;e.exports=r},{}],3:[function(t,e,n){function r(t,e,n,r){var i=o.apply(this,arguments);return t.addEventListener(n,i),{destroy:function(){t.removeEventListener(n,i)}}}function o(t,e,n,r){return function(n){n.delegateTarget=i(n.target,e,!0),n.delegateTarget&&r.call(t,n)}}var i=t("closest");e.exports=r},{closest:1}],4:[function(t,e,n){n.node=function(t){return void 0!==t&&t instanceof HTMLElement&&1===t.nodeType},n.nodeList=function(t){var e=Object.prototype.toString.call(t);return void 0!==t&&("[object NodeList]"===e||"[object HTMLCollection]"===e)&&"length"in t&&(0===t.length||n.node(t[0]))},n.string=function(t){return"string"==typeof t||t instanceof String},n.function=function(t){var e=Object.prototype.toString.call(t);return"[object Function]"===e}},{}],5:[function(t,e,n){function r(t,e,n){if(!t&&!e&&!n)throw new Error("Missing required arguments");if(!c.string(e))throw new TypeError("Second argument must be a String");if(!c.function(n))throw new TypeError("Third argument must be a Function");if(c.node(t))return o(t,e,n);if(c.nodeList(t))return i(t,e,n);if(c.string(t))return a(t,e,n);throw new TypeError("First argument must be a String, HTMLElement, HTMLCollection, or NodeList")}function o(t,e,n){return t.addEventListener(e,n),{destroy:function(){t.removeEventListener(e,n)}}}function i(t,e,n){return Array.prototype.forEach.call(t,function(t){t.addEventListener(e,n)}),{destroy:function(){Array.prototype.forEach.call(t,function(t){t.removeEventListener(e,n)})}}}function a(t,e,n){return s(document.body,t,e,n)}var c=t("./is"),s=t("delegate");e.exports=r},{"./is":4,delegate:3}],6:[function(t,e,n){function r(t){var e;if("INPUT"===t.nodeName||"TEXTAREA"===t.nodeName)t.focus(),t.setSelectionRange(0,t.value.length),e=t.value;else{t.hasAttribute("contenteditable")&&t.focus();var n=window.getSelection(),r=document.createRange();r.selectNodeContents(t),n.removeAllRanges(),n.addRange(r),e=n.toString()}return e}e.exports=r},{}],7:[function(t,e,n){function r(){}r.prototype={on:function(t,e,n){var r=this.e||(this.e={});return(r[t]||(r[t]=[])).push({fn:e,ctx:n}),this},once:function(t,e,n){function r(){o.off(t,r),e.apply(n,arguments)}var o=this;return r._=e,this.on(t,r,n)},emit:function(t){var e=[].slice.call(arguments,1),n=((this.e||(this.e={}))[t]||[]).slice(),r=0,o=n.length;for(r;o>r;r++)n[r].fn.apply(n[r].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),r=n[t],o=[];if(r&&e)for(var i=0,a=r.length;a>i;i++)r[i].fn!==e&&r[i].fn._!==e&&o.push(r[i]);return o.length?n[t]=o:delete n[t],this}},e.exports=r},{}],8:[function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}n.__esModule=!0;var i=function(){function t(t,e){for(var n=0;n<e.length;n++){var r=e[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(t,r.key,r)}}return function(e,n,r){return n&&t(e.prototype,n),r&&t(e,r),e}}(),a=t("select"),c=r(a),s=function(){function t(e){o(this,t),this.resolveOptions(e),this.initSelection()}return t.prototype.resolveOptions=function t(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.action=e.action,this.emitter=e.emitter,this.target=e.target,this.text=e.text,this.trigger=e.trigger,this.selectedText=""},t.prototype.initSelection=function t(){if(this.text&&this.target)throw new Error('Multiple attributes declared, use either "target" or "text"');if(this.text)this.selectFake();else{if(!this.target)throw new Error('Missing required attributes, use either "target" or "text"');this.selectTarget()}},t.prototype.selectFake=function t(){var e=this;this.removeFake(),this.fakeHandler=document.body.addEventListener("click",function(){return e.removeFake()}),this.fakeElem=document.createElement("textarea"),this.fakeElem.style.position="absolute",this.fakeElem.style.left="-9999px",this.fakeElem.style.top=(window.pageYOffset||document.documentElement.scrollTop)+"px",this.fakeElem.setAttribute("readonly",""),this.fakeElem.value=this.text,document.body.appendChild(this.fakeElem),this.selectedText=c.default(this.fakeElem),this.copyText()},t.prototype.removeFake=function t(){this.fakeHandler&&(document.body.removeEventListener("click"),this.fakeHandler=null),this.fakeElem&&(document.body.removeChild(this.fakeElem),this.fakeElem=null)},t.prototype.selectTarget=function t(){this.selectedText=c.default(this.target),this.copyText()},t.prototype.copyText=function t(){var e=void 0;try{e=document.execCommand(this.action)}catch(n){e=!1}this.handleResult(e)},t.prototype.handleResult=function t(e){e?this.emitter.emit("success",{action:this.action,text:this.selectedText,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)}):this.emitter.emit("error",{action:this.action,trigger:this.trigger,clearSelection:this.clearSelection.bind(this)})},t.prototype.clearSelection=function t(){this.target&&this.target.blur(),window.getSelection().removeAllRanges()},t.prototype.destroy=function t(){this.removeFake()},i(t,[{key:"action",set:function t(){var e=arguments.length<=0||void 0===arguments[0]?"copy":arguments[0];if(this._action=e,"copy"!==this._action&&"cut"!==this._action)throw new Error('Invalid "action" value, use either "copy" or "cut"')},get:function t(){return this._action}},{key:"target",set:function t(e){if(void 0!==e){if(!e||"object"!=typeof e||1!==e.nodeType)throw new Error('Invalid "target" value, use a valid Element');this._target=e}},get:function t(){return this._target}}]),t}();n.default=s,e.exports=n.default},{select:6}],9:[function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}function a(t,e){var n="data-clipboard-"+t;if(e.hasAttribute(n))return e.getAttribute(n)}n.__esModule=!0;var c=t("./clipboard-action"),s=r(c),u=t("tiny-emitter"),l=r(u),f=t("good-listener"),d=r(f),h=function(t){function e(n,r){o(this,e),t.call(this),this.resolveOptions(r),this.listenClick(n)}return i(e,t),e.prototype.resolveOptions=function t(){var e=arguments.length<=0||void 0===arguments[0]?{}:arguments[0];this.action="function"==typeof e.action?e.action:this.defaultAction,this.target="function"==typeof e.target?e.target:this.defaultTarget,this.text="function"==typeof e.text?e.text:this.defaultText},e.prototype.listenClick=function t(e){var n=this;this.listener=d.default(e,"click",function(t){return n.onClick(t)})},e.prototype.onClick=function t(e){var n=e.delegateTarget||e.currentTarget;this.clipboardAction&&(this.clipboardAction=null),this.clipboardAction=new s.default({action:this.action(n),target:this.target(n),text:this.text(n),trigger:n,emitter:this})},e.prototype.defaultAction=function t(e){return a("action",e)},e.prototype.defaultTarget=function t(e){var n=a("target",e);return n?document.querySelector(n):void 0},e.prototype.defaultText=function t(e){return a("text",e)},e.prototype.destroy=function t(){this.listener.destroy(),this.clipboardAction&&(this.clipboardAction.destroy(),this.clipboardAction=null)},e}(l.default);n.default=h,e.exports=n.default},{"./clipboard-action":8,"good-listener":5,"tiny-emitter":7}]},{},[9])(9)});
\ No newline at end of file
......@@ -147,6 +147,10 @@ class User(AbstractUser):
def otp_secret_key(self, item):
self._otp_secret_key = signer.sign(item)
def check_otp(self, code):
from ..utils import check_otp_code
return check_otp_code(self.otp_secret_key, code)
def get_absolute_url(self):
return reverse('users:user-detail', args=(self.id,))
......
amqp==2.1.4
ansible==2.4.2.0
ansible==2.8.0
asn1crypto==0.24.0
bcrypt==3.1.4
billiard==3.5.0.3
......@@ -24,7 +24,7 @@ django-ranged-response==0.2.0
django-redis-cache==1.7.1
django-rest-swagger==2.1.2
django-simple-captcha==0.5.6
djangorestframework==3.8.2
djangorestframework==3.9.4
djangorestframework-bulk==0.2.1
docutils==0.14
ecdsa==0.13
......@@ -38,7 +38,7 @@ gunicorn==19.9.0
idna==2.6
itsdangerous==0.24
itypes==1.1.0
Jinja2==2.10
Jinja2==2.10.1
jmespath==0.9.3
kombu==4.0.2
ldap3==2.4
......@@ -46,7 +46,7 @@ MarkupSafe==1.0
mysqlclient==1.3.14
olefile==0.44
openapi-codec==1.3.2
paramiko==2.4.1
paramiko==2.4.2
passlib==1.7.1
Pillow==4.3.0
pyasn1==0.4.2
......@@ -57,20 +57,20 @@ PyNaCl==1.2.1
python-dateutil==2.6.1
python-gssapi==0.6.4
pytz==2018.3
PyYAML==3.12
PyYAML==5.1
redis==2.10.6
requests==2.18.4
requests==2.22.0
jms-storage==0.0.22
s3transfer==0.1.13
simplejson==3.13.2
six==1.11.0
sshpubkeys==3.1.0
uritemplate==3.0.0
urllib3==1.22
urllib3==1.25.2
vine==1.1.4
drf-yasg==1.9.1
Werkzeug==0.14.1
drf-nested-routers==0.90.2
drf-nested-routers==0.91
aliyun-python-sdk-core-v3==2.9.1
aliyun-python-sdk-ecs==4.10.1
python-keycloak==0.13.3
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment