Commit 8e09151a authored by fit2cloud-fengyi's avatar fit2cloud-fengyi

Merge branch 'docs' of https://github.com/jumpserver/jumpserver into docs

parents 18841d6c 3fe5dade
...@@ -19,7 +19,7 @@ from rest_framework.response import Response ...@@ -19,7 +19,7 @@ from rest_framework.response import Response
from rest_framework_bulk import BulkModelViewSet from rest_framework_bulk import BulkModelViewSet
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from common.utils import get_logger from common.utils import get_logger, get_object_or_none
from ..hands import IsSuperUser from ..hands import IsSuperUser
from ..models import Node from ..models import Node
from .. import serializers from .. import serializers
...@@ -29,6 +29,7 @@ logger = get_logger(__file__) ...@@ -29,6 +29,7 @@ logger = get_logger(__file__)
__all__ = [ __all__ = [
'NodeViewSet', 'NodeChildrenApi', 'NodeViewSet', 'NodeChildrenApi',
'NodeAddAssetsApi', 'NodeRemoveAssetsApi', 'NodeAddAssetsApi', 'NodeRemoveAssetsApi',
'NodeAddChildrenApi',
] ]
...@@ -75,6 +76,24 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView): ...@@ -75,6 +76,24 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
return Response(response, status=200) return Response(response, status=200)
class NodeAddChildrenApi(generics.UpdateAPIView):
queryset = Node.objects.all()
permission_classes = (IsSuperUser,)
serializer_class = serializers.NodeAddChildrenSerializer
instance = None
def put(self, request, *args, **kwargs):
instance = self.get_object()
nodes_id = request.data.get("nodes")
children = [get_object_or_none(Node, id=pk) for pk in nodes_id]
for node in children:
if not node:
continue
node.parent = instance
node.save()
return Response("OK")
class NodeAddAssetsApi(generics.UpdateAPIView): class NodeAddAssetsApi(generics.UpdateAPIView):
serializer_class = serializers.NodeAssetsSerializer serializer_class = serializers.NodeAssetsSerializer
queryset = Node.objects.all() queryset = Node.objects.all()
......
...@@ -15,7 +15,7 @@ class AssetCreateForm(forms.ModelForm): ...@@ -15,7 +15,7 @@ class AssetCreateForm(forms.ModelForm):
model = Asset model = Asset
fields = [ fields = [
'hostname', 'ip', 'public_ip', 'port', 'comment', 'hostname', 'ip', 'public_ip', 'port', 'comment',
'nodes', 'is_active', 'admin_user', 'labels', 'nodes', 'is_active', 'admin_user', 'labels', 'platform',
] ]
widgets = { widgets = {
...@@ -44,7 +44,7 @@ class AssetUpdateForm(forms.ModelForm): ...@@ -44,7 +44,7 @@ class AssetUpdateForm(forms.ModelForm):
class Meta: class Meta:
model = Asset model = Asset
fields = [ fields = [
'hostname', 'ip', 'port', 'nodes', 'is_active', 'hostname', 'ip', 'port', 'nodes', 'is_active', 'platform',
'public_ip', 'number', 'comment', 'admin_user', 'labels', 'public_ip', 'number', 'comment', 'admin_user', 'labels',
] ]
widgets = { widgets = {
......
...@@ -38,6 +38,14 @@ def default_node(): ...@@ -38,6 +38,14 @@ def default_node():
class Asset(models.Model): class Asset(models.Model):
# Important # Important
PLATFORM_CHOICES = (
('Linux', 'Linux'),
('Unix', 'Unix'),
('MacOS', 'MacOS'),
('BSD', 'BSD'),
('Windows', 'Windows'),
('Other', 'Other'),
)
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'), db_index=True) ip = models.GenericIPAddressField(max_length=32, verbose_name=_('IP'), db_index=True)
hostname = models.CharField(max_length=128, unique=True, verbose_name=_('Hostname')) hostname = models.CharField(max_length=128, unique=True, verbose_name=_('Hostname'))
...@@ -64,7 +72,7 @@ class Asset(models.Model): ...@@ -64,7 +72,7 @@ class Asset(models.Model):
disk_total = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Disk total')) disk_total = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Disk total'))
disk_info = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Disk info')) disk_info = models.CharField(max_length=1024, null=True, blank=True, verbose_name=_('Disk info'))
platform = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('Platform')) platform = models.CharField(max_length=128, choices=PLATFORM_CHOICES, default='Linux', verbose_name=_('Platform'))
os = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('OS')) os = models.CharField(max_length=128, null=True, blank=True, verbose_name=_('OS'))
os_version = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('OS version')) os_version = models.CharField(max_length=16, null=True, blank=True, verbose_name=_('OS version'))
os_arch = models.CharField(max_length=16, blank=True, null=True, verbose_name=_('OS arch')) os_arch = models.CharField(max_length=16, blank=True, null=True, verbose_name=_('OS arch'))
...@@ -87,6 +95,12 @@ class Asset(models.Model): ...@@ -87,6 +95,12 @@ class Asset(models.Model):
return True, '' return True, ''
return False, warning return False, warning
def is_unixlike(self):
if self.platform not in ("Windows", "Other"):
return True
else:
return False
@property @property
def hardware_info(self): def hardware_info(self):
if self.cpu_count: if self.cpu_count:
...@@ -99,6 +113,8 @@ class Asset(models.Model): ...@@ -99,6 +113,8 @@ class Asset(models.Model):
@property @property
def is_connective(self): def is_connective(self):
if not self.is_unixlike():
return True
val = cache.get(ASSET_ADMIN_CONN_CACHE_KEY.format(self.hostname)) val = cache.get(ASSET_ADMIN_CONN_CACHE_KEY.format(self.hostname))
if val == 1: if val == 1:
return True return True
......
...@@ -61,6 +61,9 @@ class Node(models.Model): ...@@ -61,6 +61,9 @@ class Node(models.Model):
assets = Asset.objects.filter(nodes__id=self.id) assets = Asset.objects.filter(nodes__id=self.id)
return assets return assets
def get_active_assets(self):
return self.get_assets().filter(is_active=True)
def get_all_assets(self): def get_all_assets(self):
from .asset import Asset from .asset import Asset
if self.is_root(): if self.is_root():
...@@ -70,6 +73,9 @@ class Node(models.Model): ...@@ -70,6 +73,9 @@ class Node(models.Model):
assets = Asset.objects.filter(nodes__in=nodes) assets = Asset.objects.filter(nodes__in=nodes)
return assets return assets
def get_all_active_assets(self):
return self.get_all_assets().filter(is_active=True)
def is_root(self): def is_root(self):
return self.key == '0' return self.key == '0'
...@@ -88,6 +94,10 @@ class Node(models.Model): ...@@ -88,6 +94,10 @@ class Node(models.Model):
else: else:
return parent return parent
@parent.setter
def parent(self, parent):
self.key = parent.get_next_child_key()
@property @property
def ancestor(self): def ancestor(self):
if self.parent == self.__class__.root(): if self.parent == self.__class__.root():
......
...@@ -26,14 +26,14 @@ signer = get_signer() ...@@ -26,14 +26,14 @@ signer = get_signer()
class AssetUser(models.Model): class AssetUser(models.Model):
id = models.UUIDField(default=uuid.uuid4, primary_key=True) id = models.UUIDField(default=uuid.uuid4, primary_key=True)
name = models.CharField(max_length=128, unique=True, verbose_name=_('Name')) name = models.CharField(max_length=128, unique=True, verbose_name=_('Name'))
username = models.CharField(max_length=16, verbose_name=_('Username')) username = models.CharField(max_length=128, verbose_name=_('Username'))
_password = models.CharField(max_length=256, blank=True, null=True, verbose_name=_('Password')) _password = models.CharField(max_length=256, blank=True, null=True, verbose_name=_('Password'))
_private_key = models.TextField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'), validators=[private_key_validator, ]) _private_key = models.TextField(max_length=4096, blank=True, null=True, verbose_name=_('SSH private key'), validators=[private_key_validator, ])
_public_key = models.TextField(max_length=4096, blank=True, verbose_name=_('SSH public key')) _public_key = models.TextField(max_length=4096, blank=True, verbose_name=_('SSH public key'))
comment = models.TextField(blank=True, verbose_name=_('Comment')) comment = models.TextField(blank=True, verbose_name=_('Comment'))
date_created = models.DateTimeField(auto_now_add=True) date_created = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True) date_updated = models.DateTimeField(auto_now=True)
created_by = models.CharField(max_length=32, null=True, verbose_name=_('Created by')) created_by = models.CharField(max_length=128, null=True, verbose_name=_('Created by'))
@property @property
def password(self): def password(self):
...@@ -175,15 +175,12 @@ class AdminUser(AssetUser): ...@@ -175,15 +175,12 @@ class AdminUser(AssetUser):
return info return info
def get_related_assets(self): def get_related_assets(self):
assets = [] assets = self.asset_set.all()
for cluster in self.cluster_set.all(): return assets
assets.extend(cluster.assets.all())
assets.extend(self.asset_set.all())
return list(set(assets))
@property @property
def assets_amount(self): def assets_amount(self):
return len(self.get_related_assets()) return self.get_related_assets().count()
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
......
...@@ -66,3 +66,7 @@ class NodeAssetsSerializer(serializers.ModelSerializer): ...@@ -66,3 +66,7 @@ class NodeAssetsSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = Node model = Node
fields = ['assets'] fields = ['assets']
class NodeAddChildrenSerializer(serializers.Serializer):
nodes = serializers.ListField()
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<div class="col-sm-12"> <div class="col-sm-12">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>{% trans 'Create system user' %}</h5> <h5>{{ action }}</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>
...@@ -81,6 +81,14 @@ ...@@ -81,6 +81,14 @@
{% block custom_foot_js %} {% block custom_foot_js %}
<script> <script>
var auto_generate_key = '#'+'{{ form.auto_generate_key.id_for_label }}'; var auto_generate_key = '#'+'{{ form.auto_generate_key.id_for_label }}';
var protocol_id = '#' + '{{ form.protocol.id_for_label }}';
var password_id = '#' + '{{ form.password.id_for_label }}';
var private_key_id = '#' + '{{ form.private_key_file.id_for_label }}';
var sudo_id = '#' + '{{ form.sudo.id_for_label }}';
var shell_id = '#' + '{{ form.shell.id_for_label }}';
var need_change_field = [auto_generate_key, private_key_id, sudo_id, shell_id] ;
function authFieldsDisplay() { function authFieldsDisplay() {
if ($(auto_generate_key).prop('checked')) { if ($(auto_generate_key).prop('checked')) {
$('.auth-fields').addClass('hidden'); $('.auth-fields').addClass('hidden');
...@@ -88,9 +96,23 @@ ...@@ -88,9 +96,23 @@
$('.auth-fields').removeClass('hidden'); $('.auth-fields').removeClass('hidden');
} }
} }
function protocolChange() {
if ($(protocol_id).attr('value') === 'rdp') {
$.each(need_change_field, function (index, value) {
$(value).addClass('hidden')
});
$(password_id).removeClass('hidden')
} else {
$.each(need_change_field, function (index, value) {
$(value).removeClass('hidden')
});
}
}
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2(); $('.select2').select2();
authFieldsDisplay(); authFieldsDisplay();
protocolChange();
$(auto_generate_key).change(function () { $(auto_generate_key).change(function () {
authFieldsDisplay(); authFieldsDisplay();
}); });
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
<div class="col-sm-12"> <div class="col-sm-12">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>{% trans 'Create admin user' %}</h5> <h5>{{ action }}</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
{% bootstrap_field form.hostname layout="horizontal" %} {% bootstrap_field form.hostname layout="horizontal" %}
{% bootstrap_field form.ip layout="horizontal" %} {% bootstrap_field form.ip layout="horizontal" %}
{% bootstrap_field form.port layout="horizontal" %} {% bootstrap_field form.port layout="horizontal" %}
{% bootstrap_field form.platform layout="horizontal" %}
{% bootstrap_field form.public_ip layout="horizontal" %} {% bootstrap_field form.public_ip layout="horizontal" %}
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
......
...@@ -2,6 +2,12 @@ ...@@ -2,6 +2,12 @@
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
{% block help_message %}
<div class="alert alert-info help-message">
左侧是资产树,右击可以新建、删除、更改树节点,授权资产也是以节点方式组织的,右侧是属于该节点下的资产
</div>
{% endblock %}
{% block custom_head_css_js %} {% block custom_head_css_js %}
<link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet"> <link href="{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}" rel="stylesheet">
<script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script> <script type="text/javascript" src="{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"></script>
...@@ -224,6 +230,9 @@ function editTreeNode() { ...@@ -224,6 +230,9 @@ function editTreeNode() {
if (!current_node){ if (!current_node){
return return
} }
if (current_node.value) {
current_node.name = current_node.value;
}
zTree.editName(current_node); zTree.editName(current_node);
} }
...@@ -308,6 +317,42 @@ function selectQueryNode() { ...@@ -308,6 +317,42 @@ function selectQueryNode() {
} }
} }
function beforeDrag() {
return true
}
function beforeDrop(treeId, treeNodes, targetNode, moveType) {
var treeNodesNames = [];
$.each(treeNodes, function (index, value) {
treeNodesNames.push(value.value);
});
var msg = "你想移动节点: `" + treeNodesNames.join(",") + "` 到 `" + targetNode.value + "` 下吗?";
if (confirm(msg)){
return true
} else {
return false
}
}
function onDrag(event, treeId, treeNodes) {
}
function onDrop(event, treeId, treeNodes, targetNode, moveType) {
var treeNodesIds = [];
$.each(treeNodes, function (index, value) {
treeNodesIds.push(value.id);
});
var the_url = "{% url 'api-assets:node-add-children' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", targetNode.id);
var body = {nodes: treeNodesIds};
APIUpdateAttr({
url: the_url,
method: "PUT",
body: JSON.stringify(body)
})
}
function initTree() { function initTree() {
var setting = { var setting = {
view: { view: {
...@@ -319,11 +364,24 @@ function initTree() { ...@@ -319,11 +364,24 @@ function initTree() {
enable: true enable: true
} }
}, },
edit: {
enable: true,
showRemoveBtn: false,
showRenameBtn: false,
drag: {
isCopy: true,
isMove: true
}
},
callback: { callback: {
onRightClick: OnRightClick, onRightClick: OnRightClick,
beforeClick: beforeClick, beforeClick: beforeClick,
onRename: onRename, onRename: onRename,
onSelected: onSelected onSelected: onSelected,
beforeDrag: beforeDrag,
onDrag: onDrag,
beforeDrop: beforeDrop,
onDrop: onDrop
} }
}; };
...@@ -334,7 +392,8 @@ function initTree() { ...@@ -334,7 +392,8 @@ function initTree() {
{#if (value["key"] === "0") {#} {#if (value["key"] === "0") {#}
value["open"] = true; value["open"] = true;
{# }#} {# }#}
value["name"] = value["value"] + ' (' + value['assets_amount'] + ')' value["name"] = value["value"] + ' (' + value['assets_amount'] + ')';
value['value'] = value['value'];
}); });
zNodes = data; zNodes = data;
$.fn.zTree.init($("#assetTree"), setting, zNodes); $.fn.zTree.init($("#assetTree"), setting, zNodes);
...@@ -415,7 +474,7 @@ $(document).ready(function(){ ...@@ -415,7 +474,7 @@ $(document).ready(function(){
current_node = nodes[0]; current_node = nodes[0];
url += "?node_id=" + current_node.id; url += "?node_id=" + current_node.id;
} }
window.open(url); window.open(url, '_self');
}) })
.on('click', '.btn_asset_delete', function () { .on('click', '.btn_asset_delete', function () {
var $this = $(this); var $this = $(this);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
{% bootstrap_field form.hostname layout="horizontal" %} {% bootstrap_field form.hostname layout="horizontal" %}
{% bootstrap_field form.ip layout="horizontal" %} {% bootstrap_field form.ip layout="horizontal" %}
{% bootstrap_field form.port layout="horizontal" %} {% bootstrap_field form.port layout="horizontal" %}
{% bootstrap_field form.platform layout="horizontal" %}
{% bootstrap_field form.public_ip layout="horizontal" %} {% bootstrap_field form.public_ip layout="horizontal" %}
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
......
...@@ -44,6 +44,7 @@ urlpatterns = [ ...@@ -44,6 +44,7 @@ urlpatterns = [
url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$', url(r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/connective/$',
api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'), api.SystemUserTestConnectiveApi.as_view(), name='system-user-connective'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/$', api.NodeChildrenApi.as_view(), name='node-children'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/$', api.NodeChildrenApi.as_view(), name='node-children'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/children/add/$', api.NodeAddChildrenApi.as_view(), name='node-add-children'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$', api.NodeAddAssetsApi.as_view(), name='node-add-assets'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/add/$', api.NodeAddAssetsApi.as_view(), name='node-add-assets'),
url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/remove/$', api.NodeRemoveAssetsApi.as_view(), name='node-remove-assets'), url(r'^v1/nodes/(?P<pk>[0-9a-zA-Z\-]{36})/assets/remove/$', api.NodeRemoveAssetsApi.as_view(), name='node-remove-assets'),
] ]
......
...@@ -58,8 +58,7 @@ class UserAssetListView(LoginRequiredMixin, TemplateView): ...@@ -58,8 +58,7 @@ class UserAssetListView(LoginRequiredMixin, TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Assets'), 'action': _('My assets'),
'action': _('Asset list'),
'system_users': SystemUser.objects.all(), 'system_users': SystemUser.objects.all(),
} }
kwargs.update(context) kwargs.update(context)
...@@ -248,6 +247,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView): ...@@ -248,6 +247,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
f = form.cleaned_data['file'] f = form.cleaned_data['file']
det_result = chardet.detect(f.read()) det_result = chardet.detect(f.read())
f.seek(0) # reset file seek index f.seek(0) # reset file seek index
file_data = f.read().decode(det_result['encoding']).strip(codecs.BOM_UTF8.decode()) file_data = f.read().decode(det_result['encoding']).strip(codecs.BOM_UTF8.decode())
csv_file = StringIO(file_data) csv_file = StringIO(file_data)
reader = csv.reader(csv_file) reader = csv.reader(csv_file)
......
...@@ -68,10 +68,10 @@ class BaseForm(forms.Form): ...@@ -68,10 +68,10 @@ class BaseForm(forms.Form):
class BasicSettingForm(BaseForm): class BasicSettingForm(BaseForm):
SITE_URL = forms.URLField( SITE_URL = forms.URLField(
label=_("Current SITE URL"), label=_("Current SITE URL"),
help_text="http://jumpserver.abc.com:8080" help_text="eg: http://jumpserver.abc.com:8080"
) )
USER_GUIDE_URL = forms.URLField( USER_GUIDE_URL = forms.URLField(
label=_("User Guide URL"), label=_("User Guide URL"), required=False,
help_text=_("User first login update profile done redirect to it") help_text=_("User first login update profile done redirect to it")
) )
EMAIL_SUBJECT_PREFIX = forms.CharField( EMAIL_SUBJECT_PREFIX = forms.CharField(
...@@ -135,7 +135,7 @@ class LDAPSettingForm(BaseForm): ...@@ -135,7 +135,7 @@ class LDAPSettingForm(BaseForm):
AUTH_LDAP_START_TLS = forms.BooleanField( AUTH_LDAP_START_TLS = forms.BooleanField(
label=_("Use SSL"), initial=False, required=False label=_("Use SSL"), initial=False, required=False
) )
AUTH_LDAP = forms.BooleanField(label=_("Enable LDAP auth"), initial=False) AUTH_LDAP = forms.BooleanField(label=_("Enable LDAP auth"), initial=False, required=False)
class TerminalSettingForm(BaseForm): class TerminalSettingForm(BaseForm):
......
...@@ -99,9 +99,8 @@ class DatetimeSearchMixin: ...@@ -99,9 +99,8 @@ class DatetimeSearchMixin:
if date_from_s: if date_from_s:
date_from = timezone.datetime.strptime(date_from_s, self.date_format) date_from = timezone.datetime.strptime(date_from_s, self.date_format)
self.date_from = date_from.replace( tz = timezone.get_current_timezone()
tzinfo=timezone.get_current_timezone() self.date_from = tz.localize(date_from)
)
else: else:
self.date_from = timezone.now() - timezone.timedelta(7) self.date_from = timezone.now() - timezone.timedelta(7)
......
...@@ -73,7 +73,12 @@ def to_html(s): ...@@ -73,7 +73,12 @@ def to_html(s):
@register.filter @register.filter
def time_util_with_seconds(date_from, date_to): def time_util_with_seconds(date_from, date_to):
if date_from and date_to: if not date_from:
return ''
if not date_to:
return ''
date_to = timezone.now()
delta = date_to - date_from delta = date_to - date_from
seconds = delta.seconds seconds = delta.seconds
if seconds < 60: if seconds < 60:
...@@ -82,8 +87,6 @@ def time_util_with_seconds(date_from, date_to): ...@@ -82,8 +87,6 @@ def time_util_with_seconds(date_from, date_to):
return '{} m'.format(seconds//60) return '{} m'.format(seconds//60)
else: else:
return '{} h'.format(seconds//3600) return '{} h'.format(seconds//3600)
else:
return ''
@register.filter @register.filter
......
...@@ -8,7 +8,7 @@ msgid "" ...@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n" "Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-02-26 16:54+0800\n" "POT-Creation-Date: 2018-03-06 17:57+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n" "Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n" "Language-Team: Jumpserver team<ibuler@qq.com>\n"
...@@ -17,12 +17,12 @@ msgstr "" ...@@ -17,12 +17,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: assets/api/node.py:54 #: assets/api/node.py:55
msgid "New node {}" msgid "New node {}"
msgstr "新节点 {}" msgstr "新节点 {}"
#: assets/forms/asset.py:23 assets/forms/asset.py:52 assets/forms/user.py:125 #: assets/forms/asset.py:23 assets/forms/asset.py:52 assets/forms/user.py:125
#: assets/models/asset.py:45 assets/models/user.py:221 #: assets/models/asset.py:53 assets/models/user.py:218
#: assets/templates/assets/asset_detail.html:181 #: assets/templates/assets/asset_detail.html:181
#: assets/templates/assets/asset_detail.html:189 #: assets/templates/assets/asset_detail.html:189
#: assets/templates/assets/system_user_detail.html:164 #: assets/templates/assets/system_user_detail.html:164
...@@ -30,16 +30,16 @@ msgid "Nodes" ...@@ -30,16 +30,16 @@ msgid "Nodes"
msgstr "节点管理" msgstr "节点管理"
#: assets/forms/asset.py:26 assets/forms/asset.py:55 assets/forms/asset.py:90 #: assets/forms/asset.py:26 assets/forms/asset.py:55 assets/forms/asset.py:90
#: assets/forms/asset.py:94 assets/models/asset.py:49 #: assets/forms/asset.py:94 assets/models/asset.py:57
#: assets/models/cluster.py:19 assets/models/user.py:190 #: assets/models/cluster.py:19 assets/models/user.py:187
#: assets/templates/assets/asset_detail.html:73 templates/_nav.html:23 #: assets/templates/assets/asset_detail.html:73 templates/_nav.html:24
msgid "Admin user" msgid "Admin user"
msgstr "管理用户" msgstr "管理用户"
#: assets/forms/asset.py:29 assets/forms/asset.py:58 assets/models/asset.py:73 #: assets/forms/asset.py:29 assets/forms/asset.py:58 assets/models/asset.py:81
#: assets/templates/assets/asset_create.html:31 #: assets/templates/assets/asset_create.html:32
#: assets/templates/assets/asset_detail.html:218 #: assets/templates/assets/asset_detail.html:218
#: assets/templates/assets/asset_update.html:36 templates/_nav.html:25 #: assets/templates/assets/asset_update.html:37 templates/_nav.html:26
msgid "Labels" msgid "Labels"
msgstr "标签管理" msgstr "标签管理"
...@@ -54,7 +54,7 @@ msgstr "管理用户是资产上已经存在的特权用户,如 root或者其 ...@@ -54,7 +54,7 @@ msgstr "管理用户是资产上已经存在的特权用户,如 root或者其
msgid "Select assets" msgid "Select assets"
msgstr "选择资产" msgstr "选择资产"
#: assets/forms/asset.py:86 assets/models/asset.py:44 #: assets/forms/asset.py:86 assets/models/asset.py:52
#: assets/templates/assets/admin_user_assets.html:53 #: assets/templates/assets/admin_user_assets.html:53
#: assets/templates/assets/asset_detail.html:69 #: assets/templates/assets/asset_detail.html:69
#: assets/templates/assets/system_user_asset.html:51 #: assets/templates/assets/system_user_asset.html:51
...@@ -62,7 +62,7 @@ msgstr "选择资产" ...@@ -62,7 +62,7 @@ msgstr "选择资产"
msgid "Port" msgid "Port"
msgstr "端口" msgstr "端口"
#: assets/forms/asset.py:106 assets/templates/assets/asset_create.html:35 #: assets/forms/asset.py:106 assets/templates/assets/asset_create.html:36
msgid "Select labels" msgid "Select labels"
msgstr "选择标签" msgstr "选择标签"
...@@ -70,11 +70,11 @@ msgstr "选择标签" ...@@ -70,11 +70,11 @@ msgstr "选择标签"
msgid "Select nodes" msgid "Select nodes"
msgstr "选择节点" msgstr "选择节点"
#: assets/forms/label.py:13 assets/models/asset.py:137 #: assets/forms/label.py:13 assets/models/asset.py:153
#: assets/templates/assets/admin_user_list.html:24 #: assets/templates/assets/admin_user_list.html:24
#: assets/templates/assets/label_list.html:16 #: assets/templates/assets/label_list.html:16
#: assets/templates/assets/system_user_list.html:26 perms/models.py:17 #: assets/templates/assets/system_user_list.html:26 perms/models.py:17
#: terminal/backends/command/models.py:11 terminal/models.py:116 #: terminal/backends/command/models.py:11 terminal/models.py:123
#: terminal/templates/terminal/command_list.html:40 #: terminal/templates/terminal/command_list.html:40
#: terminal/templates/terminal/command_list.html:73 #: terminal/templates/terminal/command_list.html:73
#: terminal/templates/terminal/session_list.html:41 #: terminal/templates/terminal/session_list.html:41
...@@ -84,10 +84,10 @@ msgstr "资产" ...@@ -84,10 +84,10 @@ msgstr "资产"
#: assets/forms/user.py:24 #: assets/forms/user.py:24
msgid "Password or private key passphrase" msgid "Password or private key passphrase"
msgstr "密码或钥密码" msgstr "密码或钥密码"
#: assets/forms/user.py:25 assets/models/user.py:30 common/forms.py:113 #: assets/forms/user.py:25 assets/models/user.py:30 common/forms.py:113
#: users/forms.py:16 users/forms.py:24 users/templates/users/login.html:56 #: users/forms.py:16 users/forms.py:24 users/templates/users/login.html:59
#: users/templates/users/reset_password.html:52 #: users/templates/users/reset_password.html:52
#: users/templates/users/user_create.html:11 #: users/templates/users/user_create.html:11
#: users/templates/users/user_password_update.html:40 #: users/templates/users/user_password_update.html:40
...@@ -116,11 +116,11 @@ msgstr "密码和私钥, 必须输入一个" ...@@ -116,11 +116,11 @@ msgstr "密码和私钥, 必须输入一个"
#: assets/templates/assets/system_user_detail.html:58 #: assets/templates/assets/system_user_detail.html:58
#: assets/templates/assets/system_user_list.html:24 common/models.py:26 #: assets/templates/assets/system_user_list.html:24 common/models.py:26
#: common/templates/common/terminal_setting.html:67 #: common/templates/common/terminal_setting.html:67
#: common/templates/common/terminal_setting.html:88 ops/models.py:31 #: common/templates/common/terminal_setting.html:85 ops/models.py:31
#: ops/templates/ops/task_detail.html:56 ops/templates/ops/task_list.html:34 #: ops/templates/ops/task_detail.html:56 ops/templates/ops/task_list.html:34
#: perms/models.py:14 perms/templates/perms/asset_permission_detail.html:62 #: perms/models.py:14 perms/templates/perms/asset_permission_detail.html:62
#: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:15 #: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:16
#: terminal/models.py:141 terminal/templates/terminal/terminal_detail.html:43 #: terminal/models.py:149 terminal/templates/terminal/terminal_detail.html:43
#: terminal/templates/terminal/terminal_list.html:29 users/models/group.py:14 #: terminal/templates/terminal/terminal_list.html:29 users/models/group.py:14
#: users/models/user.py:35 users/templates/users/_select_user_modal.html:13 #: users/models/user.py:35 users/templates/users/_select_user_modal.html:13
#: users/templates/users/user_detail.html:63 #: users/templates/users/user_detail.html:63
...@@ -138,9 +138,9 @@ msgstr "名称" ...@@ -138,9 +138,9 @@ msgstr "名称"
#: assets/templates/assets/system_user_detail.html:62 #: assets/templates/assets/system_user_detail.html:62
#: assets/templates/assets/system_user_list.html:25 #: assets/templates/assets/system_user_list.html:25
#: perms/templates/perms/asset_permission_user.html:55 users/forms.py:14 #: perms/templates/perms/asset_permission_user.html:55 users/forms.py:14
#: users/models/authentication.py:44 users/models/user.py:34 #: users/models/authentication.py:45 users/models/user.py:34
#: users/templates/users/_select_user_modal.html:14 #: users/templates/users/_select_user_modal.html:14
#: users/templates/users/login.html:53 #: users/templates/users/login.html:56
#: users/templates/users/login_log_list.html:49 #: users/templates/users/login_log_list.html:49
#: users/templates/users/user_detail.html:67 #: users/templates/users/user_detail.html:67
#: users/templates/users/user_list.html:24 #: users/templates/users/user_list.html:24
...@@ -162,10 +162,10 @@ msgid "" ...@@ -162,10 +162,10 @@ msgid ""
"than 2 system user" "than 2 system user"
msgstr "高优先级的系统用户将会作为默认登录用户" msgstr "高优先级的系统用户将会作为默认登录用户"
#: assets/models/asset.py:42 assets/templates/assets/_asset_list_modal.html:21 #: assets/models/asset.py:50 assets/templates/assets/_asset_list_modal.html:21
#: assets/templates/assets/admin_user_assets.html:52 #: assets/templates/assets/admin_user_assets.html:52
#: assets/templates/assets/asset_detail.html:61 #: assets/templates/assets/asset_detail.html:61
#: assets/templates/assets/asset_list.html:81 #: assets/templates/assets/asset_list.html:87
#: assets/templates/assets/system_user_asset.html:50 #: assets/templates/assets/system_user_asset.html:50
#: assets/templates/assets/user_asset_list.html:20 common/forms.py:144 #: assets/templates/assets/user_asset_list.html:20 common/forms.py:144
#: perms/templates/perms/asset_permission_asset.html:55 #: perms/templates/perms/asset_permission_asset.html:55
...@@ -175,10 +175,10 @@ msgstr "高优先级的系统用户将会作为默认登录用户" ...@@ -175,10 +175,10 @@ msgstr "高优先级的系统用户将会作为默认登录用户"
msgid "IP" msgid "IP"
msgstr "IP" msgstr "IP"
#: assets/models/asset.py:43 assets/templates/assets/_asset_list_modal.html:20 #: assets/models/asset.py:51 assets/templates/assets/_asset_list_modal.html:20
#: assets/templates/assets/admin_user_assets.html:51 #: assets/templates/assets/admin_user_assets.html:51
#: assets/templates/assets/asset_detail.html:57 #: assets/templates/assets/asset_detail.html:57
#: assets/templates/assets/asset_list.html:80 #: assets/templates/assets/asset_list.html:86
#: assets/templates/assets/system_user_asset.html:49 #: assets/templates/assets/system_user_asset.html:49
#: assets/templates/assets/user_asset_list.html:19 common/forms.py:143 #: assets/templates/assets/user_asset_list.html:19 common/forms.py:143
#: perms/templates/perms/asset_permission_asset.html:54 #: perms/templates/perms/asset_permission_asset.html:54
...@@ -187,77 +187,77 @@ msgstr "IP" ...@@ -187,77 +187,77 @@ msgstr "IP"
msgid "Hostname" msgid "Hostname"
msgstr "主机名" msgstr "主机名"
#: assets/models/asset.py:46 assets/models/label.py:20 #: assets/models/asset.py:54 assets/models/label.py:20
#: assets/templates/assets/asset_detail.html:105 #: assets/templates/assets/asset_detail.html:105
#: perms/templates/perms/asset_permission_list.html:70 #: perms/templates/perms/asset_permission_list.html:70
msgid "Is active" msgid "Is active"
msgstr "激活" msgstr "激活"
#: assets/models/asset.py:52 assets/templates/assets/asset_detail.html:65 #: assets/models/asset.py:60 assets/templates/assets/asset_detail.html:65
msgid "Public IP" msgid "Public IP"
msgstr "公网IP" msgstr "公网IP"
#: assets/models/asset.py:53 assets/templates/assets/asset_detail.html:113 #: assets/models/asset.py:61 assets/templates/assets/asset_detail.html:113
msgid "Asset number" msgid "Asset number"
msgstr "资产编号" msgstr "资产编号"
#: assets/models/asset.py:56 assets/templates/assets/asset_detail.html:77 #: assets/models/asset.py:64 assets/templates/assets/asset_detail.html:77
msgid "Vendor" msgid "Vendor"
msgstr "制造商" msgstr "制造商"
#: assets/models/asset.py:57 assets/templates/assets/asset_detail.html:81 #: assets/models/asset.py:65 assets/templates/assets/asset_detail.html:81
msgid "Model" msgid "Model"
msgstr "型号" msgstr "型号"
#: assets/models/asset.py:58 assets/templates/assets/asset_detail.html:109 #: assets/models/asset.py:66 assets/templates/assets/asset_detail.html:109
msgid "Serial number" msgid "Serial number"
msgstr "序列号" msgstr "序列号"
#: assets/models/asset.py:60 #: assets/models/asset.py:68
msgid "CPU model" msgid "CPU model"
msgstr "CPU型号" msgstr "CPU型号"
#: assets/models/asset.py:61 #: assets/models/asset.py:69
msgid "CPU count" msgid "CPU count"
msgstr "CPU数量" msgstr "CPU数量"
#: assets/models/asset.py:62 #: assets/models/asset.py:70
msgid "CPU cores" msgid "CPU cores"
msgstr "CPU核数" msgstr "CPU核数"
#: assets/models/asset.py:63 assets/templates/assets/asset_detail.html:89 #: assets/models/asset.py:71 assets/templates/assets/asset_detail.html:89
msgid "Memory" msgid "Memory"
msgstr "内存" msgstr "内存"
#: assets/models/asset.py:64 #: assets/models/asset.py:72
msgid "Disk total" msgid "Disk total"
msgstr "硬盘大小" msgstr "硬盘大小"
#: assets/models/asset.py:65 #: assets/models/asset.py:73
msgid "Disk info" msgid "Disk info"
msgstr "硬盘信息" msgstr "硬盘信息"
#: assets/models/asset.py:67 assets/templates/assets/asset_detail.html:97 #: assets/models/asset.py:75 assets/templates/assets/asset_detail.html:97
msgid "Platform" msgid "Platform"
msgstr "系统平台" msgstr "系统平台"
#: assets/models/asset.py:68 assets/templates/assets/asset_detail.html:101 #: assets/models/asset.py:76 assets/templates/assets/asset_detail.html:101
msgid "OS" msgid "OS"
msgstr "操作系统" msgstr "操作系统"
#: assets/models/asset.py:69 #: assets/models/asset.py:77
msgid "OS version" msgid "OS version"
msgstr "系统版本" msgstr "系统版本"
#: assets/models/asset.py:70 #: assets/models/asset.py:78
msgid "OS arch" msgid "OS arch"
msgstr "系统架构" msgstr "系统架构"
#: assets/models/asset.py:71 #: assets/models/asset.py:79
msgid "Hostname raw" msgid "Hostname raw"
msgstr "主机名原始" msgstr "主机名原始"
#: assets/models/asset.py:74 assets/models/cluster.py:28 #: assets/models/asset.py:82 assets/models/cluster.py:28
#: assets/models/group.py:21 assets/models/user.py:36 #: assets/models/group.py:21 assets/models/user.py:36
#: assets/templates/assets/admin_user_detail.html:68 #: assets/templates/assets/admin_user_detail.html:68
#: assets/templates/assets/asset_detail.html:117 #: assets/templates/assets/asset_detail.html:117
...@@ -268,7 +268,7 @@ msgstr "主机名原始" ...@@ -268,7 +268,7 @@ msgstr "主机名原始"
msgid "Created by" msgid "Created by"
msgstr "创建者" msgstr "创建者"
#: assets/models/asset.py:75 assets/models/cluster.py:26 #: assets/models/asset.py:83 assets/models/cluster.py:26
#: assets/models/group.py:22 assets/models/label.py:23 #: assets/models/group.py:22 assets/models/label.py:23
#: assets/templates/assets/admin_user_detail.html:64 #: assets/templates/assets/admin_user_detail.html:64
#: assets/templates/assets/system_user_detail.html:92 #: assets/templates/assets/system_user_detail.html:92
...@@ -280,7 +280,7 @@ msgstr "创建者" ...@@ -280,7 +280,7 @@ msgstr "创建者"
msgid "Date created" msgid "Date created"
msgstr "创建日期" msgstr "创建日期"
#: assets/models/asset.py:76 assets/models/cluster.py:29 #: assets/models/asset.py:84 assets/models/cluster.py:29
#: assets/models/group.py:23 assets/models/label.py:21 assets/models/user.py:33 #: assets/models/group.py:23 assets/models/label.py:21 assets/models/user.py:33
#: assets/templates/assets/admin_user_detail.html:72 #: assets/templates/assets/admin_user_detail.html:72
#: assets/templates/assets/admin_user_list.html:28 #: assets/templates/assets/admin_user_list.html:28
...@@ -288,7 +288,7 @@ msgstr "创建日期" ...@@ -288,7 +288,7 @@ msgstr "创建日期"
#: assets/templates/assets/system_user_detail.html:100 #: assets/templates/assets/system_user_detail.html:100
#: assets/templates/assets/system_user_list.html:30 common/models.py:30 #: assets/templates/assets/system_user_list.html:30 common/models.py:30
#: ops/models.py:37 perms/models.py:24 perms/models.py:81 #: ops/models.py:37 perms/models.py:24 perms/models.py:81
#: perms/templates/perms/asset_permission_detail.html:98 terminal/models.py:25 #: perms/templates/perms/asset_permission_detail.html:98 terminal/models.py:26
#: terminal/templates/terminal/terminal_detail.html:63 users/models/group.py:15 #: terminal/templates/terminal/terminal_detail.html:63 users/models/group.py:15
#: users/models/user.py:47 users/templates/users/user_detail.html:111 #: users/models/user.py:47 users/templates/users/user_detail.html:111
#: users/templates/users/user_group_detail.html:67 #: users/templates/users/user_group_detail.html:67
...@@ -331,7 +331,7 @@ msgid "Default" ...@@ -331,7 +331,7 @@ msgid "Default"
msgstr "默认" msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:13 #: assets/models/cluster.py:36 assets/models/label.py:13
#: users/models/user.py:261 #: users/models/user.py:266
msgid "System" msgid "System"
msgstr "系统" msgstr "系统"
...@@ -352,13 +352,14 @@ msgid "Default asset group" ...@@ -352,13 +352,14 @@ msgid "Default asset group"
msgstr "默认资产组" msgstr "默认资产组"
#: assets/models/label.py:14 perms/models.py:15 #: assets/models/label.py:14 perms/models.py:15
#: terminal/backends/command/models.py:10 terminal/models.py:115 #: terminal/backends/command/models.py:10 terminal/models.py:122
#: terminal/templates/terminal/command_list.html:32 #: terminal/templates/terminal/command_list.html:32
#: terminal/templates/terminal/command_list.html:72 #: terminal/templates/terminal/command_list.html:72
#: terminal/templates/terminal/session_list.html:33 #: terminal/templates/terminal/session_list.html:33
#: terminal/templates/terminal/session_list.html:71 users/forms.py:190 #: terminal/templates/terminal/session_list.html:71 users/forms.py:190
#: users/models/user.py:30 users/templates/users/user_group_detail.html:78 #: users/models/user.py:30 users/models/user.py:254
#: users/templates/users/user_group_list.html:13 users/views/user.py:330 #: users/templates/users/user_group_detail.html:78
#: users/templates/users/user_group_list.html:13 users/views/user.py:333
msgid "User" msgid "User"
msgstr "用户" msgstr "用户"
...@@ -383,32 +384,32 @@ msgstr "ssh密钥" ...@@ -383,32 +384,32 @@ msgstr "ssh密钥"
msgid "SSH public key" msgid "SSH public key"
msgstr "ssh公钥" msgstr "ssh公钥"
#: assets/models/user.py:222 #: assets/models/user.py:219
msgid "Priority" msgid "Priority"
msgstr "优先级" msgstr "优先级"
#: assets/models/user.py:223 assets/templates/assets/system_user_detail.html:66 #: assets/models/user.py:220 assets/templates/assets/system_user_detail.html:66
msgid "Protocol" msgid "Protocol"
msgstr "协议" msgstr "协议"
#: assets/models/user.py:224 assets/templates/assets/_system_user.html:58 #: assets/models/user.py:221 assets/templates/assets/_system_user.html:58
#: assets/templates/assets/system_user_detail.html:118 #: assets/templates/assets/system_user_detail.html:118
#: assets/templates/assets/system_user_update.html:11 #: assets/templates/assets/system_user_update.html:11
msgid "Auto push" msgid "Auto push"
msgstr "自动推送" msgstr "自动推送"
#: assets/models/user.py:225 assets/templates/assets/system_user_detail.html:70 #: assets/models/user.py:222 assets/templates/assets/system_user_detail.html:70
msgid "Sudo" msgid "Sudo"
msgstr "Sudo" msgstr "Sudo"
#: assets/models/user.py:226 assets/templates/assets/system_user_detail.html:75 #: assets/models/user.py:223 assets/templates/assets/system_user_detail.html:75
msgid "Shell" msgid "Shell"
msgstr "Shell" msgstr "Shell"
#: assets/models/user.py:269 perms/forms.py:25 perms/models.py:19 #: assets/models/user.py:266 perms/forms.py:25 perms/models.py:19
#: perms/models.py:76 perms/templates/perms/asset_permission_detail.html:136 #: perms/models.py:76 perms/templates/perms/asset_permission_detail.html:136
#: perms/templates/perms/asset_permission_list.html:69 templates/_nav.html:24 #: perms/templates/perms/asset_permission_list.html:69 templates/_nav.html:25
#: terminal/backends/command/models.py:12 terminal/models.py:117 #: terminal/backends/command/models.py:12 terminal/models.py:124
#: terminal/templates/terminal/command_list.html:48 #: terminal/templates/terminal/command_list.html:48
#: terminal/templates/terminal/command_list.html:74 #: terminal/templates/terminal/command_list.html:74
#: terminal/templates/terminal/session_list.html:49 #: terminal/templates/terminal/session_list.html:49
...@@ -463,7 +464,7 @@ msgstr "推送系统用户到节点: {}" ...@@ -463,7 +464,7 @@ msgstr "推送系统用户到节点: {}"
#: assets/templates/assets/_asset_group_bulk_update_modal.html:5 #: assets/templates/assets/_asset_group_bulk_update_modal.html:5
msgid "Update asset group" msgid "Update asset group"
msgstr "编辑用户组" msgstr "更新用户组"
#: assets/templates/assets/_asset_group_bulk_update_modal.html:8 #: assets/templates/assets/_asset_group_bulk_update_modal.html:8
msgid "Hint: only change the field you want to update." msgid "Hint: only change the field you want to update."
...@@ -474,12 +475,11 @@ msgstr "仅修改你需要更新的字段" ...@@ -474,12 +475,11 @@ msgstr "仅修改你需要更新的字段"
#: assets/views/admin_user.py:29 assets/views/admin_user.py:47 #: assets/views/admin_user.py:29 assets/views/admin_user.py:47
#: assets/views/admin_user.py:63 assets/views/admin_user.py:78 #: assets/views/admin_user.py:63 assets/views/admin_user.py:78
#: assets/views/admin_user.py:102 assets/views/asset.py:48 #: assets/views/admin_user.py:102 assets/views/asset.py:48
#: assets/views/asset.py:61 assets/views/asset.py:95 assets/views/asset.py:155 #: assets/views/asset.py:94 assets/views/asset.py:154 assets/views/asset.py:171
#: assets/views/asset.py:172 assets/views/asset.py:196 assets/views/label.py:26 #: assets/views/asset.py:195 assets/views/label.py:26 assets/views/label.py:42
#: assets/views/label.py:42 assets/views/label.py:58 #: assets/views/label.py:58 assets/views/system_user.py:28
#: assets/views/system_user.py:28 assets/views/system_user.py:44 #: assets/views/system_user.py:44 assets/views/system_user.py:60
#: assets/views/system_user.py:60 assets/views/system_user.py:74 #: assets/views/system_user.py:74 templates/_nav.html:20
#: templates/_nav.html:19
msgid "Assets" msgid "Assets"
msgstr "资产管理" msgstr "资产管理"
...@@ -522,14 +522,14 @@ msgid "If set id, will use this id update asset existed" ...@@ -522,14 +522,14 @@ msgid "If set id, will use this id update asset existed"
msgstr "如果设置了id,则会使用该行信息更新该id的资产" msgstr "如果设置了id,则会使用该行信息更新该id的资产"
#: assets/templates/assets/_asset_list_modal.html:22 #: assets/templates/assets/_asset_list_modal.html:22
#: assets/templates/assets/asset_list.html:82 #: assets/templates/assets/asset_list.html:88
#: assets/templates/assets/user_asset_list.html:22 #: assets/templates/assets/user_asset_list.html:22
msgid "Hardware" msgid "Hardware"
msgstr "硬件" msgstr "硬件"
#: assets/templates/assets/_asset_list_modal.html:23 #: assets/templates/assets/_asset_list_modal.html:23
#: assets/templates/assets/asset_detail.html:143 #: assets/templates/assets/asset_detail.html:143
#: assets/templates/assets/asset_list.html:83 #: assets/templates/assets/asset_list.html:89
#: assets/templates/assets/user_asset_list.html:23 perms/models.py:20 #: assets/templates/assets/user_asset_list.html:23 perms/models.py:20
#: perms/models.py:77 #: perms/models.py:77
#: perms/templates/perms/asset_permission_create_update.html:51 #: perms/templates/perms/asset_permission_create_update.html:51
...@@ -548,7 +548,7 @@ msgstr "激活中" ...@@ -548,7 +548,7 @@ msgstr "激活中"
#: assets/templates/assets/admin_user_assets.html:54 #: assets/templates/assets/admin_user_assets.html:54
#: assets/templates/assets/admin_user_list.html:25 #: assets/templates/assets/admin_user_list.html:25
#: assets/templates/assets/asset_detail.html:357 #: assets/templates/assets/asset_detail.html:357
#: assets/templates/assets/asset_list.html:84 #: assets/templates/assets/asset_list.html:90
#: assets/templates/assets/system_user_asset.html:52 #: assets/templates/assets/system_user_asset.html:52
#: assets/templates/assets/system_user_list.html:27 #: assets/templates/assets/system_user_list.html:27
#: users/templates/users/user_granted_asset.html:47 #: users/templates/users/user_granted_asset.html:47
...@@ -558,13 +558,13 @@ msgstr "可连接" ...@@ -558,13 +558,13 @@ msgstr "可连接"
#: assets/templates/assets/_asset_list_modal.html:25 #: assets/templates/assets/_asset_list_modal.html:25
#: assets/templates/assets/admin_user_list.html:29 #: assets/templates/assets/admin_user_list.html:29
#: assets/templates/assets/asset_list.html:85 #: assets/templates/assets/asset_list.html:91
#: assets/templates/assets/label_list.html:17 #: assets/templates/assets/label_list.html:17
#: assets/templates/assets/system_user_list.html:31 #: assets/templates/assets/system_user_list.html:31
#: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:61 #: ops/templates/ops/adhoc_history.html:59 ops/templates/ops/task_adhoc.html:61
#: ops/templates/ops/task_history.html:62 ops/templates/ops/task_list.html:41 #: ops/templates/ops/task_history.html:62 ops/templates/ops/task_list.html:41
#: perms/templates/perms/asset_permission_list.html:72 #: perms/templates/perms/asset_permission_list.html:72
#: terminal/templates/terminal/session_list.html:79 #: terminal/templates/terminal/session_list.html:80
#: terminal/templates/terminal/terminal_list.html:36 #: terminal/templates/terminal/terminal_list.html:36
#: users/templates/users/user_group_list.html:15 #: users/templates/users/user_group_list.html:15
#: users/templates/users/user_list.html:28 #: users/templates/users/user_list.html:28
...@@ -572,25 +572,25 @@ msgid "Action" ...@@ -572,25 +572,25 @@ msgid "Action"
msgstr "动作" msgstr "动作"
#: assets/templates/assets/_asset_list_modal.html:34 #: assets/templates/assets/_asset_list_modal.html:34
#: assets/templates/assets/asset_list.html:94 #: assets/templates/assets/asset_list.html:100
#: users/templates/users/user_list.html:37 #: users/templates/users/user_list.html:37
msgid "Delete selected" msgid "Delete selected"
msgstr "批量删除" msgstr "批量删除"
#: assets/templates/assets/_asset_list_modal.html:35 #: assets/templates/assets/_asset_list_modal.html:35
#: assets/templates/assets/asset_list.html:95 #: assets/templates/assets/asset_list.html:101
#: users/templates/users/user_list.html:38 #: users/templates/users/user_list.html:38
msgid "Update selected" msgid "Update selected"
msgstr "批量更新" msgstr "批量更新"
#: assets/templates/assets/_asset_list_modal.html:36 #: assets/templates/assets/_asset_list_modal.html:36
#: assets/templates/assets/asset_list.html:97 #: assets/templates/assets/asset_list.html:103
#: users/templates/users/user_list.html:39 #: users/templates/users/user_list.html:39
msgid "Deactive selected" msgid "Deactive selected"
msgstr "禁用所选" msgstr "禁用所选"
#: assets/templates/assets/_asset_list_modal.html:37 #: assets/templates/assets/_asset_list_modal.html:37
#: assets/templates/assets/asset_list.html:98 #: assets/templates/assets/asset_list.html:104
#: users/templates/users/user_list.html:40 #: users/templates/users/user_list.html:40
msgid "Active selected" msgid "Active selected"
msgstr "激活所选" msgstr "激活所选"
...@@ -599,16 +599,17 @@ msgstr "激活所选" ...@@ -599,16 +599,17 @@ msgstr "激活所选"
#: assets/templates/assets/_system_user.html:71 #: assets/templates/assets/_system_user.html:71
#: assets/templates/assets/admin_user_create_update.html:46 #: assets/templates/assets/admin_user_create_update.html:46
#: assets/templates/assets/asset_bulk_update.html:24 #: assets/templates/assets/asset_bulk_update.html:24
#: assets/templates/assets/asset_create.html:65 #: assets/templates/assets/asset_create.html:66
#: assets/templates/assets/asset_list.html:102 #: assets/templates/assets/asset_list.html:108
#: assets/templates/assets/asset_update.html:69 #: assets/templates/assets/asset_update.html:70
#: assets/templates/assets/label_create_update.html:17 #: assets/templates/assets/label_create_update.html:17
#: common/templates/common/basic_setting.html:59 #: common/templates/common/basic_setting.html:59
#: common/templates/common/email_setting.html:60 #: common/templates/common/email_setting.html:60
#: common/templates/common/ldap_setting.html:60 #: common/templates/common/ldap_setting.html:60
#: common/templates/common/terminal_setting.html:108 #: common/templates/common/terminal_setting.html:103
#: perms/templates/perms/asset_permission_create_update.html:72 #: perms/templates/perms/asset_permission_create_update.html:72
#: terminal/templates/terminal/terminal_update.html:47 #: terminal/templates/terminal/session_list.html:120
#: terminal/templates/terminal/terminal_update.html:48
#: users/templates/users/_user.html:44 #: users/templates/users/_user.html:44
#: users/templates/users/first_login.html:62 #: users/templates/users/first_login.html:62
#: users/templates/users/forgot_password.html:44 #: users/templates/users/forgot_password.html:44
...@@ -624,7 +625,7 @@ msgstr "提交" ...@@ -624,7 +625,7 @@ msgstr "提交"
#: assets/templates/assets/admin_user_detail.html:24 #: assets/templates/assets/admin_user_detail.html:24
#: assets/templates/assets/admin_user_list.html:84 #: assets/templates/assets/admin_user_list.html:84
#: assets/templates/assets/asset_detail.html:24 #: assets/templates/assets/asset_detail.html:24
#: assets/templates/assets/asset_list.html:160 #: assets/templates/assets/asset_list.html:166
#: assets/templates/assets/label_list.html:38 #: assets/templates/assets/label_list.html:38
#: assets/templates/assets/system_user_detail.html:26 #: assets/templates/assets/system_user_detail.html:26
#: assets/templates/assets/system_user_list.html:85 #: assets/templates/assets/system_user_list.html:85
...@@ -643,7 +644,7 @@ msgstr "更新" ...@@ -643,7 +644,7 @@ msgstr "更新"
#: assets/templates/assets/admin_user_detail.html:28 #: assets/templates/assets/admin_user_detail.html:28
#: assets/templates/assets/admin_user_list.html:85 #: assets/templates/assets/admin_user_list.html:85
#: assets/templates/assets/asset_detail.html:28 #: assets/templates/assets/asset_detail.html:28
#: assets/templates/assets/asset_list.html:161 #: assets/templates/assets/asset_list.html:167
#: assets/templates/assets/label_list.html:39 #: assets/templates/assets/label_list.html:39
#: assets/templates/assets/system_user_detail.html:30 #: assets/templates/assets/system_user_detail.html:30
#: assets/templates/assets/system_user_list.html:86 #: assets/templates/assets/system_user_list.html:86
...@@ -673,8 +674,8 @@ msgid "Basic" ...@@ -673,8 +674,8 @@ msgid "Basic"
msgstr "基本" msgstr "基本"
#: assets/templates/assets/_system_user.html:44 #: assets/templates/assets/_system_user.html:44
#: assets/templates/assets/asset_create.html:23 #: assets/templates/assets/asset_create.html:24
#: assets/templates/assets/asset_update.html:28 #: assets/templates/assets/asset_update.html:29
#: assets/templates/assets/system_user_update.html:7 #: assets/templates/assets/system_user_update.html:7
#: users/templates/users/user_create.html:9 #: users/templates/users/user_create.html:9
#: users/templates/users/user_update.html:6 #: users/templates/users/user_update.html:6
...@@ -683,28 +684,28 @@ msgstr "认证" ...@@ -683,28 +684,28 @@ msgstr "认证"
#: assets/templates/assets/_system_user.html:47 #: assets/templates/assets/_system_user.html:47
msgid "Auto generate key" msgid "Auto generate key"
msgstr "自动生成钥" msgstr "自动生成钥"
#: assets/templates/assets/_system_user.html:64 #: assets/templates/assets/_system_user.html:64
#: assets/templates/assets/asset_create.html:57 #: assets/templates/assets/asset_create.html:58
#: assets/templates/assets/asset_update.html:61 #: assets/templates/assets/asset_update.html:62
#: perms/templates/perms/asset_permission_create_update.html:49 #: perms/templates/perms/asset_permission_create_update.html:49
#: terminal/templates/terminal/terminal_update.html:41 #: terminal/templates/terminal/terminal_update.html:42
msgid "Other" msgid "Other"
msgstr "其它" msgstr "其它"
#: assets/templates/assets/_system_user.html:70 #: assets/templates/assets/_system_user.html:70
#: assets/templates/assets/admin_user_create_update.html:45 #: assets/templates/assets/admin_user_create_update.html:45
#: assets/templates/assets/asset_bulk_update.html:23 #: assets/templates/assets/asset_bulk_update.html:23
#: assets/templates/assets/asset_create.html:64 #: assets/templates/assets/asset_create.html:65
#: assets/templates/assets/asset_update.html:68 #: assets/templates/assets/asset_update.html:69
#: assets/templates/assets/label_create_update.html:16 #: assets/templates/assets/label_create_update.html:16
#: common/templates/common/basic_setting.html:58 #: common/templates/common/basic_setting.html:58
#: common/templates/common/email_setting.html:59 #: common/templates/common/email_setting.html:59
#: common/templates/common/ldap_setting.html:59 #: common/templates/common/ldap_setting.html:59
#: common/templates/common/terminal_setting.html:106 #: common/templates/common/terminal_setting.html:101
#: perms/templates/perms/asset_permission_create_update.html:71 #: perms/templates/perms/asset_permission_create_update.html:71
#: terminal/templates/terminal/terminal_update.html:46 #: terminal/templates/terminal/terminal_update.html:47
#: users/templates/users/_user.html:43 #: users/templates/users/_user.html:43
#: users/templates/users/user_bulk_update.html:23 #: users/templates/users/user_bulk_update.html:23
#: users/templates/users/user_password_update.html:58 #: users/templates/users/user_password_update.html:58
...@@ -773,7 +774,7 @@ msgstr "替换资产的管理员" ...@@ -773,7 +774,7 @@ msgstr "替换资产的管理员"
#: assets/templates/assets/admin_user_detail.html:100 #: assets/templates/assets/admin_user_detail.html:100
#: assets/templates/assets/asset_detail.html:198 #: assets/templates/assets/asset_detail.html:198
#: assets/templates/assets/asset_list.html:482 #: assets/templates/assets/asset_list.html:541
#: assets/templates/assets/system_user_detail.html:181 #: assets/templates/assets/system_user_detail.html:181
#: assets/templates/assets/system_user_list.html:135 templates/_modal.html:16 #: assets/templates/assets/system_user_list.html:135 templates/_modal.html:16
#: terminal/templates/terminal/session_detail.html:108 #: terminal/templates/terminal/session_detail.html:108
...@@ -799,20 +800,20 @@ msgstr "不可达" ...@@ -799,20 +800,20 @@ msgstr "不可达"
msgid "Ratio" msgid "Ratio"
msgstr "比例" msgstr "比例"
#: assets/templates/assets/asset_create.html:27 #: assets/templates/assets/asset_create.html:28
#: assets/templates/assets/asset_update.html:32 perms/models.py:74 #: assets/templates/assets/asset_update.html:33 perms/models.py:74
#: perms/templates/perms/asset_permission_create_update.html:40 #: perms/templates/perms/asset_permission_create_update.html:40
#: perms/templates/perms/asset_permission_list.html:67 #: perms/templates/perms/asset_permission_list.html:67
msgid "Node" msgid "Node"
msgstr "节点" msgstr "节点"
#: assets/templates/assets/asset_create.html:33 #: assets/templates/assets/asset_create.html:34
#: assets/templates/assets/asset_list.html:69 #: assets/templates/assets/asset_list.html:75
#: assets/templates/assets/asset_update.html:38 #: assets/templates/assets/asset_update.html:39
msgid "Label" msgid "Label"
msgstr "标签" msgstr "标签"
#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:197 #: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:196
msgid "Asset detail" msgid "Asset detail"
msgstr "资产详情" msgstr "资产详情"
...@@ -850,50 +851,50 @@ msgstr "刷新" ...@@ -850,50 +851,50 @@ msgstr "刷新"
msgid "Update successfully!" msgid "Update successfully!"
msgstr "更新成功" msgstr "更新成功"
#: assets/templates/assets/asset_list.html:57 #: assets/templates/assets/asset_list.html:63
#: assets/templates/assets/asset_list.html:114 assets/views/asset.py:96 #: assets/templates/assets/asset_list.html:120 assets/views/asset.py:95
msgid "Create asset" msgid "Create asset"
msgstr "创建资产" msgstr "创建资产"
#: assets/templates/assets/asset_list.html:61 #: assets/templates/assets/asset_list.html:67
#: users/templates/users/user_list.html:7 #: users/templates/users/user_list.html:7
msgid "Import" msgid "Import"
msgstr "导入" msgstr "导入"
#: assets/templates/assets/asset_list.html:64 #: assets/templates/assets/asset_list.html:70
#: users/templates/users/user_list.html:10 #: users/templates/users/user_list.html:10
msgid "Export" msgid "Export"
msgstr "导出" msgstr "导出"
#: assets/templates/assets/asset_list.html:96 #: assets/templates/assets/asset_list.html:102
msgid "Remove from this node" msgid "Remove from this node"
msgstr "从节点移除" msgstr "从节点移除"
#: assets/templates/assets/asset_list.html:115 #: assets/templates/assets/asset_list.html:121
msgid "Add asset" msgid "Add asset"
msgstr "添加资产到节点" msgstr "添加资产到节点"
#: assets/templates/assets/asset_list.html:117 #: assets/templates/assets/asset_list.html:123
msgid "Add node" msgid "Add node"
msgstr "新建节点" msgstr "新建节点"
#: assets/templates/assets/asset_list.html:118 #: assets/templates/assets/asset_list.html:124
msgid "Rename node" msgid "Rename node"
msgstr "重命名节点" msgstr "重命名节点"
#: assets/templates/assets/asset_list.html:120 #: assets/templates/assets/asset_list.html:126
msgid "Delete node" msgid "Delete node"
msgstr "删除节点" msgstr "删除节点"
#: assets/templates/assets/asset_list.html:195 #: assets/templates/assets/asset_list.html:201
msgid "Create node failed" msgid "Create node failed"
msgstr "创建节点失败" msgstr "创建节点失败"
#: assets/templates/assets/asset_list.html:208 #: assets/templates/assets/asset_list.html:214
msgid "Have child node, cancel" msgid "Have child node, cancel"
msgstr "存在子节点,不能删除" msgstr "存在子节点,不能删除"
#: assets/templates/assets/asset_list.html:477 #: assets/templates/assets/asset_list.html:536
#: assets/templates/assets/system_user_list.html:130 #: assets/templates/assets/system_user_list.html:130
#: users/templates/users/user_detail.html:334 #: users/templates/users/user_detail.html:334
#: users/templates/users/user_detail.html:359 #: users/templates/users/user_detail.html:359
...@@ -902,24 +903,24 @@ msgstr "存在子节点,不能删除" ...@@ -902,24 +903,24 @@ msgstr "存在子节点,不能删除"
msgid "Are you sure?" msgid "Are you sure?"
msgstr "你确认吗?" msgstr "你确认吗?"
#: assets/templates/assets/asset_list.html:478 #: assets/templates/assets/asset_list.html:537
msgid "This will delete the selected assets !!!" msgid "This will delete the selected assets !!!"
msgstr "删除选择资产" msgstr "删除选择资产"
#: assets/templates/assets/asset_list.html:486 #: assets/templates/assets/asset_list.html:545
msgid "Asset Deleted." msgid "Asset Deleted."
msgstr "已被删除" msgstr "已被删除"
#: assets/templates/assets/asset_list.html:487 #: assets/templates/assets/asset_list.html:546
#: assets/templates/assets/asset_list.html:492 #: assets/templates/assets/asset_list.html:551
msgid "Asset Delete" msgid "Asset Delete"
msgstr "删除" msgstr "删除"
#: assets/templates/assets/asset_list.html:491 #: assets/templates/assets/asset_list.html:550
msgid "Asset Deleting failed." msgid "Asset Deleting failed."
msgstr "删除失败" msgstr "删除失败"
#: assets/templates/assets/asset_update.html:57 #: assets/templates/assets/asset_update.html:58
msgid "Configuration" msgid "Configuration"
msgstr "配置" msgstr "配置"
...@@ -1011,17 +1012,21 @@ msgstr "更新管理用户" ...@@ -1011,17 +1012,21 @@ msgstr "更新管理用户"
msgid "Admin user detail" msgid "Admin user detail"
msgstr "管理用户详情" msgstr "管理用户详情"
#: assets/views/asset.py:49 assets/views/asset.py:62 templates/_nav.html:22 #: assets/views/asset.py:49 templates/_nav.html:23
msgid "Asset list" msgid "Asset list"
msgstr "资产列表" msgstr "资产列表"
#: assets/views/asset.py:156 #: assets/views/asset.py:61 templates/_nav_user.html:4
msgid "My assets"
msgstr "我的资产"
#: assets/views/asset.py:155
msgid "Bulk update asset" msgid "Bulk update asset"
msgstr "批量更新资产" msgstr "批量更新资产"
#: assets/views/asset.py:173 #: assets/views/asset.py:172
msgid "Update asset" msgid "Update asset"
msgstr "编辑资产" msgstr "更新资产"
#: assets/views/asset.py:296 #: assets/views/asset.py:296
msgid "already exists" msgid "already exists"
...@@ -1033,7 +1038,7 @@ msgstr "标签列表" ...@@ -1033,7 +1038,7 @@ msgstr "标签列表"
#: assets/views/label.py:59 #: assets/views/label.py:59
msgid "Update label" msgid "Update label"
msgstr "编辑标签" msgstr "更新标签"
#: assets/views/system_user.py:29 #: assets/views/system_user.py:29
msgid "System user list" msgid "System user list"
...@@ -1192,10 +1197,10 @@ msgstr "密码认证" ...@@ -1192,10 +1197,10 @@ msgstr "密码认证"
#: common/forms.py:156 #: common/forms.py:156
msgid "Public key auth" msgid "Public key auth"
msgstr "钥认证" msgstr "钥认证"
#: common/forms.py:159 common/templates/common/terminal_setting.html:63 #: common/forms.py:159 common/templates/common/terminal_setting.html:63
#: terminal/forms.py:21 terminal/models.py:19 #: terminal/forms.py:30 terminal/models.py:20
msgid "Command storage" msgid "Command storage"
msgstr "命令存储" msgstr "命令存储"
...@@ -1205,8 +1210,8 @@ msgid "" ...@@ -1205,8 +1210,8 @@ msgid ""
"other storage and some terminal using" "other storage and some terminal using"
msgstr "设置终端命令存储,default是默认用的存储方式" msgstr "设置终端命令存储,default是默认用的存储方式"
#: common/forms.py:165 common/templates/common/terminal_setting.html:84 #: common/forms.py:165 common/templates/common/terminal_setting.html:81
#: terminal/models.py:20 #: terminal/forms.py:34 terminal/models.py:21
msgid "Replay storage" msgid "Replay storage"
msgstr "录像存储" msgstr "录像存储"
...@@ -1263,19 +1268,13 @@ msgid "Test connection" ...@@ -1263,19 +1268,13 @@ msgid "Test connection"
msgstr "测试连接" msgstr "测试连接"
#: common/templates/common/terminal_setting.html:68 #: common/templates/common/terminal_setting.html:68
#: common/templates/common/terminal_setting.html:89 #: common/templates/common/terminal_setting.html:86
#: users/templates/users/login_log_list.html:50 #: users/templates/users/login_log_list.html:50
msgid "Type" msgid "Type"
msgstr "类型" msgstr "类型"
#: common/templates/common/terminal_setting.html:90
#: users/templates/users/reset_password.html:57
#: users/templates/users/user_profile.html:20
msgid "Setting"
msgstr "设置"
#: common/views.py:20 common/views.py:46 common/views.py:72 common/views.py:102 #: common/views.py:20 common/views.py:46 common/views.py:72 common/views.py:102
#: templates/_nav.html:66 #: templates/_nav.html:72
msgid "Settings" msgid "Settings"
msgstr "系统设置" msgstr "系统设置"
...@@ -1430,7 +1429,7 @@ msgstr "执行历史" ...@@ -1430,7 +1429,7 @@ msgstr "执行历史"
#: ops/templates/ops/adhoc_history.html:52 #: ops/templates/ops/adhoc_history.html:52
#: ops/templates/ops/adhoc_history_detail.html:58 #: ops/templates/ops/adhoc_history_detail.html:58
#: ops/templates/ops/task_history.html:55 terminal/models.py:124 #: ops/templates/ops/task_history.html:55 terminal/models.py:132
#: terminal/templates/terminal/session_list.html:77 #: terminal/templates/terminal/session_list.html:77
msgid "Date start" msgid "Date start"
msgstr "开始日期" msgstr "开始日期"
...@@ -1542,7 +1541,7 @@ msgstr "任务开始: " ...@@ -1542,7 +1541,7 @@ msgstr "任务开始: "
msgid "Ops" msgid "Ops"
msgstr "作业中心" msgstr "作业中心"
#: ops/views.py:37 templates/_nav.html:52 #: ops/views.py:37 templates/_nav.html:58
msgid "Task list" msgid "Task list"
msgstr "任务列表" msgstr "任务列表"
...@@ -1551,8 +1550,9 @@ msgid "Task run history" ...@@ -1551,8 +1550,9 @@ msgid "Task run history"
msgstr "执行历史" msgstr "执行历史"
#: perms/forms.py:22 perms/models.py:16 perms/models.py:75 #: perms/forms.py:22 perms/models.py:16 perms/models.py:75
#: perms/templates/perms/asset_permission_list.html:68 templates/_nav.html:13 #: perms/templates/perms/asset_permission_list.html:68 templates/_nav.html:14
#: users/models/user.py:37 users/templates/users/_select_user_modal.html:16 #: users/models/group.py:25 users/models/user.py:37
#: users/templates/users/_select_user_modal.html:16
#: users/templates/users/user_detail.html:179 #: users/templates/users/user_detail.html:179
#: users/templates/users/user_list.html:26 #: users/templates/users/user_list.html:26
msgid "User group" msgid "User group"
...@@ -1566,7 +1566,7 @@ msgstr "用户组" ...@@ -1566,7 +1566,7 @@ msgstr "用户组"
msgid "Date expired" msgid "Date expired"
msgstr "失效日期" msgstr "失效日期"
#: perms/models.py:88 templates/_nav.html:32 #: perms/models.py:88 templates/_nav.html:33
msgid "Asset permission" msgid "Asset permission"
msgstr "资产授权" msgstr "资产授权"
...@@ -1660,7 +1660,7 @@ msgstr "添加用户组" ...@@ -1660,7 +1660,7 @@ msgstr "添加用户组"
msgid "Select user groups" msgid "Select user groups"
msgstr "选择用户组" msgstr "选择用户组"
#: perms/views.py:23 perms/views.py:47 perms/views.py:67 templates/_nav.html:29 #: perms/views.py:23 perms/views.py:47 perms/views.py:67 templates/_nav.html:30
msgid "Perms" msgid "Perms"
msgstr "权限管理" msgstr "权限管理"
...@@ -1677,37 +1677,41 @@ msgid "Update asset permission" ...@@ -1677,37 +1677,41 @@ msgid "Update asset permission"
msgstr "更新资产授权" msgstr "更新资产授权"
#: templates/_header_bar.html:18 #: templates/_header_bar.html:18
msgid "Help" msgid "Supports"
msgstr "帮助" msgstr "商业支持"
#: templates/_header_bar.html:23
msgid "Docs"
msgstr "文档"
#: templates/_header_bar.html:32 templates/_nav_user.html:9 #: templates/_header_bar.html:37 templates/_nav_user.html:9
#: users/templates/users/_user.html:36 #: users/templates/users/_user.html:36
#: users/templates/users/user_password_update.html:37 #: users/templates/users/user_password_update.html:37
#: users/templates/users/user_profile.html:17 #: users/templates/users/user_profile.html:17
#: users/templates/users/user_profile_update.html:37 #: users/templates/users/user_profile_update.html:37
#: users/templates/users/user_profile_update.html:57 #: users/templates/users/user_profile_update.html:57
#: users/templates/users/user_pubkey_update.html:37 users/views/user.py:313 #: users/templates/users/user_pubkey_update.html:37 users/views/user.py:316
msgid "Profile" msgid "Profile"
msgstr "个人信息" msgstr "个人信息"
#: templates/_header_bar.html:36 #: templates/_header_bar.html:40
msgid "Admin page" msgid "Admin page"
msgstr "管理页面" msgstr "管理页面"
#: templates/_header_bar.html:38 #: templates/_header_bar.html:42
msgid "User page" msgid "User page"
msgstr "用户页面" msgstr "用户页面"
#: templates/_header_bar.html:41 #: templates/_header_bar.html:45
msgid "Logout" msgid "Logout"
msgstr "注销登录" msgstr "注销登录"
#: templates/_header_bar.html:45 users/templates/users/login.html:42 #: templates/_header_bar.html:49 users/templates/users/login.html:44
#: users/templates/users/login.html:61 #: users/templates/users/login.html:64
msgid "Login" msgid "Login"
msgstr "登录" msgstr "登录"
#: templates/_header_bar.html:58 templates/_nav.html:4 #: templates/_header_bar.html:62 templates/_nav.html:4
msgid "Dashboard" msgid "Dashboard"
msgstr "仪表盘" msgstr "仪表盘"
...@@ -1733,7 +1737,7 @@ msgid "" ...@@ -1733,7 +1737,7 @@ msgid ""
" " " "
msgstr "" msgstr ""
"\n" "\n"
" 您的ssh钥没有设置或已失效,请点击 <a href=" " 您的ssh钥没有设置或已失效,请点击 <a href="
"\"%(user_pubkey_update)s\"> 链接 </a> 更新\n" "\"%(user_pubkey_update)s\"> 链接 </a> 更新\n"
" " " "
...@@ -1741,39 +1745,43 @@ msgstr "" ...@@ -1741,39 +1745,43 @@ msgstr ""
msgid "Close" msgid "Close"
msgstr "关闭" msgstr "关闭"
#: templates/_nav.html:9 users/views/group.py:28 users/views/group.py:44 #: templates/_nav.html:10 users/views/group.py:28 users/views/group.py:44
#: users/views/group.py:62 users/views/group.py:79 users/views/login.py:200 #: users/views/group.py:62 users/views/group.py:79 users/views/group.py:95
#: users/views/login.py:249 users/views/user.py:57 users/views/user.py:72 #: users/views/login.py:209 users/views/login.py:258 users/views/user.py:59
#: users/views/user.py:91 users/views/user.py:147 users/views/user.py:300 #: users/views/user.py:74 users/views/user.py:93 users/views/user.py:149
#: users/views/user.py:312 users/views/user.py:348 users/views/user.py:370 #: users/views/user.py:304 users/views/user.py:351 users/views/user.py:373
msgid "Users" msgid "Users"
msgstr "用户管理" msgstr "用户管理"
#: templates/_nav.html:12 users/views/user.py:58 #: templates/_nav.html:13 users/views/user.py:60
msgid "User list" msgid "User list"
msgstr "用户列表" msgstr "用户列表"
#: templates/_nav.html:14 #: templates/_nav.html:15
msgid "Login logs" msgid "Login logs"
msgstr "登录日志" msgstr "登录日志"
#: templates/_nav.html:38 #: templates/_nav.html:39
msgid "Sessions" msgid "Sessions"
msgstr "会话管理" msgstr "会话管理"
#: templates/_nav.html:41 #: templates/_nav.html:42
msgid "Session online" msgid "Session online"
msgstr "在线会话" msgstr "在线会话"
#: templates/_nav.html:42 #: templates/_nav.html:43
msgid "Session offline" msgid "Session offline"
msgstr "历史会话" msgstr "历史会话"
#: templates/_nav.html:43 #: templates/_nav.html:44
msgid "Commands" msgid "Commands"
msgstr "命令记录" msgstr "命令记录"
#: templates/_nav.html:44 terminal/templates/terminal/session_list.html:75 #: templates/_nav.html:47 templates/_nav_user.html:14
msgid "Web terminal"
msgstr "Web终端"
#: templates/_nav.html:50 terminal/templates/terminal/session_list.html:75
#: terminal/views/command.py:47 terminal/views/session.py:75 #: terminal/views/command.py:47 terminal/views/session.py:75
#: terminal/views/session.py:92 terminal/views/session.py:114 #: terminal/views/session.py:92 terminal/views/session.py:114
#: terminal/views/terminal.py:31 terminal/views/terminal.py:46 #: terminal/views/terminal.py:31 terminal/views/terminal.py:46
...@@ -1781,18 +1789,10 @@ msgstr "命令记录" ...@@ -1781,18 +1789,10 @@ msgstr "命令记录"
msgid "Terminal" msgid "Terminal"
msgstr "终端管理" msgstr "终端管理"
#: templates/_nav.html:49 #: templates/_nav.html:55
msgid "Job Center" msgid "Job Center"
msgstr "作业中心" msgstr "作业中心"
#: templates/_nav_user.html:4
msgid "My assets"
msgstr "我的资产"
#: templates/_nav_user.html:14
msgid "Web terminal"
msgstr "Web终端"
#: templates/captcha/image.html:3 #: templates/captcha/image.html:3
msgid "Play CAPTCHA as audio file" msgid "Play CAPTCHA as audio file"
msgstr "语言播放验证码" msgstr "语言播放验证码"
...@@ -1819,71 +1819,75 @@ msgstr "输出" ...@@ -1819,71 +1819,75 @@ msgstr "输出"
msgid "Session" msgid "Session"
msgstr "会话" msgstr "会话"
#: terminal/forms.py:27 #: terminal/forms.py:44
msgid "Coco ssh listen port" msgid "Coco ssh listen port"
msgstr "SSH 监听端口" msgstr "SSH 监听端口"
#: terminal/forms.py:28 #: terminal/forms.py:45
msgid "Coco http/ws listen port" msgid "Coco http/ws listen port"
msgstr "Http/Websocket 监听端口" msgstr "Http/Websocket 监听端口"
#: terminal/models.py:16 #: terminal/models.py:17
msgid "Remote Address" msgid "Remote Address"
msgstr "远端地址" msgstr "远端地址"
#: terminal/models.py:17 #: terminal/models.py:18
msgid "SSH Port" msgid "SSH Port"
msgstr "SSH端口" msgstr "SSH端口"
#: terminal/models.py:18 #: terminal/models.py:19
msgid "HTTP Port" msgid "HTTP Port"
msgstr "HTTP端口" msgstr "HTTP端口"
#: terminal/models.py:91 #: terminal/models.py:98
msgid "Session Online" msgid "Session Online"
msgstr "在线会话" msgstr "在线会话"
#: terminal/models.py:92 #: terminal/models.py:99
msgid "CPU Usage" msgid "CPU Usage"
msgstr "CPU使用" msgstr "CPU使用"
#: terminal/models.py:93 #: terminal/models.py:100
msgid "Memory Used" msgid "Memory Used"
msgstr "内存使用" msgstr "内存使用"
#: terminal/models.py:94 #: terminal/models.py:101
msgid "Connections" msgid "Connections"
msgstr "连接数" msgstr "连接数"
#: terminal/models.py:95 #: terminal/models.py:102
msgid "Threads" msgid "Threads"
msgstr "线程数" msgstr "线程数"
#: terminal/models.py:96 #: terminal/models.py:103
msgid "Boot Time" msgid "Boot Time"
msgstr "运行时间" msgstr "运行时间"
#: terminal/models.py:119 terminal/templates/terminal/session_list.html:74 #: terminal/models.py:126 terminal/templates/terminal/session_list.html:74
#: terminal/templates/terminal/terminal_detail.html:47 #: terminal/templates/terminal/terminal_detail.html:47
msgid "Remote addr" msgid "Remote addr"
msgstr "远端地址" msgstr "远端地址"
#: terminal/models.py:121 terminal/templates/terminal/session_list.html:100 #: terminal/models.py:128 terminal/templates/terminal/session_list.html:102
msgid "Replay" msgid "Replay"
msgstr "回放" msgstr "回放"
#: terminal/models.py:122 terminal/templates/terminal/command_list.html:55 #: terminal/models.py:129 terminal/templates/terminal/command_list.html:55
#: terminal/templates/terminal/command_list.html:71 #: terminal/templates/terminal/command_list.html:71
#: terminal/templates/terminal/session_detail.html:48 #: terminal/templates/terminal/session_detail.html:48
#: terminal/templates/terminal/session_list.html:76 #: terminal/templates/terminal/session_list.html:76
msgid "Command" msgid "Command"
msgstr "命令" msgstr "命令"
#: terminal/models.py:125 #: terminal/models.py:131
msgid "Date last active"
msgstr "最后活跃日期"
#: terminal/models.py:133
msgid "Date end" msgid "Date end"
msgstr "结束日期" msgstr "结束日期"
#: terminal/models.py:142 #: terminal/models.py:150
msgid "Args" msgid "Args"
msgstr "参数" msgstr "参数"
...@@ -1922,19 +1926,25 @@ msgstr "监控" ...@@ -1922,19 +1926,25 @@ msgstr "监控"
msgid "Terminate session" msgid "Terminate session"
msgstr "终止会话" msgstr "终止会话"
#: terminal/templates/terminal/session_list.html:78 #: terminal/templates/terminal/session_list.html:79
msgid "Duration" msgid "Duration"
msgstr "时长" msgstr "时长"
#: terminal/templates/terminal/session_list.html:102 #: terminal/templates/terminal/session_list.html:104
msgid "Monitor" msgid "Monitor"
msgstr "监控" msgstr "监控"
#: terminal/templates/terminal/session_list.html:103 #: terminal/templates/terminal/session_list.html:105
msgid "Terminate" msgid "Terminate"
msgstr "终断" msgstr "终断"
#: terminal/templates/terminal/session_list.html:119 #: terminal/templates/terminal/session_list.html:116
#, fuzzy
#| msgid "Deactive selected"
msgid "Terminate selected"
msgstr "禁用所选"
#: terminal/templates/terminal/session_list.html:136
msgid "Terminate task send, waiting ..." msgid "Terminate task send, waiting ..."
msgstr "终断任务已发送,请等待" msgstr "终断任务已发送,请等待"
...@@ -2105,31 +2115,31 @@ msgstr "ssh密钥不合法" ...@@ -2105,31 +2115,31 @@ msgstr "ssh密钥不合法"
msgid "Select users" msgid "Select users"
msgstr "选择用户" msgstr "选择用户"
#: users/models/authentication.py:35 #: users/models/authentication.py:36
msgid "Private Token" msgid "Private Token"
msgstr "ssh密钥" msgstr "ssh密钥"
#: users/models/authentication.py:45 #: users/models/authentication.py:46
msgid "Login type" msgid "Login type"
msgstr "登录方式" msgstr "登录方式"
#: users/models/authentication.py:46 #: users/models/authentication.py:47
msgid "Login ip" msgid "Login ip"
msgstr "登录IP" msgstr "登录IP"
#: users/models/authentication.py:47 #: users/models/authentication.py:48
msgid "Login city" msgid "Login city"
msgstr "登录城市" msgstr "登录城市"
#: users/models/authentication.py:48 #: users/models/authentication.py:49
msgid "User agent" msgid "User agent"
msgstr "Agent" msgstr "Agent"
#: users/models/authentication.py:49 #: users/models/authentication.py:50
msgid "Date login" msgid "Date login"
msgstr "登录日期" msgstr "登录日期"
#: users/models/user.py:29 users/models/user.py:257 #: users/models/user.py:29 users/models/user.py:262
msgid "Administrator" msgid "Administrator"
msgstr "管理员" msgstr "管理员"
...@@ -2168,7 +2178,7 @@ msgstr "二次验证" ...@@ -2168,7 +2178,7 @@ msgstr "二次验证"
msgid "Public key" msgid "Public key"
msgstr "ssh公钥" msgstr "ssh公钥"
#: users/models/user.py:260 #: users/models/user.py:265
msgid "Administrator is the super user of system" msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员" msgstr "Administrator是初始的超级管理员"
...@@ -2239,7 +2249,7 @@ msgid " for more information" ...@@ -2239,7 +2249,7 @@ msgid " for more information"
msgstr "获取更多信息" msgstr "获取更多信息"
#: users/templates/users/forgot_password.html:26 #: users/templates/users/forgot_password.html:26
#: users/templates/users/login.html:64 #: users/templates/users/login.html:73
msgid "Forgot password" msgid "Forgot password"
msgstr "忘记密码" msgstr "忘记密码"
...@@ -2247,7 +2257,7 @@ msgstr "忘记密码" ...@@ -2247,7 +2257,7 @@ msgstr "忘记密码"
msgid "Input your email, that will send a mail to your" msgid "Input your email, that will send a mail to your"
msgstr "输入您的邮箱, 将会发一封重置邮件到您的邮箱中" msgstr "输入您的邮箱, 将会发一封重置邮件到您的邮箱中"
#: users/templates/users/login.html:47 #: users/templates/users/login.html:50
msgid "Captcha invalid" msgid "Captcha invalid"
msgstr "验证码错误" msgstr "验证码错误"
...@@ -2269,8 +2279,13 @@ msgstr "重置密码" ...@@ -2269,8 +2279,13 @@ msgstr "重置密码"
msgid "Password again" msgid "Password again"
msgstr "再次输入密码" msgstr "再次输入密码"
#: users/templates/users/reset_password.html:57
#: users/templates/users/user_profile.html:20
msgid "Setting"
msgstr "设置"
#: users/templates/users/user_create.html:4 #: users/templates/users/user_create.html:4
#: users/templates/users/user_list.html:16 users/views/user.py:72 #: users/templates/users/user_list.html:16 users/views/user.py:74
msgid "Create user" msgid "Create user"
msgstr "创建用户" msgstr "创建用户"
...@@ -2279,7 +2294,7 @@ msgid "Reset link will be generated and sent to the user. " ...@@ -2279,7 +2294,7 @@ msgid "Reset link will be generated and sent to the user. "
msgstr "生成重置密码连接,通过邮件发送给用户" msgstr "生成重置密码连接,通过邮件发送给用户"
#: users/templates/users/user_detail.html:19 #: users/templates/users/user_detail.html:19
#: users/templates/users/user_granted_asset.html:18 users/views/user.py:148 #: users/templates/users/user_granted_asset.html:18 users/views/user.py:150
msgid "User detail" msgid "User detail"
msgstr "用户详情" msgstr "用户详情"
...@@ -2320,7 +2335,7 @@ msgstr "将失效用户当前密码,并发送重设密码邮件到用户邮箱 ...@@ -2320,7 +2335,7 @@ msgstr "将失效用户当前密码,并发送重设密码邮件到用户邮箱
msgid "" msgid ""
"The reset-ssh-public-key E-mail has been sent successfully. Please inform " "The reset-ssh-public-key E-mail has been sent successfully. Please inform "
"the user to update his new ssh public key." "the user to update his new ssh public key."
msgstr "重设钥邮件将会发送到用户邮箱" msgstr "重设钥邮件将会发送到用户邮箱"
#: users/templates/users/user_detail.html:350 #: users/templates/users/user_detail.html:350
#: users/templates/users/user_profile.html:140 #: users/templates/users/user_profile.html:140
...@@ -2329,7 +2344,7 @@ msgstr "重置SSH密钥" ...@@ -2329,7 +2344,7 @@ msgstr "重置SSH密钥"
#: users/templates/users/user_detail.html:360 #: users/templates/users/user_detail.html:360
msgid "This will reset the user public key and send a reset mail" msgid "This will reset the user public key and send a reset mail"
msgstr "将会失效用户当前钥,并发送重置邮件到用户邮箱" msgstr "将会失效用户当前钥,并发送重置邮件到用户邮箱"
#: users/templates/users/user_detail.html:377 #: users/templates/users/user_detail.html:377
#: users/templates/users/user_profile.html:166 #: users/templates/users/user_profile.html:166
...@@ -2351,7 +2366,7 @@ msgstr "取消" ...@@ -2351,7 +2366,7 @@ msgstr "取消"
#: users/templates/users/user_group_granted_asset.html:18 #: users/templates/users/user_group_granted_asset.html:18
#: users/views/group.py:80 #: users/views/group.py:80
msgid "User group detail" msgid "User group detail"
msgstr "资产组详情" msgstr "用户组详情"
#: users/templates/users/user_group_detail.html:86 #: users/templates/users/user_group_detail.html:86
msgid "Add user" msgid "Add user"
...@@ -2399,8 +2414,8 @@ msgstr "用户删除失败" ...@@ -2399,8 +2414,8 @@ msgstr "用户删除失败"
msgid "OTP" msgid "OTP"
msgstr "" msgstr ""
#: users/templates/users/user_profile.html:100 users/views/user.py:177 #: users/templates/users/user_profile.html:100 users/views/user.py:179
#: users/views/user.py:229 #: users/views/user.py:233
msgid "User groups" msgid "User groups"
msgstr "用户组" msgstr "用户组"
...@@ -2420,9 +2435,9 @@ msgstr "指纹" ...@@ -2420,9 +2435,9 @@ msgstr "指纹"
msgid "Update public key" msgid "Update public key"
msgstr "更新密钥" msgstr "更新密钥"
#: users/templates/users/user_update.html:4 users/views/user.py:91 #: users/templates/users/user_update.html:4 users/views/user.py:93
msgid "Update user" msgid "Update user"
msgstr "编辑用户" msgstr "更新用户"
#: users/utils.py:35 #: users/utils.py:35
msgid "Create account successfully" msgid "Create account successfully"
...@@ -2552,7 +2567,7 @@ msgstr "禁用或失效" ...@@ -2552,7 +2567,7 @@ msgstr "禁用或失效"
#: users/utils.py:154 #: users/utils.py:154
msgid "Password or SSH public key invalid" msgid "Password or SSH public key invalid"
msgstr "密码或钥不合法" msgstr "密码或钥不合法"
#: users/views/group.py:29 #: users/views/group.py:29
msgid "User group list" msgid "User group list"
...@@ -2560,78 +2575,81 @@ msgstr "用户组列表" ...@@ -2560,78 +2575,81 @@ msgstr "用户组列表"
#: users/views/group.py:63 #: users/views/group.py:63
msgid "Update user group" msgid "Update user group"
msgstr "编辑用户组" msgstr "更新用户组"
#: users/views/group.py:96
msgid "User group granted asset"
msgstr "用户组授权资产"
#: users/views/login.py:56 #: users/views/login.py:57
msgid "Please enable cookies and try again." msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie" msgstr "设置你的浏览器支持cookie"
#: users/views/login.py:90 #: users/views/login.py:99
msgid "Logout success" msgid "Logout success"
msgstr "退出登录成功" msgstr "退出登录成功"
#: users/views/login.py:91 #: users/views/login.py:100
msgid "Logout success, return login page" msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面" msgstr "退出登录成功,返回到登录页面"
#: users/views/login.py:107 #: users/views/login.py:116
msgid "Email address invalid, please input again" msgid "Email address invalid, please input again"
msgstr "邮箱地址错误,重新输入" msgstr "邮箱地址错误,重新输入"
#: users/views/login.py:120 #: users/views/login.py:129
msgid "Send reset password message" msgid "Send reset password message"
msgstr "发送重置密码邮件" msgstr "发送重置密码邮件"
#: users/views/login.py:121 #: users/views/login.py:130
msgid "Send reset password mail success, login your mail box and follow it " msgid "Send reset password mail success, login your mail box and follow it "
msgstr "" msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)" "发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
#: users/views/login.py:135 #: users/views/login.py:144
msgid "Reset password success" msgid "Reset password success"
msgstr "重置密码成功" msgstr "重置密码成功"
#: users/views/login.py:136 #: users/views/login.py:145
msgid "Reset password success, return to login page" msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面" msgstr "重置密码成功,返回到登录页面"
#: users/views/login.py:153 users/views/login.py:166 #: users/views/login.py:162 users/views/login.py:175
msgid "Token invalid or expired" msgid "Token invalid or expired"
msgstr "Token错误或失效" msgstr "Token错误或失效"
#: users/views/login.py:162 #: users/views/login.py:171
msgid "Password not same" msgid "Password not same"
msgstr "密码不一致" msgstr "密码不一致"
#: users/views/login.py:200 #: users/views/login.py:209
msgid "First login" msgid "First login"
msgstr "首次登陆" msgstr "首次登陆"
#: users/views/login.py:250 #: users/views/login.py:259
msgid "Login log list" msgid "Login log list"
msgstr "登录日志" msgstr "登录日志"
#: users/views/user.py:101 #: users/views/user.py:103
msgid "Bulk update user success" msgid "Bulk update user success"
msgstr "批量更新用户成功" msgstr "批量更新用户成功"
#: users/views/user.py:206 #: users/views/user.py:208
msgid "Invalid file." msgid "Invalid file."
msgstr "文件不合法" msgstr "文件不合法"
#: users/views/user.py:301 #: users/views/user.py:305
msgid "User granted assets" msgid "User granted assets"
msgstr "用户授权资产" msgstr "用户授权资产"
#: users/views/user.py:331 #: users/views/user.py:334
msgid "Profile setting" msgid "Profile setting"
msgstr "个人信息设置" msgstr "个人信息设置"
#: users/views/user.py:349 #: users/views/user.py:352
msgid "Password update" msgid "Password update"
msgstr "密码更新" msgstr "密码更新"
#: users/views/user.py:371 #: users/views/user.py:374
msgid "Public key update" msgid "Public key update"
msgstr "秘钥更新" msgstr "密钥更新"
...@@ -397,6 +397,6 @@ BOOTSTRAP3 = { ...@@ -397,6 +397,6 @@ BOOTSTRAP3 = {
} }
TOKEN_EXPIRATION = CONFIG.TOKEN_EXPIRATION or 3600 TOKEN_EXPIRATION = CONFIG.TOKEN_EXPIRATION or 3600
DISPLAY_PER_PAGE = CONFIG.DISPLAY_PER_PAGE DISPLAY_PER_PAGE = CONFIG.DISPLAY_PER_PAGE or 25
DEFAULT_EXPIRED_YEARS = 70 DEFAULT_EXPIRED_YEARS = 70
USER_GUIDE_URL = "" USER_GUIDE_URL = ""
...@@ -4,16 +4,16 @@ from __future__ import unicode_literals ...@@ -4,16 +4,16 @@ from __future__ import unicode_literals
from django.conf.urls import url, include from django.conf.urls import url, include
from django.conf import settings from django.conf import settings
from django.conf.urls.static import static from django.conf.urls.static import static
from django.views.static import serve as static_serve
from rest_framework.schemas import get_schema_view from rest_framework.schemas import get_schema_view
from rest_framework_swagger.renderers import SwaggerUIRenderer, OpenAPIRenderer from rest_framework_swagger.renderers import SwaggerUIRenderer, OpenAPIRenderer
from .views import IndexView from .views import IndexView, LunaView
schema_view = get_schema_view(title='Users API', renderer_classes=[OpenAPIRenderer, SwaggerUIRenderer]) schema_view = get_schema_view(title='Users API', renderer_classes=[OpenAPIRenderer, SwaggerUIRenderer])
urlpatterns = [ urlpatterns = [
url(r'^$', IndexView.as_view(), name='index'), url(r'^$', IndexView.as_view(), name='index'),
url(r'^luna/$', LunaView.as_view(), name='luna-error'),
url(r'^users/', include('users.urls.views_urls', namespace='users')), url(r'^users/', include('users.urls.views_urls', namespace='users')),
url(r'^assets/', include('assets.urls.views_urls', namespace='assets')), url(r'^assets/', include('assets.urls.views_urls', namespace='assets')),
url(r'^perms/', include('perms.urls.views_urls', namespace='perms')), url(r'^perms/', include('perms.urls.views_urls', namespace='perms')),
......
from django.views.generic import TemplateView from django.http import HttpResponse
from django.views.generic import TemplateView, View
from django.utils import timezone from django.utils import timezone
from django.db.models import Count from django.db.models import Count
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
...@@ -45,7 +46,8 @@ class IndexView(LoginRequiredMixin, TemplateView): ...@@ -45,7 +46,8 @@ class IndexView(LoginRequiredMixin, TemplateView):
return self.session_week.values('user').distinct().count() return self.session_week.values('user').distinct().count()
def get_week_login_asset_count(self): def get_week_login_asset_count(self):
return self.session_week.values('asset').distinct().count() return self.session_week.count()
# return self.session_week.values('asset').distinct().count()
def get_month_day_metrics(self): def get_month_day_metrics(self):
month_str = [d.strftime('%m-%d') for d in self.session_month_dates] or ['0'] month_str = [d.strftime('%m-%d') for d in self.session_month_dates] or ['0']
...@@ -149,3 +151,12 @@ class IndexView(LoginRequiredMixin, TemplateView): ...@@ -149,3 +151,12 @@ class IndexView(LoginRequiredMixin, TemplateView):
kwargs.update(context) kwargs.update(context)
return super(IndexView, self).get_context_data(**kwargs) return super(IndexView, self).get_context_data(**kwargs)
class LunaView(View):
def get(self, request):
msg = """
Luna是单独部署的一个程序,你需要部署luna,coco,配置nginx做url分发,
如果你看到了这个页面,证明你访问的不是nginx监听的端口,祝你好运
"""
return HttpResponse(msg)
\ No newline at end of file
...@@ -54,7 +54,11 @@ class UserGrantedAssetsApi(ListAPIView): ...@@ -54,7 +54,11 @@ class UserGrantedAssetsApi(ListAPIView):
user = self.request.user user = self.request.user
for k, v in NodePermissionUtil.get_user_assets(user).items(): for k, v in NodePermissionUtil.get_user_assets(user).items():
k.system_users_granted = v if k.is_unixlike():
system_users_granted = [s for s in v if s.protocol == 'ssh']
else:
system_users_granted = [s for s in v if s.protocol == 'rdp']
k.system_users_granted = system_users_granted
queryset.append(k) queryset.append(k)
return queryset return queryset
...@@ -118,9 +122,16 @@ class UserGrantedNodesWithAssetsApi(ListAPIView): ...@@ -118,9 +122,16 @@ class UserGrantedNodesWithAssetsApi(ListAPIView):
user = get_object_or_404(User, id=user_id) user = get_object_or_404(User, id=user_id)
nodes = NodePermissionUtil.get_user_nodes_with_assets(user) nodes = NodePermissionUtil.get_user_nodes_with_assets(user)
assets = {}
for k, v in NodePermissionUtil.get_user_assets(user).items():
if k.is_unixlike():
system_users_granted = [s for s in v if s.protocol == 'ssh']
else:
system_users_granted = [s for s in v if s.protocol == 'rdp']
assets[k] = system_users_granted
for node, v in nodes.items(): for node, v in nodes.items():
for asset in v['assets']: for asset in v['assets']:
asset.system_users_granted = v['system_users'] asset.system_users_granted = assets[asset]
node.assets_granted = v['assets'] node.assets_granted = v['assets']
queryset.append(node) queryset.append(node)
return queryset return queryset
......
...@@ -12,7 +12,7 @@ class AssetPermissionCreateUpdateSerializer(serializers.ModelSerializer): ...@@ -12,7 +12,7 @@ class AssetPermissionCreateUpdateSerializer(serializers.ModelSerializer):
class Meta: class Meta:
model = NodePermission model = NodePermission
fields = [ fields = [
'node', 'user_group', 'system_user', 'id', 'node', 'user_group', 'system_user',
'is_active', 'date_expired' 'is_active', 'date_expired'
] ]
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
<div class="col-sm-12"> <div class="col-sm-12">
<div class="ibox float-e-margins"> <div class="ibox float-e-margins">
<div class="ibox-title"> <div class="ibox-title">
<h5>{% trans 'Create asset permission ' %}</h5> <h5>{{ action }}</h5>
<div class="ibox-tools"> <div class="ibox-tools">
<a class="collapse-link"> <a class="collapse-link">
<i class="fa fa-chevron-up"></i> <i class="fa fa-chevron-up"></i>
......
...@@ -215,16 +215,6 @@ $(document).ready(function(){ ...@@ -215,16 +215,6 @@ $(document).ready(function(){
initTable(); initTable();
initTree(); initTree();
}) })
.on('click', '.btn-create-asset', function () {
var url = "{% url 'assets:asset-create' %}";
var nodes = zTree.getSelectedNodes();
var current_node;
if (nodes && nodes.length ===1 ){
current_node = nodes[0];
url += "?node=" + current_node.id;
}
window.open(url);
})
.on('click', '.btn-del', function () { .on('click', '.btn-del', function () {
var $this = $(this); var $this = $(this);
var uid = $this.data('uid'); var uid = $this.data('uid');
...@@ -241,7 +231,7 @@ $(document).ready(function(){ ...@@ -241,7 +231,7 @@ $(document).ready(function(){
current_node = nodes[0]; current_node = nodes[0];
url += "?node_id=" + current_node.id; url += "?node_id=" + current_node.id;
} }
window.open(url); window.open(url, '_self');
}) })
</script> </script>
......
...@@ -56,7 +56,7 @@ class NodePermissionUtil: ...@@ -56,7 +56,7 @@ class NodePermissionUtil:
nodes_with_assets = dict() nodes_with_assets = dict()
for node, system_users in nodes.items(): for node, system_users in nodes.items():
nodes_with_assets[node] = { nodes_with_assets[node] = {
'assets': node.get_assets(), 'assets': node.get_active_assets(),
'system_users': system_users 'system_users': system_users
} }
return nodes_with_assets return nodes_with_assets
...@@ -87,7 +87,7 @@ class NodePermissionUtil: ...@@ -87,7 +87,7 @@ class NodePermissionUtil:
nodes_with_assets = dict() nodes_with_assets = dict()
for node, system_users in nodes.items(): for node, system_users in nodes.items():
nodes_with_assets[node] = { nodes_with_assets[node] = {
'assets': node.get_assets(), 'assets': node.get_active_assets(),
'system_users': system_users 'system_users': system_users
} }
return nodes_with_assets return nodes_with_assets
......
...@@ -427,3 +427,9 @@ div.dataTables_wrapper div.dataTables_filter { ...@@ -427,3 +427,9 @@ div.dataTables_wrapper div.dataTables_filter {
text-align: center; text-align: center;
padding: 5px 0; padding: 5px 0;
} }
.profile-dropdown li a {
font-size: 12px !important;
}
...@@ -3299,7 +3299,7 @@ body.tour-open .animated { ...@@ -3299,7 +3299,7 @@ body.tour-open .animated {
border-bottom: 1px solid #e7eaec; border-bottom: 1px solid #e7eaec;
} }
body { body {
font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif; font-family: "open sans", "Helvetica Neue", "微软雅黑", Helvetica, Arial, sans-serif;
background-color: #2f4050; background-color: #2f4050;
font-size: 13px; font-size: 13px;
color: #676a6c; color: #676a6c;
......
apps/static/img/logo-text.png

12.4 KB | W: | H:

apps/static/img/logo-text.png

17.7 KB | W: | H:

apps/static/img/logo-text.png
apps/static/img/logo-text.png
apps/static/img/logo-text.png
apps/static/img/logo-text.png
  • 2-up
  • Swipe
  • Onion skin
<strong>Copyright</strong> 北京堆栈科技有限公司 &copy; 2014-2018
\ No newline at end of file
...@@ -14,8 +14,13 @@ ...@@ -14,8 +14,13 @@
{# <span class="m-r-sm text-muted welcome-message">{% trans 'Welcome to use Jumpserver system' %}</span>#} {# <span class="m-r-sm text-muted welcome-message">{% trans 'Welcome to use Jumpserver system' %}</span>#}
{# </li>#} {# </li>#}
<li class="dropdown"> <li class="dropdown">
<a class="dropdown-toggle count-info" data-toggle="dropdown" href="#"> <a class="dropdown-toggle count-info" data-toggle="dropdown" href="https://market.aliyun.com/products/53690006/cmgj026011.html?spm=5176.730005.0.0.cY2io1">
<span class="m-r-sm text-muted welcome-message">{% trans 'Help' %}</span> <span class="m-r-sm text-muted welcome-message">{% trans 'Supports' %}</span>
</a>
</li>
<li class="dropdown">
<a class="count-info" href="http://jumpserver.readthedocs.io/">
<span class="m-r-sm text-muted welcome-message">{% trans 'Docs' %}</span>
</a> </a>
</li> </li>
<li class="dropdown"> <li class="dropdown">
...@@ -28,9 +33,8 @@ ...@@ -28,9 +33,8 @@
</span> </span>
</span> </span>
</a> </a>
<ul class="dropdown-menu animated fadeInRight m-t-xs"> <ul class="dropdown-menu animated fadeInRight m-t-xs profile-dropdown">
<li><a href="{% url 'users:user-profile' %}"><i class="fa fa-cogs"> </i><span> {% trans 'Profile' %}</span></a></li> <li><a href="{% url 'users:user-profile' %}"><i class="fa fa-cogs"> </i><span> {% trans 'Profile' %}</span></a></li>
<li class="divider"></li>
{% if request.user.is_superuser %} {% if request.user.is_superuser %}
{% if request.COOKIES.IN_ADMIN_PAGE == 'No' %} {% if request.COOKIES.IN_ADMIN_PAGE == 'No' %}
<li><a id="switch_admin"><i class="fa fa-exchange"></i><span> {% trans 'Admin page' %}</span></a></li> <li><a id="switch_admin"><i class="fa fa-exchange"></i><span> {% trans 'Admin page' %}</span></a></li>
...@@ -57,11 +61,11 @@ ...@@ -57,11 +61,11 @@
<li> <li>
<a href="">{% trans 'Dashboard' %}</a> <a href="">{% trans 'Dashboard' %}</a>
</li> </li>
<li>
{% if app %} {% if app %}
<li>
<a>{{ app }}</a> <a>{{ app }}</a>
{% endif %}
</li> </li>
{% endif %}
{% if action %} {% if action %}
<li class="active"> <li class="active">
<strong>{{ action }}</strong> <strong>{{ action }}</strong>
......
{% load i18n %} {% load i18n %}
<li id="index"> <li id="index">
<a href="{% url 'index' %}"> <a href="{% url 'index' %}">
<i class="fa fa-dashboard" style="font-size: 13px"></i> <span class="nav-label">{% trans 'Dashboard' %}</span><span class="label label-info pull-right"></span> <i class="fa fa-dashboard" style="width: 14px"></i> <span class="nav-label">{% trans 'Dashboard' %}</span><span
class="label label-info pull-right"></span>
</a> </a>
</li> </li>
<li id="users"> <li id="users">
<a href="#"> <a href="#">
<i class="fa fa-group" style="font-size: 13px"></i> <span class="nav-label">{% trans 'Users' %}</span><span class="fa arrow"></span> <i class="fa fa-group" style="width: 14px"></i> <span class="nav-label">{% trans 'Users' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level active"> <ul class="nav nav-second-level active">
<li id="user"><a href="{% url 'users:user-list' %}">{% trans 'User list' %}</a></li> <li id="user"><a href="{% url 'users:user-list' %}">{% trans 'User list' %}</a></li>
...@@ -16,7 +17,7 @@ ...@@ -16,7 +17,7 @@
</li> </li>
<li id="assets"> <li id="assets">
<a> <a>
<i class="fa fa-inbox"></i> <span class="nav-label">{% trans 'Assets' %}</span><span class="fa arrow"></span> <i class="fa fa-inbox" style="width: 14px"></i> <span class="nav-label">{% trans 'Assets' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li id="asset"><a href="{% url 'assets:asset-list' %}">{% trans 'Asset list' %}</a></li> <li id="asset"><a href="{% url 'assets:asset-list' %}">{% trans 'Asset list' %}</a></li>
...@@ -26,7 +27,7 @@ ...@@ -26,7 +27,7 @@
</ul> </ul>
</li> </li>
<li id="perms"> <li id="perms">
<a href="#"><i class="fa fa-edit"></i> <span class="nav-label">{% trans 'Perms' %}</span><span class="fa arrow"></span></a> <a href="#"><i class="fa fa-edit" style="width: 14px"></i> <span class="nav-label">{% trans 'Perms' %}</span><span class="fa arrow"></span></a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li id="asset-permission"> <li id="asset-permission">
<a href="{% url 'perms:asset-permission-list' %}">{% trans 'Asset permission' %}</a> <a href="{% url 'perms:asset-permission-list' %}">{% trans 'Asset permission' %}</a>
...@@ -35,18 +36,23 @@ ...@@ -35,18 +36,23 @@
</li> </li>
<li id="terminal"> <li id="terminal">
<a> <a>
<i class="fa fa-rocket"></i> <span class="nav-label">{% trans 'Sessions' %}</span><span class="fa arrow"></span> <i class="fa fa-rocket" style="width: 14px"></i> <span class="nav-label">{% trans 'Sessions' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li id="session-online"><a href="{% url 'terminal:session-online-list' %}">{% trans 'Session online' %}</a></li> <li id="session-online"><a href="{% url 'terminal:session-online-list' %}">{% trans 'Session online' %}</a></li>
<li id="session-offline"><a href="{% url 'terminal:session-offline-list' %}">{% trans 'Session offline' %}</a></li> <li id="session-offline"><a href="{% url 'terminal:session-offline-list' %}">{% trans 'Session offline' %}</a></li>
<li id="command"><a href="{% url 'terminal:command-list' %}">{% trans 'Commands' %}</a></li> <li id="command"><a href="{% url 'terminal:command-list' %}">{% trans 'Commands' %}</a></li>
<li>
<a href="{% url 'terminal:web-terminal' %}" target="_blank">
<span class="nav-label">{% trans 'Web terminal' %}</span>
</a>
</li>
<li id="terminal"><a href="{% url 'terminal:terminal-list' %}">{% trans 'Terminal' %}</a></li> <li id="terminal"><a href="{% url 'terminal:terminal-list' %}">{% trans 'Terminal' %}</a></li>
</ul> </ul>
</li> </li>
<li id="ops"> <li id="ops">
<a> <a>
<i class="fa fa-coffee"></i> <span class="nav-label">{% trans 'Job Center' %}</span><span class="fa arrow"></span> <i class="fa fa-coffee" style="width: 14px"></i> <span class="nav-label">{% trans 'Job Center' %}</span><span class="fa arrow"></span>
</a> </a>
<ul class="nav nav-second-level"> <ul class="nav nav-second-level">
<li id="task"><a href="{% url 'ops:task-list' %}">{% trans 'Task list' %}</a></li> <li id="task"><a href="{% url 'ops:task-list' %}">{% trans 'Task list' %}</a></li>
......
{% load i18n %} {% load i18n %}
<li id="assets"> <li id="assets">
<a href="{% url 'assets:user-asset-list' %}"> <a href="{% url 'assets:user-asset-list' %}">
<i class="fa fa-files-o"></i><span class="nav-label">{% trans 'My assets' %}</span><span class="label label-info pull-right"></span> <i class="fa fa-files-o" style="width: 14px"></i><span class="nav-label">{% trans 'My assets' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
<li id="users"> <li id="users">
<a href="{% url 'users:user-profile' %}"> <a href="{% url 'users:user-profile' %}">
<i class="fa fa-user" ></i> <span class="nav-label">{% trans 'Profile' %}</span><span class="label label-info pull-right"></span> <i class="fa fa-user" style="width: 14px"></i> <span class="nav-label">{% trans 'Profile' %}</span><span class="label label-info pull-right"></span>
</a> </a>
</li> </li>
<li > <li >
<a href="{% url 'terminal:web-terminal' %}" target="_blank"><i class="fa fa-window-maximize"></i> <a href="{% url 'terminal:web-terminal' %}" target="_blank"><i class="fa fa-window-maximize" style="width: 14px"></i>
<span class="nav-label">{% trans 'Web terminal' %}</span> <span class="nav-label">{% trans 'Web terminal' %}</span>
</a> </a>
</li> </li>
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<li class="nav-header"> <li class="nav-header">
<div class="dropdown profile-element"> <div class="dropdown profile-element">
<div href="http://www.jumpserver.org" target="_blank"> <div href="http://www.jumpserver.org" target="_blank">
<img alt="image" height="55" src="/static/img/logo-text.png" style="margin-left: 10px"/> <img alt="logo" height="55" width="185" src="/static/img/logo-text.png" style="margin-left: 20px"/>
</div> </div>
</div> </div>
<div class="clearfix"></div> <div class="clearfix"></div>
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
<hr/> <hr/>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
Copyright Jumpserver.org {% include '_copyright.html' %}
</div> </div>
<div class="col-md-6 text-right"> <div class="col-md-6 text-right">
<small>2014-2018</small> <small>2014-2018</small>
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="{% url 'users:user-list' %}">{{ users_count }}</a></h1> <h1 class="no-margins"><a href="{% url 'users:user-list' %}">{{ users_count }}</a></h1>
<small>All user</small> <small>All users</small>
</div> </div>
</div> </div>
</div> </div>
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="{% url 'assets:asset-list' %}">{{ assets_count }}</a></h1> <h1 class="no-margins"><a href="{% url 'assets:asset-list' %}">{{ assets_count }}</a></h1>
<small>All host</small> <small>All hosts</small>
</div> </div>
</div> </div>
</div> </div>
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
</div> </div>
<div class="ibox-content"> <div class="ibox-content">
<h1 class="no-margins"><a href="{% url 'terminal:session-online-list' %}"> <span id="online_users"></span>{{ online_user_count }}</a></h1> <h1 class="no-margins"><a href="{% url 'terminal:session-online-list' %}"> <span id="online_users"></span>{{ online_user_count }}</a></h1>
<small>Online user</small> <small>Online users</small>
</div> </div>
</div> </div>
</div> </div>
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
<div class="row"> <div class="row">
<div class="col-sm-2 border-bottom white-bg dashboard-header" style="margin-left:15px;height: 346px"> <div class="col-sm-2 border-bottom white-bg dashboard-header" style="margin-left:15px;height: 346px">
<h2>活跃用户TOP5</h2> <h2>活跃用户TOP5</h2>
<small>过去一周共有<span class="text-info">{{ user_visit_count_weekly }}</span>位用户登录<span class="text-success">{{ asset_visit_count_weekly }}</span>服务器.</small> <small>过去一周共有<span class="text-info">{{ user_visit_count_weekly }}</span>位用户登录<span class="text-success">{{ asset_visit_count_weekly }}</span>资产.</small>
<ul class="list-group clear-list m-t"> <ul class="list-group clear-list m-t">
{% for data in user_visit_count_top_five %} {% for data in user_visit_count_top_five %}
<li class="list-group-item fist-item"> <li class="list-group-item fist-item">
......
...@@ -25,18 +25,22 @@ def get_all_replay_storage(): ...@@ -25,18 +25,22 @@ def get_all_replay_storage():
class TerminalForm(forms.ModelForm): class TerminalForm(forms.ModelForm):
command_storage = forms.ChoiceField(choices=get_all_command_storage(), command_storage = forms.ChoiceField(
label=_("Command storage")) choices=get_all_command_storage(),
replay_storage = forms.ChoiceField(choices=get_all_replay_storage(), label=_("Command storage")
label=_("Replay storage")) )
replay_storage = forms.ChoiceField(
choices=get_all_replay_storage(),
label=_("Replay storage")
)
class Meta: class Meta:
model = Terminal model = Terminal
fields = ['name', 'remote_addr', 'ssh_port', 'http_port', 'comment', 'command_storage', 'replay_storage'] fields = [
'name', 'remote_addr', 'ssh_port', 'http_port', 'comment',
'command_storage', 'replay_storage',
]
help_texts = { help_texts = {
'ssh_port': _("Coco ssh listen port"), 'ssh_port': _("Coco ssh listen port"),
'http_port': _("Coco http/ws listen port"), 'http_port': _("Coco http/ws listen port"),
} }
widgets = {
'name': forms.TextInput(attrs={'readonly': 'readonly'})
}
...@@ -4,6 +4,7 @@ import uuid ...@@ -4,6 +4,7 @@ import uuid
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils import timezone
from django.conf import settings from django.conf import settings
from users.models import User from users.models import User
...@@ -127,6 +128,7 @@ class Session(models.Model): ...@@ -127,6 +128,7 @@ class Session(models.Model):
has_replay = models.BooleanField(default=False, verbose_name=_("Replay")) has_replay = models.BooleanField(default=False, verbose_name=_("Replay"))
has_command = models.BooleanField(default=False, verbose_name=_("Command")) has_command = models.BooleanField(default=False, verbose_name=_("Command"))
terminal = models.ForeignKey(Terminal, null=True, on_delete=models.CASCADE) terminal = models.ForeignKey(Terminal, null=True, on_delete=models.CASCADE)
date_last_active = models.DateTimeField(verbose_name=_("Date last active"), default=timezone.now)
date_start = models.DateTimeField(verbose_name=_("Date start")) date_start = models.DateTimeField(verbose_name=_("Date start"))
date_end = models.DateTimeField(verbose_name=_("Date end"), null=True) date_end = models.DateTimeField(verbose_name=_("Date end"), null=True)
......
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
import datetime
from celery import shared_task from celery import shared_task
from django.utils import timezone
from common.celery import register_as_period_task, after_app_ready_start, \
after_app_shutdown_clean
from .models import Status, Session
CACHE_REFRESH_INTERVAL = 10 CACHE_REFRESH_INTERVAL = 10
RUNNING = False RUNNING = False
# Todo: 定期清理上报history
@shared_task @shared_task
def clean_terminal_history(): @register_as_period_task(interval=3600)
pass @after_app_ready_start
@after_app_shutdown_clean
def delete_terminal_status_period():
yesterday = timezone.now() - datetime.timedelta(days=3)
Status.objects.filter(date_created__lt=yesterday).delete()
@shared_task
@register_as_period_task(interval=3600)
@after_app_ready_start
@after_app_shutdown_clean
def clean_orphan_session():
active_sessions = Session.objects.filter(is_finished=False)
for session in active_sessions:
if not session.terminal.is_active:
session.is_finished = True
session.save()
...@@ -75,6 +75,7 @@ ...@@ -75,6 +75,7 @@
<th class="text-center">{% trans 'Terminal' %}</th> <th class="text-center">{% trans 'Terminal' %}</th>
<th class="text-center">{% trans 'Command' %}</th> <th class="text-center">{% trans 'Command' %}</th>
<th class="text-center">{% trans 'Date start' %}</th> <th class="text-center">{% trans 'Date start' %}</th>
{# <th class="text-center">{% trans 'Date last active' %}</th>#}
<th class="text-center">{% trans 'Duration' %}</th> <th class="text-center">{% trans 'Duration' %}</th>
<th class="text-center">{% trans 'Action' %}</th> <th class="text-center">{% trans 'Action' %}</th>
{% endblock %} {% endblock %}
...@@ -94,6 +95,7 @@ ...@@ -94,6 +95,7 @@
<td class="text-center">{{ session.id | get_session_command_amount }}</td> <td class="text-center">{{ session.id | get_session_command_amount }}</td>
<td class="text-center">{{ session.date_start }}</td> <td class="text-center">{{ session.date_start }}</td>
{# <td class="text-center">{{ session.date_last_active }}</td>#}
<td class="text-center">{{ session.date_start|time_util_with_seconds:session.date_end }}</td> <td class="text-center">{{ session.date_start|time_util_with_seconds:session.date_end }}</td>
<td> <td>
{% if session.is_finished %} {% if session.is_finished %}
...@@ -107,6 +109,21 @@ ...@@ -107,6 +109,21 @@
{% endfor %} {% endfor %}
{% endblock %} {% endblock %}
{% block content_bottom_left %}
<div id="actions" >
<div class="input-group">
<select class="form-control m-b" style="width: auto" id="slct_bulk_update">
<option value="delete">{% trans 'Terminate selected' %}</option>
</select>
<div class="input-group-btn pull-left" style="padding-left: 5px;">
<button id='btn_bulk_update' style="height: 32px;" class="btn btn-sm btn-primary">
{% trans 'Submit' %}
</button>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script> <script src="{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"></script>
<script> <script>
......
...@@ -6,7 +6,7 @@ from django.conf import settings ...@@ -6,7 +6,7 @@ from django.conf import settings
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from common.mixins import DatetimeSearchMixin from common.mixins import DatetimeSearchMixin, AdminUserRequiredMixin
from ..models import Command from ..models import Command
from .. import utils from .. import utils
from ..backends import get_multi_command_store from ..backends import get_multi_command_store
...@@ -15,7 +15,7 @@ __all__ = ['CommandListView'] ...@@ -15,7 +15,7 @@ __all__ = ['CommandListView']
common_storage = get_multi_command_store() common_storage = get_multi_command_store()
class CommandListView(DatetimeSearchMixin, ListView): class CommandListView(DatetimeSearchMixin, AdminUserRequiredMixin, ListView):
model = Command model = Command
template_name = "terminal/command_list.html" template_name = "terminal/command_list.html"
context_object_name = 'command_list' context_object_name = 'command_list'
......
...@@ -97,7 +97,7 @@ class SessionOfflineListView(SessionListView): ...@@ -97,7 +97,7 @@ class SessionOfflineListView(SessionListView):
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
class SessionDetailView(SingleObjectMixin, ListView): class SessionDetailView(SingleObjectMixin, AdminUserRequiredMixin, ListView):
template_name = 'terminal/session_detail.html' template_name = 'terminal/session_detail.html'
model = Session model = Session
object = None object = None
......
...@@ -145,7 +145,8 @@ class UserAuthApi(APIView): ...@@ -145,7 +145,8 @@ class UserAuthApi(APIView):
if not login_ip: if not login_ip:
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '').split(',') x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '').split(',')
if x_forwarded_for:
if x_forwarded_for and x_forwarded_for[0]:
login_ip = x_forwarded_for[0] login_ip = x_forwarded_for[0]
else: else:
login_ip = request.META.get("REMOTE_ADDR") login_ip = request.META.get("REMOTE_ADDR")
......
...@@ -6,3 +6,6 @@ from django.apps import AppConfig ...@@ -6,3 +6,6 @@ from django.apps import AppConfig
class UsersConfig(AppConfig): class UsersConfig(AppConfig):
name = 'users' name = 'users'
def ready(self):
from . import signals_handler
super().ready()
...@@ -16,7 +16,8 @@ class AccessKey(models.Model): ...@@ -16,7 +16,8 @@ class AccessKey(models.Model):
default=uuid.uuid4, editable=False) default=uuid.uuid4, editable=False)
secret = models.UUIDField(verbose_name='AccessKeySecret', secret = models.UUIDField(verbose_name='AccessKeySecret',
default=uuid.uuid4, editable=False) default=uuid.uuid4, editable=False)
user = models.ForeignKey(User, verbose_name='User', on_delete=models.CASCADE, related_name='access_key') user = models.ForeignKey(User, verbose_name='User',
on_delete=models.CASCADE, related_name='access_key')
def get_id(self): def get_id(self):
return str(self.id) return str(self.id)
......
...@@ -22,6 +22,7 @@ class UserGroup(NoDeleteModelMixin): ...@@ -22,6 +22,7 @@ class UserGroup(NoDeleteModelMixin):
class Meta: class Meta:
ordering = ['name'] ordering = ['name']
verbose_name = _("User group")
@classmethod @classmethod
def initial(cls): def initial(cls):
......
...@@ -151,6 +151,10 @@ class User(AbstractUser): ...@@ -151,6 +151,10 @@ class User(AbstractUser):
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.name: if not self.name:
self.name = self.username self.name = self.username
if self.username == 'admin':
self.role = 'Admin'
self.is_active = True
super().save(*args, **kwargs) super().save(*args, **kwargs)
@property @property
...@@ -247,6 +251,7 @@ class User(AbstractUser): ...@@ -247,6 +251,7 @@ class User(AbstractUser):
class Meta: class Meta:
ordering = ['username'] ordering = ['username']
verbose_name = _("User")
#: Use this method initial user #: Use this method initial user
@classmethod @classmethod
......
# -*- coding: utf-8 -*- from django.dispatch import Signal
#
from django.dispatch import Signal, receiver
from django.db.models.signals import post_save
from common.utils import get_logger post_user_create = Signal(providing_args=('user',))
from .models import User
logger = get_logger(__file__)
@receiver(post_save, sender=User)
def on_user_created(sender, instance=None, created=False, **kwargs):
if created:
logger.debug("Receive user `{}` create signal".format(instance.name))
from .utils import send_user_created_mail
logger.info(" - Sending welcome mail ...".format(instance.name))
if instance.email:
send_user_created_mail(instance)
# -*- coding: utf-8 -*-
#
from django.dispatch import receiver
from django.db.models.signals import post_save
from common.utils import get_logger
from .models import User
logger = get_logger(__file__)
@receiver(post_save, sender=User)
def on_user_created(sender, instance=None, created=False, **kwargs):
if created:
logger.debug("Receive user `{}` create signal".format(instance.name))
from .utils import send_user_created_mail
logger.info(" - Sending welcome mail ...".format(instance.name))
if instance.email:
send_user_created_mail(instance)
\ No newline at end of file
...@@ -51,11 +51,8 @@ ...@@ -51,11 +51,8 @@
</div> </div>
<hr/> <hr/>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-12">
Copyright Jumpserver.org {% include '_copyright.html' %}
</div>
<div class="col-md-6 text-right">
<small>© 2014-2018</small>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -22,24 +22,27 @@ ...@@ -22,24 +22,27 @@
<div class="loginColumns animated fadeInDown"> <div class="loginColumns animated fadeInDown">
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
<h2 class="font-bold">欢迎使用Jumpserver开源跳板</h2> <h2 class="font-bold">欢迎使用Jumpserver开源堡垒</h2>
<p> <p>
Jumpserver是一款使用Python, Django开发的开源跳板机系统, 助力互联网企业高效 用户、资产、权限、审计 管理 全球首款完全开源的堡垒机,使用GNU GPL v2.0开源协议,是符合 4A 的专业运维审计系统。
</p> </p>
<p> <p>
我们自五湖四海,我们对开源精神无比敬仰和崇拜,我们对完美、整洁、优雅 无止境的追求 使用Python / Django 进行开发,遵循 Web 2.0 规范,配备了业界领先的 Web Terminal 解决方案,交互界面美观、用户体验好。
</p> </p>
<p> <p>
专注自动化运维,努力打造 易用、稳定、安全、自动化 的跳板机, 这是我们的不懈的追求和动力 采纳分布式架构,支持多机房跨区域部署,中心节点提供 API,各机房部署登录节点,可横向扩展、无并发访问限制。
</p> </p>
<p> <p>
<small>永远年轻,永远热泪盈眶 stay foolish stay hungry</small> 改变世界,从一点点开始。
</p> </p>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<div class="ibox-content"> <div class="ibox-content">
<div><img src="{% static 'img/logo.png' %}" width="82" height="82"> <span class="font-bold text-center" style="font-size: 32px; font-family: inherit">{% trans 'Login' %}</span></div> <div>
<img src="{% static 'img/logo.png' %}" width="60" height="60">
<span class="font-bold text-center" style="font-size: 24px; font-family: inherit; margin-left: 20px">{% trans 'Login' %}</span>
</div>
<form class="m-t" role="form" method="post" action=""> <form class="m-t" role="form" method="post" action="">
{% csrf_token %} {% csrf_token %}
{% if form.errors %} {% if form.errors %}
...@@ -60,12 +63,16 @@ ...@@ -60,12 +63,16 @@
</div> </div>
<button type="submit" class="btn btn-primary block full-width m-b">{% trans 'Login' %}</button> <button type="submit" class="btn btn-primary block full-width m-b">{% trans 'Login' %}</button>
{% if demo_mode %}
<p class="text-muted font-bold" style="color: red">
Demo账号: admin 密码: admin
</p>
{% endif %}
<a href="{% url 'users:forgot-password' %}"> <a href="{% url 'users:forgot-password' %}">
<small>{% trans 'Forgot password' %}?</small> <small>{% trans 'Forgot password' %}?</small>
</a> </a>
<p class="text-muted text-center">
</p>
</form> </form>
<p class="m-t"> <p class="m-t">
</p> </p>
...@@ -74,11 +81,8 @@ ...@@ -74,11 +81,8 @@
</div> </div>
<hr/> <hr/>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-12">
Copyright 北京堆栈科技有限公司 {% include '_copyright.html' %}
</div>
<div class="col-md-6 text-right">
<small>© 2014-2018</small>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -70,11 +70,8 @@ ...@@ -70,11 +70,8 @@
</div> </div>
<hr/> <hr/>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-12">
Copyright Jumpserver.org {% include '_copyright.html' %}
</div>
<div class="col-md-6 text-right">
<small>© 2014-2018</small>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -92,8 +92,8 @@ class UserGroupGrantedAssetView(AdminUserRequiredMixin, DetailView): ...@@ -92,8 +92,8 @@ class UserGroupGrantedAssetView(AdminUserRequiredMixin, DetailView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': 'User', 'app': _('Users'),
'action': 'User group granted asset', 'action': _('User group granted asset'),
} }
kwargs.update(context) kwargs.update(context)
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals from __future__ import unicode_literals
import os
from django import forms from django import forms
from django.shortcuts import render from django.shortcuts import render
from django.contrib.auth import login as auth_login, logout as auth_logout from django.contrib.auth import login as auth_login, logout as auth_logout
...@@ -56,6 +57,7 @@ class UserLoginView(FormView): ...@@ -56,6 +57,7 @@ class UserLoginView(FormView):
return HttpResponse(_("Please enable cookies and try again.")) return HttpResponse(_("Please enable cookies and try again."))
auth_login(self.request, form.get_user()) auth_login(self.request, form.get_user())
x_forwarded_for = self.request.META.get('HTTP_X_FORWARDED_FOR', '').split(',') x_forwarded_for = self.request.META.get('HTTP_X_FORWARDED_FOR', '').split(',')
if x_forwarded_for and x_forwarded_for[0]: if x_forwarded_for and x_forwarded_for[0]:
login_ip = x_forwarded_for[0] login_ip = x_forwarded_for[0]
else: else:
...@@ -75,6 +77,13 @@ class UserLoginView(FormView): ...@@ -75,6 +77,13 @@ class UserLoginView(FormView):
self.redirect_field_name, self.redirect_field_name,
self.request.GET.get(self.redirect_field_name, reverse('index'))) self.request.GET.get(self.redirect_field_name, reverse('index')))
def get_context_data(self, **kwargs):
context = {
'demo_mode': os.environ.get("DEMO_MODE"),
}
kwargs.update(context)
return super().get_context_data(**kwargs)
@method_decorator(never_cache, name='dispatch') @method_decorator(never_cache, name='dispatch')
class UserLogoutView(TemplateView): class UserLogoutView(TemplateView):
...@@ -237,7 +246,7 @@ class LoginLogListView(DatetimeSearchMixin, ListView): ...@@ -237,7 +246,7 @@ class LoginLogListView(DatetimeSearchMixin, ListView):
if self.user: if self.user:
queryset = queryset.filter(username=self.user) queryset = queryset.filter(username=self.user)
if self.keyword: if self.keyword:
queryset = self.queryset.filter( queryset = queryset.filter(
Q(ip__contains=self.keyword) | Q(ip__contains=self.keyword) |
Q(city__contains=self.keyword) | Q(city__contains=self.keyword) |
Q(username__contains=self.keyword) Q(username__contains=self.keyword)
......
...@@ -6,6 +6,7 @@ import json ...@@ -6,6 +6,7 @@ import json
import uuid import uuid
import csv import csv
import codecs import codecs
import chardet
from io import StringIO from io import StringIO
from django.contrib import messages from django.contrib import messages
...@@ -20,6 +21,7 @@ from django.utils.translation import ugettext as _ ...@@ -20,6 +21,7 @@ from django.utils.translation import ugettext as _
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views import View from django.views import View
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django.db import transaction
from django.views.generic.edit import ( from django.views.generic.edit import (
CreateView, UpdateView, FormMixin, FormView CreateView, UpdateView, FormMixin, FormView
) )
...@@ -33,7 +35,7 @@ from common.utils import get_logger, get_object_or_none, is_uuid ...@@ -33,7 +35,7 @@ from common.utils import get_logger, get_object_or_none, is_uuid
from .. import forms from .. import forms
from ..models import User, UserGroup from ..models import User, UserGroup
from ..utils import AdminUserRequiredMixin from ..utils import AdminUserRequiredMixin
from ..signals import on_user_created from ..signals import post_user_create
__all__ = [ __all__ = [
...@@ -212,8 +214,10 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView): ...@@ -212,8 +214,10 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
# todo: need be patch, method to long # todo: need be patch, method to long
def form_valid(self, form): def form_valid(self, form):
file = form.cleaned_data['file'] f = form.cleaned_data['file']
data = file.read().decode('utf-8').strip(codecs.BOM_UTF8.decode('utf-8')) det_result = chardet.detect(f.read())
f.seek(0) # reset file seek index
data = f.read().decode(det_result['encoding']).strip(codecs.BOM_UTF8.decode())
csv_file = StringIO(data) csv_file = StringIO(data)
reader = csv.reader(csv_file) reader = csv.reader(csv_file)
csv_data = [row for row in reader] csv_data = [row for row in reader]
...@@ -252,15 +256,15 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView): ...@@ -252,15 +256,15 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
else: else:
continue continue
user_dict[k] = v user_dict[k] = v
user = get_object_or_none(User, id=id_) if id_ and is_uuid(id_) else None
user = get_object_or_none(User, id=id_) if is_uuid(id_) else None
if not user: if not user:
try: try:
with transaction.atomic():
groups = user_dict.pop('groups') groups = user_dict.pop('groups')
user = User.objects.create(**user_dict) user = User.objects.create(**user_dict)
user.groups.set(groups) user.groups.set(groups)
created.append(user_dict['username']) created.append(user_dict['username'])
on_user_created.send(self.__class__, user=user) post_user_create.send(self.__class__, user=user)
except Exception as e: except Exception as e:
failed.append('%s: %s' % (user_dict['username'], str(e))) failed.append('%s: %s' % (user_dict['username'], str(e)))
else: else:
...@@ -309,7 +313,6 @@ class UserProfileView(LoginRequiredMixin, TemplateView): ...@@ -309,7 +313,6 @@ class UserProfileView(LoginRequiredMixin, TemplateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Users'),
'action': _('Profile'), 'action': _('Profile'),
} }
kwargs.update(context) kwargs.update(context)
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
contain the root `toctree` directive. contain the root `toctree` directive.
Jumpserver 文档 Jumpserver 文档
==================== ======================================
目录: 目录:
......
简介
============
Jumpserver是混合云下更好用的堡垒机, 分布式架构设计无限扩展,轻松对接混合云资产,支持使用云存储(AWS S3, ES等)存储录像、命令
Jumpserver颠覆传统堡垒机, 无主机和并发数量限制,支持水平扩容,FIT2CLOUD提供完备的商业服务支持,用户无后顾之忧
Jumpserver拥有极致的用户体验, 极致UI体验,容器化的部署方式,部署过程方便快捷,可持续升级
组件说明
++++++++++++++++++++++++
Jumpserver
```````````
现指Jumpserver管理后台,是核心组件(Core), 使用 Django Class Based View 风格开发,支持Restful API。
`Github <https://github.com/jumpserver/jumpserver.git>`_
Coco
````````
实现了SSH Server 和 Web Terminal Server的组件,提供ssh和websocket接口, 使用 Paramiko 和 Flask 开发。
`Github <https://github.com/jumpserver/coco.git>`__
Luna
````````
现在是Web Terminal前端,计划前端页面都由该项目提供,Jumpserver只提供API,不再负责后台渲染html等。
`Github <https://github.com/jumpserver/luna.git>`__
Guacamole
```````````
Apache 跳板机项目,Jumpserver使用其组件实现RDP功能,Jumpserver并没有修改其代码而是添加了额外的插件,支持Jumpserver调用
Jumpserver-python-sdk
```````````````````````
Jumpserver API Python SDK,Coco目前使用该SDK与Jumpserver API交互
`Github <https://github.com/jumpserver/jumpserver-python-sdk.git>`__
组件架构图
++++++++++++++++++++++++
.. image:: _static/img/structure.png
:alt: 组件架构图
用户使用文档 用户使用文档
=============== =============
这部分给您介绍Jumpserver的用户使用方法。 这部分给您介绍Jumpserver的用户管理模块的使用方法。
.. toctree:: .. toctree::
:maxdepth: 1 :maxdepth: 1
......
...@@ -56,8 +56,8 @@ uritemplate==3.0.0 ...@@ -56,8 +56,8 @@ uritemplate==3.0.0
urllib3==1.22 urllib3==1.22
vine==1.1.4 vine==1.1.4
gunicorn==19.7.1 gunicorn==19.7.1
https://github.com/celery/django-celery-beat/zipball/master#egg=django-celery-beat #https://github.com/celery/django-celery-beat/zipball/master#egg=django-celery-beat
#django_celery_beat==1.1.0 django_celery_beat==1.1.1
ephem==3.7.6.0 ephem==3.7.6.0
python-gssapi==0.6.4 python-gssapi==0.6.4
jms-es-sdk jms-es-sdk
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