Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
J
jumpserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ops
jumpserver
Commits
8e09151a
Commit
8e09151a
authored
Mar 06, 2018
by
fit2cloud-fengyi
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'docs' of
https://github.com/jumpserver/jumpserver
into docs
parents
18841d6c
3fe5dade
Hide whitespace changes
Inline
Side-by-side
Showing
60 changed files
with
690 additions
and
393 deletions
+690
-393
node.py
apps/assets/api/node.py
+20
-1
asset.py
apps/assets/forms/asset.py
+2
-2
asset.py
apps/assets/models/asset.py
+17
-1
node.py
apps/assets/models/node.py
+10
-0
user.py
apps/assets/models/user.py
+5
-8
node.py
apps/assets/serializers/node.py
+5
-2
_system_user.html
apps/assets/templates/assets/_system_user.html
+23
-1
admin_user_create_update.html
apps/assets/templates/assets/admin_user_create_update.html
+1
-1
asset_create.html
apps/assets/templates/assets/asset_create.html
+1
-0
asset_list.html
apps/assets/templates/assets/asset_list.html
+62
-3
asset_update.html
apps/assets/templates/assets/asset_update.html
+1
-0
api_urls.py
apps/assets/urls/api_urls.py
+1
-0
asset.py
apps/assets/views/asset.py
+2
-2
forms.py
apps/common/forms.py
+3
-3
mixins.py
apps/common/mixins.py
+2
-3
common_tags.py
apps/common/templatetags/common_tags.py
+13
-10
django.mo
apps/i18n/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/i18n/zh/LC_MESSAGES/django.po
+249
-231
settings.py
apps/jumpserver/settings.py
+1
-1
urls.py
apps/jumpserver/urls.py
+2
-2
views.py
apps/jumpserver/views.py
+14
-2
api.py
apps/perms/api.py
+13
-2
serializers.py
apps/perms/serializers.py
+1
-1
asset_permission_create_update.html
...perms/templates/perms/asset_permission_create_update.html
+1
-1
asset_permission_list.html
apps/perms/templates/perms/asset_permission_list.html
+1
-11
utils.py
apps/perms/utils.py
+2
-2
jumpserver.css
apps/static/css/jumpserver.css
+6
-0
style.css
apps/static/css/style.css
+1
-1
logo-text.png
apps/static/img/logo-text.png
+0
-0
_copyright.html
apps/templates/_copyright.html
+2
-0
_header_bar.html
apps/templates/_header_bar.html
+11
-7
_nav.html
apps/templates/_nav.html
+12
-6
_nav_user.html
apps/templates/_nav_user.html
+4
-3
_user_profile.html
apps/templates/_user_profile.html
+1
-1
flash_message_standalone.html
apps/templates/flash_message_standalone.html
+1
-1
index.html
apps/templates/index.html
+4
-4
forms.py
apps/terminal/forms.py
+12
-8
models.py
apps/terminal/models.py
+2
-0
tasks.py
apps/terminal/tasks.py
+23
-7
session_list.html
apps/terminal/templates/terminal/session_list.html
+17
-0
command.py
apps/terminal/views/command.py
+2
-2
session.py
apps/terminal/views/session.py
+1
-1
api.py
apps/users/api.py
+2
-1
apps.py
apps/users/apps.py
+3
-0
authentication.py
apps/users/models/authentication.py
+2
-1
group.py
apps/users/models/group.py
+1
-0
user.py
apps/users/models/user.py
+5
-0
signals.py
apps/users/signals.py
+2
-18
signals_handler.py
apps/users/signals_handler.py
+21
-0
forgot_password.html
apps/users/templates/users/forgot_password.html
+2
-5
login.html
apps/users/templates/users/login.html
+17
-13
reset_password.html
apps/users/templates/users/reset_password.html
+2
-5
group.py
apps/users/views/group.py
+2
-2
login.py
apps/users/views/login.py
+10
-1
user.py
apps/users/views/user.py
+14
-11
structure.png
docs/_static/img/structure.png
+0
-0
index.rst
docs/index.rst
+1
-1
intro.rst
docs/intro.rst
+51
-0
user_guide.rst
docs/user_guide.rst
+2
-2
requirements.txt
requirements/requirements.txt
+2
-2
No files found.
apps/assets/api/node.py
View file @
8e09151a
...
...
@@ -19,7 +19,7 @@ from rest_framework.response import Response
from
rest_framework_bulk
import
BulkModelViewSet
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
..models
import
Node
from
..
import
serializers
...
...
@@ -29,6 +29,7 @@ logger = get_logger(__file__)
__all__
=
[
'NodeViewSet'
,
'NodeChildrenApi'
,
'NodeAddAssetsApi'
,
'NodeRemoveAssetsApi'
,
'NodeAddChildrenApi'
,
]
...
...
@@ -75,6 +76,24 @@ class NodeChildrenApi(mixins.ListModelMixin, generics.CreateAPIView):
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
):
serializer_class
=
serializers
.
NodeAssetsSerializer
queryset
=
Node
.
objects
.
all
()
...
...
apps/assets/forms/asset.py
View file @
8e09151a
...
...
@@ -15,7 +15,7 @@ class AssetCreateForm(forms.ModelForm):
model
=
Asset
fields
=
[
'hostname'
,
'ip'
,
'public_ip'
,
'port'
,
'comment'
,
'nodes'
,
'is_active'
,
'admin_user'
,
'labels'
,
'nodes'
,
'is_active'
,
'admin_user'
,
'labels'
,
'platform'
,
]
widgets
=
{
...
...
@@ -44,7 +44,7 @@ class AssetUpdateForm(forms.ModelForm):
class
Meta
:
model
=
Asset
fields
=
[
'hostname'
,
'ip'
,
'port'
,
'nodes'
,
'is_active'
,
'hostname'
,
'ip'
,
'port'
,
'nodes'
,
'is_active'
,
'platform'
,
'public_ip'
,
'number'
,
'comment'
,
'admin_user'
,
'labels'
,
]
widgets
=
{
...
...
apps/assets/models/asset.py
View file @
8e09151a
...
...
@@ -38,6 +38,14 @@ def default_node():
class
Asset
(
models
.
Model
):
# Important
PLATFORM_CHOICES
=
(
(
'Linux'
,
'Linux'
),
(
'Unix'
,
'Unix'
),
(
'MacOS'
,
'MacOS'
),
(
'BSD'
,
'BSD'
),
(
'Windows'
,
'Windows'
),
(
'Other'
,
'Other'
),
)
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
ip
=
models
.
GenericIPAddressField
(
max_length
=
32
,
verbose_name
=
_
(
'IP'
),
db_index
=
True
)
hostname
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
'Hostname'
))
...
...
@@ -64,7 +72,7 @@ class Asset(models.Model):
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'
))
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_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'
))
...
...
@@ -87,6 +95,12 @@ class Asset(models.Model):
return
True
,
''
return
False
,
warning
def
is_unixlike
(
self
):
if
self
.
platform
not
in
(
"Windows"
,
"Other"
):
return
True
else
:
return
False
@property
def
hardware_info
(
self
):
if
self
.
cpu_count
:
...
...
@@ -99,6 +113,8 @@ class Asset(models.Model):
@property
def
is_connective
(
self
):
if
not
self
.
is_unixlike
():
return
True
val
=
cache
.
get
(
ASSET_ADMIN_CONN_CACHE_KEY
.
format
(
self
.
hostname
))
if
val
==
1
:
return
True
...
...
apps/assets/models/node.py
View file @
8e09151a
...
...
@@ -61,6 +61,9 @@ class Node(models.Model):
assets
=
Asset
.
objects
.
filter
(
nodes__id
=
self
.
id
)
return
assets
def
get_active_assets
(
self
):
return
self
.
get_assets
()
.
filter
(
is_active
=
True
)
def
get_all_assets
(
self
):
from
.asset
import
Asset
if
self
.
is_root
():
...
...
@@ -70,6 +73,9 @@ class Node(models.Model):
assets
=
Asset
.
objects
.
filter
(
nodes__in
=
nodes
)
return
assets
def
get_all_active_assets
(
self
):
return
self
.
get_all_assets
()
.
filter
(
is_active
=
True
)
def
is_root
(
self
):
return
self
.
key
==
'0'
...
...
@@ -88,6 +94,10 @@ class Node(models.Model):
else
:
return
parent
@parent.setter
def
parent
(
self
,
parent
):
self
.
key
=
parent
.
get_next_child_key
()
@property
def
ancestor
(
self
):
if
self
.
parent
==
self
.
__class__
.
root
():
...
...
apps/assets/models/user.py
View file @
8e09151a
...
...
@@ -26,14 +26,14 @@ signer = get_signer()
class
AssetUser
(
models
.
Model
):
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
'Name'
))
username
=
models
.
CharField
(
max_length
=
1
6
,
verbose_name
=
_
(
'Username'
))
username
=
models
.
CharField
(
max_length
=
1
28
,
verbose_name
=
_
(
'Username'
))
_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
,
])
_public_key
=
models
.
TextField
(
max_length
=
4096
,
blank
=
True
,
verbose_name
=
_
(
'SSH public key'
))
comment
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
date_created
=
models
.
DateTimeField
(
auto_now_add
=
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
def
password
(
self
):
...
...
@@ -175,15 +175,12 @@ class AdminUser(AssetUser):
return
info
def
get_related_assets
(
self
):
assets
=
[]
for
cluster
in
self
.
cluster_set
.
all
():
assets
.
extend
(
cluster
.
assets
.
all
())
assets
.
extend
(
self
.
asset_set
.
all
())
return
list
(
set
(
assets
))
assets
=
self
.
asset_set
.
all
()
return
assets
@property
def
assets_amount
(
self
):
return
len
(
self
.
get_related_assets
()
)
return
self
.
get_related_assets
()
.
count
(
)
class
Meta
:
ordering
=
[
'name'
]
...
...
apps/assets/serializers/node.py
View file @
8e09151a
...
...
@@ -65,4 +65,8 @@ class NodeAssetsSerializer(serializers.ModelSerializer):
class
Meta
:
model
=
Node
fields
=
[
'assets'
]
\ No newline at end of file
fields
=
[
'assets'
]
class
NodeAddChildrenSerializer
(
serializers
.
Serializer
):
nodes
=
serializers
.
ListField
()
apps/assets/templates/assets/_system_user.html
View file @
8e09151a
...
...
@@ -13,7 +13,7 @@
<div
class=
"col-sm-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
{
% trans 'Create system user' %
}
</h5>
<h5>
{
{ action }
}
</h5>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
@@ -81,6 +81,14 @@
{% block custom_foot_js %}
<script>
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
()
{
if
(
$
(
auto_generate_key
).
prop
(
'checked'
))
{
$
(
'.auth-fields'
).
addClass
(
'hidden'
);
...
...
@@ -88,9 +96,23 @@
$
(
'.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
()
{
$
(
'.select2'
).
select2
();
authFieldsDisplay
();
protocolChange
();
$
(
auto_generate_key
).
change
(
function
()
{
authFieldsDisplay
();
});
...
...
apps/assets/templates/assets/admin_user_create_update.html
View file @
8e09151a
...
...
@@ -13,7 +13,7 @@
<div
class=
"col-sm-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
{
% trans 'Create admin user' %
}
</h5>
<h5>
{
{ action }
}
</h5>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
apps/assets/templates/assets/asset_create.html
View file @
8e09151a
...
...
@@ -17,6 +17,7 @@
{% bootstrap_field form.hostname layout="horizontal" %}
{% bootstrap_field form.ip layout="horizontal" %}
{% bootstrap_field form.port layout="horizontal" %}
{% bootstrap_field form.platform layout="horizontal" %}
{% bootstrap_field form.public_ip layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
...
...
apps/assets/templates/assets/asset_list.html
View file @
8e09151a
...
...
@@ -2,6 +2,12 @@
{% load static %}
{% load i18n %}
{% block help_message %}
<div
class=
"alert alert-info help-message"
>
左侧是资产树,右击可以新建、删除、更改树节点,授权资产也是以节点方式组织的,右侧是属于该节点下的资产
</div>
{% endblock %}
{% block custom_head_css_js %}
<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>
...
...
@@ -224,6 +230,9 @@ function editTreeNode() {
if
(
!
current_node
){
return
}
if
(
current_node
.
value
)
{
current_node
.
name
=
current_node
.
value
;
}
zTree
.
editName
(
current_node
);
}
...
...
@@ -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
()
{
var
setting
=
{
view
:
{
...
...
@@ -319,11 +364,24 @@ function initTree() {
enable
:
true
}
},
edit
:
{
enable
:
true
,
showRemoveBtn
:
false
,
showRenameBtn
:
false
,
drag
:
{
isCopy
:
true
,
isMove
:
true
}
},
callback
:
{
onRightClick
:
OnRightClick
,
beforeClick
:
beforeClick
,
onRename
:
onRename
,
onSelected
:
onSelected
onSelected
:
onSelected
,
beforeDrag
:
beforeDrag
,
onDrag
:
onDrag
,
beforeDrop
:
beforeDrop
,
onDrop
:
onDrop
}
};
...
...
@@ -334,7 +392,8 @@ function initTree() {
{
#
if
(
value
[
"key"
]
===
"0"
)
{
#
}
value
[
"open"
]
=
true
;
{
#
}
#
}
value
[
"name"
]
=
value
[
"value"
]
+
' ('
+
value
[
'assets_amount'
]
+
')'
value
[
"name"
]
=
value
[
"value"
]
+
' ('
+
value
[
'assets_amount'
]
+
')'
;
value
[
'value'
]
=
value
[
'value'
];
});
zNodes
=
data
;
$
.
fn
.
zTree
.
init
(
$
(
"#assetTree"
),
setting
,
zNodes
);
...
...
@@ -415,7 +474,7 @@ $(document).ready(function(){
current_node
=
nodes
[
0
];
url
+=
"?node_id="
+
current_node
.
id
;
}
window
.
open
(
url
);
window
.
open
(
url
,
'_self'
);
})
.
on
(
'click'
,
'.btn_asset_delete'
,
function
()
{
var
$this
=
$
(
this
);
...
...
apps/assets/templates/assets/asset_update.html
View file @
8e09151a
...
...
@@ -22,6 +22,7 @@
{% bootstrap_field form.hostname layout="horizontal" %}
{% bootstrap_field form.ip layout="horizontal" %}
{% bootstrap_field form.port layout="horizontal" %}
{% bootstrap_field form.platform layout="horizontal" %}
{% bootstrap_field form.public_ip layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
...
...
apps/assets/urls/api_urls.py
View file @
8e09151a
...
...
@@ -44,6 +44,7 @@ urlpatterns = [
url
(
r'^v1/system-user/(?P<pk>[0-9a-zA-Z\-]{36})/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/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/remove/$'
,
api
.
NodeRemoveAssetsApi
.
as_view
(),
name
=
'node-remove-assets'
),
]
...
...
apps/assets/views/asset.py
View file @
8e09151a
...
...
@@ -58,8 +58,7 @@ class UserAssetListView(LoginRequiredMixin, TemplateView):
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Asset list'
),
'action'
:
_
(
'My assets'
),
'system_users'
:
SystemUser
.
objects
.
all
(),
}
kwargs
.
update
(
context
)
...
...
@@ -248,6 +247,7 @@ class BulkImportAssetView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
f
=
form
.
cleaned_data
[
'file'
]
det_result
=
chardet
.
detect
(
f
.
read
())
f
.
seek
(
0
)
# reset file seek index
file_data
=
f
.
read
()
.
decode
(
det_result
[
'encoding'
])
.
strip
(
codecs
.
BOM_UTF8
.
decode
())
csv_file
=
StringIO
(
file_data
)
reader
=
csv
.
reader
(
csv_file
)
...
...
apps/common/forms.py
View file @
8e09151a
...
...
@@ -68,10 +68,10 @@ class BaseForm(forms.Form):
class
BasicSettingForm
(
BaseForm
):
SITE_URL
=
forms
.
URLField
(
label
=
_
(
"Current SITE URL"
),
help_text
=
"http://jumpserver.abc.com:8080"
help_text
=
"
eg:
http://jumpserver.abc.com:8080"
)
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"
)
)
EMAIL_SUBJECT_PREFIX
=
forms
.
CharField
(
...
...
@@ -135,7 +135,7 @@ class LDAPSettingForm(BaseForm):
AUTH_LDAP_START_TLS
=
forms
.
BooleanField
(
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
):
...
...
apps/common/mixins.py
View file @
8e09151a
...
...
@@ -99,9 +99,8 @@ class DatetimeSearchMixin:
if
date_from_s
:
date_from
=
timezone
.
datetime
.
strptime
(
date_from_s
,
self
.
date_format
)
self
.
date_from
=
date_from
.
replace
(
tzinfo
=
timezone
.
get_current_timezone
()
)
tz
=
timezone
.
get_current_timezone
()
self
.
date_from
=
tz
.
localize
(
date_from
)
else
:
self
.
date_from
=
timezone
.
now
()
-
timezone
.
timedelta
(
7
)
...
...
apps/common/templatetags/common_tags.py
View file @
8e09151a
...
...
@@ -73,17 +73,20 @@ def to_html(s):
@register.filter
def
time_util_with_seconds
(
date_from
,
date_to
):
if
date_from
and
date_to
:
delta
=
date_to
-
date_from
seconds
=
delta
.
seconds
if
seconds
<
60
:
return
'{} s'
.
format
(
seconds
)
elif
seconds
<
60
*
60
:
return
'{} m'
.
format
(
seconds
//
60
)
else
:
return
'{} h'
.
format
(
seconds
//
3600
)
else
:
if
not
date_from
:
return
''
if
not
date_to
:
return
''
date_to
=
timezone
.
now
()
delta
=
date_to
-
date_from
seconds
=
delta
.
seconds
if
seconds
<
60
:
return
'{} s'
.
format
(
seconds
)
elif
seconds
<
60
*
60
:
return
'{} m'
.
format
(
seconds
//
60
)
else
:
return
'{} h'
.
format
(
seconds
//
3600
)
@register.filter
...
...
apps/i18n/zh/LC_MESSAGES/django.mo
View file @
8e09151a
No preview for this file type
apps/i18n/zh/LC_MESSAGES/django.po
View file @
8e09151a
...
...
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-0
2-26 16:54
+0800\n"
"POT-Creation-Date: 2018-0
3-06 17:57
+0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: ibuler <ibuler@qq.com>\n"
"Language-Team: Jumpserver team<ibuler@qq.com>\n"
...
...
@@ -17,12 +17,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: assets/api/node.py:5
4
#: assets/api/node.py:5
5
msgid "New node {}"
msgstr "新节点 {}"
#: 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:189
#: assets/templates/assets/system_user_detail.html:164
...
...
@@ -30,16 +30,16 @@ msgid "Nodes"
msgstr "节点管理"
#: 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/models/cluster.py:19 assets/models/user.py:1
90
#: assets/templates/assets/asset_detail.html:73 templates/_nav.html:2
3
#: assets/forms/asset.py:94 assets/models/asset.py:
57
#: assets/models/cluster.py:19 assets/models/user.py:1
87
#: assets/templates/assets/asset_detail.html:73 templates/_nav.html:2
4
msgid "Admin user"
msgstr "管理用户"
#: assets/forms/asset.py:29 assets/forms/asset.py:58 assets/models/asset.py:
73
#: assets/templates/assets/asset_create.html:3
1
#: assets/forms/asset.py:29 assets/forms/asset.py:58 assets/models/asset.py:
81
#: assets/templates/assets/asset_create.html:3
2
#: assets/templates/assets/asset_detail.html:218
#: assets/templates/assets/asset_update.html:3
6 templates/_nav.html:25
#: assets/templates/assets/asset_update.html:3
7 templates/_nav.html:26
msgid "Labels"
msgstr "标签管理"
...
...
@@ -54,7 +54,7 @@ msgstr "管理用户是资产上已经存在的特权用户,如 root或者其
msgid "Select assets"
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/asset_detail.html:69
#: assets/templates/assets/system_user_asset.html:51
...
...
@@ -62,7 +62,7 @@ msgstr "选择资产"
msgid "Port"
msgstr "端口"
#: assets/forms/asset.py:106 assets/templates/assets/asset_create.html:3
5
#: assets/forms/asset.py:106 assets/templates/assets/asset_create.html:3
6
msgid "Select labels"
msgstr "选择标签"
...
...
@@ -70,11 +70,11 @@ msgstr "选择标签"
msgid "Select nodes"
msgstr "选择节点"
#: assets/forms/label.py:13 assets/models/asset.py:1
37
#: assets/forms/label.py:13 assets/models/asset.py:1
53
#: assets/templates/assets/admin_user_list.html:24
#: assets/templates/assets/label_list.html:16
#: assets/templates/assets/system_user_list.html:26 perms/models.py:17
#: terminal/backends/command/models.py:11 terminal/models.py:1
16
#: terminal/backends/command/models.py:11 terminal/models.py:1
23
#: terminal/templates/terminal/command_list.html:40
#: terminal/templates/terminal/command_list.html:73
#: terminal/templates/terminal/session_list.html:41
...
...
@@ -84,10 +84,10 @@ msgstr "资产"
#: assets/forms/user.py:24
msgid "Password or private key passphrase"
msgstr "密码或
秘
钥密码"
msgstr "密码或
密
钥密码"
#: 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:5
6
#: users/forms.py:16 users/forms.py:24 users/templates/users/login.html:5
9
#: users/templates/users/reset_password.html:52
#: users/templates/users/user_create.html:11
#: users/templates/users/user_password_update.html:40
...
...
@@ -116,11 +116,11 @@ msgstr "密码和私钥, 必须输入一个"
#: assets/templates/assets/system_user_detail.html:58
#: 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:8
8
ops/models.py:31
#: common/templates/common/terminal_setting.html:8
5
ops/models.py:31
#: 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/templates/perms/asset_permission_user.html:54 terminal/models.py:1
5
#: terminal/models.py:14
1
terminal/templates/terminal/terminal_detail.html:43
#: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:1
6
#: terminal/models.py:14
9
terminal/templates/terminal/terminal_detail.html:43
#: 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/templates/users/user_detail.html:63
...
...
@@ -138,9 +138,9 @@ msgstr "名称"
#: assets/templates/assets/system_user_detail.html:62
#: assets/templates/assets/system_user_list.html:25
#: perms/templates/perms/asset_permission_user.html:55 users/forms.py:14
#: users/models/authentication.py:4
4
users/models/user.py:34
#: users/models/authentication.py:4
5
users/models/user.py:34
#: users/templates/users/_select_user_modal.html:14
#: users/templates/users/login.html:5
3
#: users/templates/users/login.html:5
6
#: users/templates/users/login_log_list.html:49
#: users/templates/users/user_detail.html:67
#: users/templates/users/user_list.html:24
...
...
@@ -162,10 +162,10 @@ msgid ""
"than 2 system user"
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/asset_detail.html:61
#: assets/templates/assets/asset_list.html:8
1
#: assets/templates/assets/asset_list.html:8
7
#: assets/templates/assets/system_user_asset.html:50
#: assets/templates/assets/user_asset_list.html:20 common/forms.py:144
#: perms/templates/perms/asset_permission_asset.html:55
...
...
@@ -175,10 +175,10 @@ msgstr "高优先级的系统用户将会作为默认登录用户"
msgid "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/asset_detail.html:57
#: assets/templates/assets/asset_list.html:8
0
#: assets/templates/assets/asset_list.html:8
6
#: assets/templates/assets/system_user_asset.html:49
#: assets/templates/assets/user_asset_list.html:19 common/forms.py:143
#: perms/templates/perms/asset_permission_asset.html:54
...
...
@@ -187,77 +187,77 @@ msgstr "IP"
msgid "Hostname"
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
#: perms/templates/perms/asset_permission_list.html:70
msgid "Is active"
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"
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"
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"
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"
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"
msgstr "序列号"
#: assets/models/asset.py:6
0
#: assets/models/asset.py:6
8
msgid "CPU model"
msgstr "CPU型号"
#: assets/models/asset.py:6
1
#: assets/models/asset.py:6
9
msgid "CPU count"
msgstr "CPU数量"
#: assets/models/asset.py:
62
#: assets/models/asset.py:
70
msgid "CPU cores"
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"
msgstr "内存"
#: assets/models/asset.py:
64
#: assets/models/asset.py:
72
msgid "Disk total"
msgstr "硬盘大小"
#: assets/models/asset.py:
65
#: assets/models/asset.py:
73
msgid "Disk info"
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"
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"
msgstr "操作系统"
#: assets/models/asset.py:
69
#: assets/models/asset.py:
77
msgid "OS version"
msgstr "系统版本"
#: assets/models/asset.py:7
0
#: assets/models/asset.py:7
8
msgid "OS arch"
msgstr "系统架构"
#: assets/models/asset.py:7
1
#: assets/models/asset.py:7
9
msgid "Hostname raw"
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/templates/assets/admin_user_detail.html:68
#: assets/templates/assets/asset_detail.html:117
...
...
@@ -268,7 +268,7 @@ msgstr "主机名原始"
msgid "Created by"
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/templates/assets/admin_user_detail.html:64
#: assets/templates/assets/system_user_detail.html:92
...
...
@@ -280,7 +280,7 @@ msgstr "创建者"
msgid "Date created"
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/templates/assets/admin_user_detail.html:72
#: assets/templates/assets/admin_user_list.html:28
...
...
@@ -288,7 +288,7 @@ msgstr "创建日期"
#: assets/templates/assets/system_user_detail.html:100
#: assets/templates/assets/system_user_list.html:30 common/models.py:30
#: ops/models.py:37 perms/models.py:24 perms/models.py:81
#: perms/templates/perms/asset_permission_detail.html:98 terminal/models.py:2
5
#: perms/templates/perms/asset_permission_detail.html:98 terminal/models.py:2
6
#: 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/templates/users/user_group_detail.html:67
...
...
@@ -331,7 +331,7 @@ msgid "Default"
msgstr "默认"
#: assets/models/cluster.py:36 assets/models/label.py:13
#: users/models/user.py:26
1
#: users/models/user.py:26
6
msgid "System"
msgstr "系统"
...
...
@@ -352,13 +352,14 @@ msgid "Default asset group"
msgstr "默认资产组"
#: assets/models/label.py:14 perms/models.py:15
#: terminal/backends/command/models.py:10 terminal/models.py:1
15
#: terminal/backends/command/models.py:10 terminal/models.py:1
22
#: terminal/templates/terminal/command_list.html:32
#: terminal/templates/terminal/command_list.html:72
#: terminal/templates/terminal/session_list.html:33
#: 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/templates/users/user_group_list.html:13 users/views/user.py:330
#: users/models/user.py:30 users/models/user.py:254
#: users/templates/users/user_group_detail.html:78
#: users/templates/users/user_group_list.html:13 users/views/user.py:333
msgid "User"
msgstr "用户"
...
...
@@ -383,32 +384,32 @@ msgstr "ssh密钥"
msgid "SSH public key"
msgstr "ssh公钥"
#: assets/models/user.py:2
22
#: assets/models/user.py:2
19
msgid "Priority"
msgstr "优先级"
#: assets/models/user.py:22
3
assets/templates/assets/system_user_detail.html:66
#: assets/models/user.py:22
0
assets/templates/assets/system_user_detail.html:66
msgid "Protocol"
msgstr "协议"
#: assets/models/user.py:22
4
assets/templates/assets/_system_user.html:58
#: assets/models/user.py:22
1
assets/templates/assets/_system_user.html:58
#: assets/templates/assets/system_user_detail.html:118
#: assets/templates/assets/system_user_update.html:11
msgid "Auto push"
msgstr "自动推送"
#: assets/models/user.py:22
5
assets/templates/assets/system_user_detail.html:70
#: assets/models/user.py:22
2
assets/templates/assets/system_user_detail.html:70
msgid "Sudo"
msgstr "Sudo"
#: assets/models/user.py:22
6
assets/templates/assets/system_user_detail.html:75
#: assets/models/user.py:22
3
assets/templates/assets/system_user_detail.html:75
msgid "Shell"
msgstr "Shell"
#: assets/models/user.py:26
9
perms/forms.py:25 perms/models.py:19
#: assets/models/user.py:26
6
perms/forms.py:25 perms/models.py:19
#: perms/models.py:76 perms/templates/perms/asset_permission_detail.html:136
#: perms/templates/perms/asset_permission_list.html:69 templates/_nav.html:2
4
#: terminal/backends/command/models.py:12 terminal/models.py:1
17
#: perms/templates/perms/asset_permission_list.html:69 templates/_nav.html:2
5
#: terminal/backends/command/models.py:12 terminal/models.py:1
24
#: terminal/templates/terminal/command_list.html:48
#: terminal/templates/terminal/command_list.html:74
#: terminal/templates/terminal/session_list.html:49
...
...
@@ -463,7 +464,7 @@ msgstr "推送系统用户到节点: {}"
#: assets/templates/assets/_asset_group_bulk_update_modal.html:5
msgid "Update asset group"
msgstr "
编辑
用户组"
msgstr "
更新
用户组"
#: assets/templates/assets/_asset_group_bulk_update_modal.html:8
msgid "Hint: only change the field you want to update."
...
...
@@ -474,12 +475,11 @@ msgstr "仅修改你需要更新的字段"
#: 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: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:172 assets/views/asset.py:196 assets/views/label.py:26
#: assets/views/label.py:42 assets/views/label.py:58
#: assets/views/system_user.py:28 assets/views/system_user.py:44
#: assets/views/system_user.py:60 assets/views/system_user.py:74
#: templates/_nav.html:19
#: assets/views/asset.py:94 assets/views/asset.py:154 assets/views/asset.py:171
#: assets/views/asset.py:195 assets/views/label.py:26 assets/views/label.py:42
#: assets/views/label.py:58 assets/views/system_user.py:28
#: assets/views/system_user.py:44 assets/views/system_user.py:60
#: assets/views/system_user.py:74 templates/_nav.html:20
msgid "Assets"
msgstr "资产管理"
...
...
@@ -522,14 +522,14 @@ msgid "If set id, will use this id update asset existed"
msgstr "如果设置了id,则会使用该行信息更新该id的资产"
#: assets/templates/assets/_asset_list_modal.html:22
#: assets/templates/assets/asset_list.html:8
2
#: assets/templates/assets/asset_list.html:8
8
#: assets/templates/assets/user_asset_list.html:22
msgid "Hardware"
msgstr "硬件"
#: assets/templates/assets/_asset_list_modal.html:23
#: assets/templates/assets/asset_detail.html:143
#: assets/templates/assets/asset_list.html:8
3
#: assets/templates/assets/asset_list.html:8
9
#: assets/templates/assets/user_asset_list.html:23 perms/models.py:20
#: perms/models.py:77
#: perms/templates/perms/asset_permission_create_update.html:51
...
...
@@ -548,7 +548,7 @@ msgstr "激活中"
#: assets/templates/assets/admin_user_assets.html:54
#: assets/templates/assets/admin_user_list.html:25
#: 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_list.html:27
#: users/templates/users/user_granted_asset.html:47
...
...
@@ -558,13 +558,13 @@ msgstr "可连接"
#: assets/templates/assets/_asset_list_modal.html:25
#: 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/system_user_list.html:31
#: 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
#: 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
#: users/templates/users/user_group_list.html:15
#: users/templates/users/user_list.html:28
...
...
@@ -572,25 +572,25 @@ msgid "Action"
msgstr "动作"
#: 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
msgid "Delete selected"
msgstr "批量删除"
#: 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
msgid "Update selected"
msgstr "批量更新"
#: 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
msgid "Deactive selected"
msgstr "禁用所选"
#: 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
msgid "Active selected"
msgstr "激活所选"
...
...
@@ -599,16 +599,17 @@ msgstr "激活所选"
#: assets/templates/assets/_system_user.html:71
#: assets/templates/assets/admin_user_create_update.html:46
#: assets/templates/assets/asset_bulk_update.html:24
#: assets/templates/assets/asset_create.html:6
5
#: assets/templates/assets/asset_list.html:10
2
#: assets/templates/assets/asset_update.html:
69
#: assets/templates/assets/asset_create.html:6
6
#: assets/templates/assets/asset_list.html:10
8
#: assets/templates/assets/asset_update.html:
70
#: assets/templates/assets/label_create_update.html:17
#: common/templates/common/basic_setting.html:59
#: common/templates/common/email_setting.html:60
#: common/templates/common/ldap_setting.html:60
#: common/templates/common/terminal_setting.html:10
8
#: common/templates/common/terminal_setting.html:10
3
#: 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/first_login.html:62
#: users/templates/users/forgot_password.html:44
...
...
@@ -624,7 +625,7 @@ msgstr "提交"
#: assets/templates/assets/admin_user_detail.html:24
#: assets/templates/assets/admin_user_list.html:84
#: assets/templates/assets/asset_detail.html:24
#: assets/templates/assets/asset_list.html:16
0
#: assets/templates/assets/asset_list.html:16
6
#: assets/templates/assets/label_list.html:38
#: assets/templates/assets/system_user_detail.html:26
#: assets/templates/assets/system_user_list.html:85
...
...
@@ -643,7 +644,7 @@ msgstr "更新"
#: assets/templates/assets/admin_user_detail.html:28
#: assets/templates/assets/admin_user_list.html:85
#: assets/templates/assets/asset_detail.html:28
#: assets/templates/assets/asset_list.html:16
1
#: assets/templates/assets/asset_list.html:16
7
#: assets/templates/assets/label_list.html:39
#: assets/templates/assets/system_user_detail.html:30
#: assets/templates/assets/system_user_list.html:86
...
...
@@ -673,8 +674,8 @@ msgid "Basic"
msgstr "基本"
#: assets/templates/assets/_system_user.html:44
#: assets/templates/assets/asset_create.html:2
3
#: assets/templates/assets/asset_update.html:2
8
#: assets/templates/assets/asset_create.html:2
4
#: assets/templates/assets/asset_update.html:2
9
#: assets/templates/assets/system_user_update.html:7
#: users/templates/users/user_create.html:9
#: users/templates/users/user_update.html:6
...
...
@@ -683,28 +684,28 @@ msgstr "认证"
#: assets/templates/assets/_system_user.html:47
msgid "Auto generate key"
msgstr "自动生成
秘
钥"
msgstr "自动生成
密
钥"
#: assets/templates/assets/_system_user.html:64
#: assets/templates/assets/asset_create.html:5
7
#: assets/templates/assets/asset_update.html:6
1
#: assets/templates/assets/asset_create.html:5
8
#: assets/templates/assets/asset_update.html:6
2
#: perms/templates/perms/asset_permission_create_update.html:49
#: terminal/templates/terminal/terminal_update.html:4
1
#: terminal/templates/terminal/terminal_update.html:4
2
msgid "Other"
msgstr "其它"
#: assets/templates/assets/_system_user.html:70
#: assets/templates/assets/admin_user_create_update.html:45
#: assets/templates/assets/asset_bulk_update.html:23
#: assets/templates/assets/asset_create.html:6
4
#: assets/templates/assets/asset_update.html:6
8
#: assets/templates/assets/asset_create.html:6
5
#: assets/templates/assets/asset_update.html:6
9
#: assets/templates/assets/label_create_update.html:16
#: common/templates/common/basic_setting.html:58
#: common/templates/common/email_setting.html:59
#: common/templates/common/ldap_setting.html:59
#: common/templates/common/terminal_setting.html:10
6
#: common/templates/common/terminal_setting.html:10
1
#: perms/templates/perms/asset_permission_create_update.html:71
#: terminal/templates/terminal/terminal_update.html:4
6
#: terminal/templates/terminal/terminal_update.html:4
7
#: users/templates/users/_user.html:43
#: users/templates/users/user_bulk_update.html:23
#: users/templates/users/user_password_update.html:58
...
...
@@ -773,7 +774,7 @@ msgstr "替换资产的管理员"
#: assets/templates/assets/admin_user_detail.html:100
#: 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_list.html:135 templates/_modal.html:16
#: terminal/templates/terminal/session_detail.html:108
...
...
@@ -799,20 +800,20 @@ msgstr "不可达"
msgid "Ratio"
msgstr "比例"
#: assets/templates/assets/asset_create.html:2
7
#: assets/templates/assets/asset_update.html:3
2
perms/models.py:74
#: assets/templates/assets/asset_create.html:2
8
#: assets/templates/assets/asset_update.html:3
3
perms/models.py:74
#: perms/templates/perms/asset_permission_create_update.html:40
#: perms/templates/perms/asset_permission_list.html:67
msgid "Node"
msgstr "节点"
#: assets/templates/assets/asset_create.html:3
3
#: assets/templates/assets/asset_list.html:
69
#: assets/templates/assets/asset_update.html:3
8
#: assets/templates/assets/asset_create.html:3
4
#: assets/templates/assets/asset_list.html:
75
#: assets/templates/assets/asset_update.html:3
9
msgid "Label"
msgstr "标签"
#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:19
7
#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:19
6
msgid "Asset detail"
msgstr "资产详情"
...
...
@@ -850,50 +851,50 @@ msgstr "刷新"
msgid "Update successfully!"
msgstr "更新成功"
#: assets/templates/assets/asset_list.html:
57
#: assets/templates/assets/asset_list.html:1
14 assets/views/asset.py:96
#: assets/templates/assets/asset_list.html:
63
#: assets/templates/assets/asset_list.html:1
20 assets/views/asset.py:95
msgid "Create asset"
msgstr "创建资产"
#: assets/templates/assets/asset_list.html:6
1
#: assets/templates/assets/asset_list.html:6
7
#: users/templates/users/user_list.html:7
msgid "Import"
msgstr "导入"
#: assets/templates/assets/asset_list.html:
64
#: assets/templates/assets/asset_list.html:
70
#: users/templates/users/user_list.html:10
msgid "Export"
msgstr "导出"
#: assets/templates/assets/asset_list.html:
96
#: assets/templates/assets/asset_list.html:
102
msgid "Remove from this node"
msgstr "从节点移除"
#: assets/templates/assets/asset_list.html:1
15
#: assets/templates/assets/asset_list.html:1
21
msgid "Add asset"
msgstr "添加资产到节点"
#: assets/templates/assets/asset_list.html:1
17
#: assets/templates/assets/asset_list.html:1
23
msgid "Add node"
msgstr "新建节点"
#: assets/templates/assets/asset_list.html:1
18
#: assets/templates/assets/asset_list.html:1
24
msgid "Rename node"
msgstr "重命名节点"
#: assets/templates/assets/asset_list.html:12
0
#: assets/templates/assets/asset_list.html:12
6
msgid "Delete node"
msgstr "删除节点"
#: assets/templates/assets/asset_list.html:
195
#: assets/templates/assets/asset_list.html:
201
msgid "Create node failed"
msgstr "创建节点失败"
#: assets/templates/assets/asset_list.html:2
08
#: assets/templates/assets/asset_list.html:2
14
msgid "Have child node, cancel"
msgstr "存在子节点,不能删除"
#: assets/templates/assets/asset_list.html:
477
#: assets/templates/assets/asset_list.html:
536
#: assets/templates/assets/system_user_list.html:130
#: users/templates/users/user_detail.html:334
#: users/templates/users/user_detail.html:359
...
...
@@ -902,24 +903,24 @@ msgstr "存在子节点,不能删除"
msgid "Are you sure?"
msgstr "你确认吗?"
#: assets/templates/assets/asset_list.html:
478
#: assets/templates/assets/asset_list.html:
537
msgid "This will delete the selected assets !!!"
msgstr "删除选择资产"
#: assets/templates/assets/asset_list.html:
486
#: assets/templates/assets/asset_list.html:
545
msgid "Asset Deleted."
msgstr "已被删除"
#: assets/templates/assets/asset_list.html:
487
#: assets/templates/assets/asset_list.html:
492
#: assets/templates/assets/asset_list.html:
546
#: assets/templates/assets/asset_list.html:
551
msgid "Asset Delete"
msgstr "删除"
#: assets/templates/assets/asset_list.html:
491
#: assets/templates/assets/asset_list.html:
550
msgid "Asset Deleting failed."
msgstr "删除失败"
#: assets/templates/assets/asset_update.html:5
7
#: assets/templates/assets/asset_update.html:5
8
msgid "Configuration"
msgstr "配置"
...
...
@@ -1011,17 +1012,21 @@ msgstr "更新管理用户"
msgid "Admin user detail"
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"
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"
msgstr "批量更新资产"
#: assets/views/asset.py:17
3
#: assets/views/asset.py:17
2
msgid "Update asset"
msgstr "
编辑
资产"
msgstr "
更新
资产"
#: assets/views/asset.py:296
msgid "already exists"
...
...
@@ -1033,7 +1038,7 @@ msgstr "标签列表"
#: assets/views/label.py:59
msgid "Update label"
msgstr "
编辑
标签"
msgstr "
更新
标签"
#: assets/views/system_user.py:29
msgid "System user list"
...
...
@@ -1192,10 +1197,10 @@ msgstr "密码认证"
#: common/forms.py:156
msgid "Public key auth"
msgstr "
秘
钥认证"
msgstr "
密
钥认证"
#: 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"
msgstr "命令存储"
...
...
@@ -1205,8 +1210,8 @@ msgid ""
"other storage and some terminal using"
msgstr "设置终端命令存储,default是默认用的存储方式"
#: common/forms.py:165 common/templates/common/terminal_setting.html:8
4
#: terminal/
models.py:20
#: common/forms.py:165 common/templates/common/terminal_setting.html:8
1
#: terminal/
forms.py:34 terminal/models.py:21
msgid "Replay storage"
msgstr "录像存储"
...
...
@@ -1263,19 +1268,13 @@ msgid "Test connection"
msgstr "测试连接"
#: common/templates/common/terminal_setting.html:68
#: common/templates/common/terminal_setting.html:8
9
#: common/templates/common/terminal_setting.html:8
6
#: users/templates/users/login_log_list.html:50
msgid "Type"
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
#: templates/_nav.html:
66
#: templates/_nav.html:
72
msgid "Settings"
msgstr "系统设置"
...
...
@@ -1430,7 +1429,7 @@ msgstr "执行历史"
#: ops/templates/ops/adhoc_history.html:52
#: ops/templates/ops/adhoc_history_detail.html:58
#: ops/templates/ops/task_history.html:55 terminal/models.py:1
24
#: ops/templates/ops/task_history.html:55 terminal/models.py:1
32
#: terminal/templates/terminal/session_list.html:77
msgid "Date start"
msgstr "开始日期"
...
...
@@ -1542,7 +1541,7 @@ msgstr "任务开始: "
msgid "Ops"
msgstr "作业中心"
#: ops/views.py:37 templates/_nav.html:5
2
#: ops/views.py:37 templates/_nav.html:5
8
msgid "Task list"
msgstr "任务列表"
...
...
@@ -1551,8 +1550,9 @@ msgid "Task run history"
msgstr "执行历史"
#: perms/forms.py:22 perms/models.py:16 perms/models.py:75
#: perms/templates/perms/asset_permission_list.html:68 templates/_nav.html:13
#: users/models/user.py:37 users/templates/users/_select_user_modal.html:16
#: perms/templates/perms/asset_permission_list.html:68 templates/_nav.html:14
#: 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_list.html:26
msgid "User group"
...
...
@@ -1566,7 +1566,7 @@ msgstr "用户组"
msgid "Date expired"
msgstr "失效日期"
#: perms/models.py:88 templates/_nav.html:3
2
#: perms/models.py:88 templates/_nav.html:3
3
msgid "Asset permission"
msgstr "资产授权"
...
...
@@ -1660,7 +1660,7 @@ msgstr "添加用户组"
msgid "Select user groups"
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"
msgstr "权限管理"
...
...
@@ -1677,37 +1677,41 @@ msgid "Update asset permission"
msgstr "更新资产授权"
#: templates/_header_bar.html:18
msgid "Help"
msgstr "帮助"
msgid "Supports"
msgstr "商业支持"
#: templates/_header_bar.html:23
msgid "Docs"
msgstr "文档"
#: templates/_header_bar.html:3
2
templates/_nav_user.html:9
#: templates/_header_bar.html:3
7
templates/_nav_user.html:9
#: users/templates/users/_user.html:36
#: users/templates/users/user_password_update.html:37
#: users/templates/users/user_profile.html:17
#: users/templates/users/user_profile_update.html:37
#: users/templates/users/user_profile_update.html:57
#: users/templates/users/user_pubkey_update.html:37 users/views/user.py:31
3
#: users/templates/users/user_pubkey_update.html:37 users/views/user.py:31
6
msgid "Profile"
msgstr "个人信息"
#: templates/_header_bar.html:
36
#: templates/_header_bar.html:
40
msgid "Admin page"
msgstr "管理页面"
#: templates/_header_bar.html:
38
#: templates/_header_bar.html:
42
msgid "User page"
msgstr "用户页面"
#: templates/_header_bar.html:4
1
#: templates/_header_bar.html:4
5
msgid "Logout"
msgstr "注销登录"
#: templates/_header_bar.html:4
5 users/templates/users/login.html:42
#: users/templates/users/login.html:6
1
#: templates/_header_bar.html:4
9 users/templates/users/login.html:44
#: users/templates/users/login.html:6
4
msgid "Login"
msgstr "登录"
#: templates/_header_bar.html:
58
templates/_nav.html:4
#: templates/_header_bar.html:
62
templates/_nav.html:4
msgid "Dashboard"
msgstr "仪表盘"
...
...
@@ -1733,7 +1737,7 @@ msgid ""
" "
msgstr ""
"\n"
" 您的ssh
秘
钥没有设置或已失效,请点击 <a href="
" 您的ssh
密
钥没有设置或已失效,请点击 <a href="
"\"%(user_pubkey_update)s\"> 链接 </a> 更新\n"
" "
...
...
@@ -1741,39 +1745,43 @@ msgstr ""
msgid "Close"
msgstr "关闭"
#: templates/_nav.html:
9
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/login.py:2
49 users/views/user.py:57 users/views/user.py:72
#: users/views/user.py:
91 users/views/user.py:147 users/views/user.py:300
#: users/views/user.py:3
12 users/views/user.py:348 users/views/user.py:370
#: 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/
group.py:95
#: users/views/login.py:2
09 users/views/login.py:258 users/views/user.py:59
#: users/views/user.py:
74 users/views/user.py:93 users/views/user.py:149
#: users/views/user.py:3
04 users/views/user.py:351 users/views/user.py:373
msgid "Users"
msgstr "用户管理"
#: templates/_nav.html:1
2 users/views/user.py:58
#: templates/_nav.html:1
3 users/views/user.py:60
msgid "User list"
msgstr "用户列表"
#: templates/_nav.html:1
4
#: templates/_nav.html:1
5
msgid "Login logs"
msgstr "登录日志"
#: templates/_nav.html:3
8
#: templates/_nav.html:3
9
msgid "Sessions"
msgstr "会话管理"
#: templates/_nav.html:4
1
#: templates/_nav.html:4
2
msgid "Session online"
msgstr "在线会话"
#: templates/_nav.html:4
2
#: templates/_nav.html:4
3
msgid "Session offline"
msgstr "历史会话"
#: templates/_nav.html:4
3
#: templates/_nav.html:4
4
msgid "Commands"
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/session.py:92 terminal/views/session.py:114
#: terminal/views/terminal.py:31 terminal/views/terminal.py:46
...
...
@@ -1781,18 +1789,10 @@ msgstr "命令记录"
msgid "Terminal"
msgstr "终端管理"
#: templates/_nav.html:
49
#: templates/_nav.html:
55
msgid "Job Center"
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
msgid "Play CAPTCHA as audio file"
msgstr "语言播放验证码"
...
...
@@ -1819,71 +1819,75 @@ msgstr "输出"
msgid "Session"
msgstr "会话"
#: terminal/forms.py:
27
#: terminal/forms.py:
44
msgid "Coco ssh listen port"
msgstr "SSH 监听端口"
#: terminal/forms.py:
28
#: terminal/forms.py:
45
msgid "Coco http/ws listen port"
msgstr "Http/Websocket 监听端口"
#: terminal/models.py:1
6
#: terminal/models.py:1
7
msgid "Remote Address"
msgstr "远端地址"
#: terminal/models.py:1
7
#: terminal/models.py:1
8
msgid "SSH Port"
msgstr "SSH端口"
#: terminal/models.py:1
8
#: terminal/models.py:1
9
msgid "HTTP Port"
msgstr "HTTP端口"
#: terminal/models.py:9
1
#: terminal/models.py:9
8
msgid "Session Online"
msgstr "在线会话"
#: terminal/models.py:9
2
#: terminal/models.py:9
9
msgid "CPU Usage"
msgstr "CPU使用"
#: terminal/models.py:
93
#: terminal/models.py:
100
msgid "Memory Used"
msgstr "内存使用"
#: terminal/models.py:
94
#: terminal/models.py:
101
msgid "Connections"
msgstr "连接数"
#: terminal/models.py:
95
#: terminal/models.py:
102
msgid "Threads"
msgstr "线程数"
#: terminal/models.py:
96
#: terminal/models.py:
103
msgid "Boot Time"
msgstr "运行时间"
#: terminal/models.py:1
19
terminal/templates/terminal/session_list.html:74
#: terminal/models.py:1
26
terminal/templates/terminal/session_list.html:74
#: terminal/templates/terminal/terminal_detail.html:47
msgid "Remote addr"
msgstr "远端地址"
#: terminal/models.py:12
1 terminal/templates/terminal/session_list.html:100
#: terminal/models.py:12
8 terminal/templates/terminal/session_list.html:102
msgid "Replay"
msgstr "回放"
#: terminal/models.py:12
2
terminal/templates/terminal/command_list.html:55
#: terminal/models.py:12
9
terminal/templates/terminal/command_list.html:55
#: terminal/templates/terminal/command_list.html:71
#: terminal/templates/terminal/session_detail.html:48
#: terminal/templates/terminal/session_list.html:76
msgid "Command"
msgstr "命令"
#: terminal/models.py:125
#: terminal/models.py:131
msgid "Date last active"
msgstr "最后活跃日期"
#: terminal/models.py:133
msgid "Date end"
msgstr "结束日期"
#: terminal/models.py:1
42
#: terminal/models.py:1
50
msgid "Args"
msgstr "参数"
...
...
@@ -1922,19 +1926,25 @@ msgstr "监控"
msgid "Terminate session"
msgstr "终止会话"
#: terminal/templates/terminal/session_list.html:7
8
#: terminal/templates/terminal/session_list.html:7
9
msgid "Duration"
msgstr "时长"
#: terminal/templates/terminal/session_list.html:10
2
#: terminal/templates/terminal/session_list.html:10
4
msgid "Monitor"
msgstr "监控"
#: terminal/templates/terminal/session_list.html:10
3
#: terminal/templates/terminal/session_list.html:10
5
msgid "Terminate"
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 ..."
msgstr "终断任务已发送,请等待"
...
...
@@ -2105,31 +2115,31 @@ msgstr "ssh密钥不合法"
msgid "Select users"
msgstr "选择用户"
#: users/models/authentication.py:3
5
#: users/models/authentication.py:3
6
msgid "Private Token"
msgstr "ssh密钥"
#: users/models/authentication.py:4
5
#: users/models/authentication.py:4
6
msgid "Login type"
msgstr "登录方式"
#: users/models/authentication.py:4
6
#: users/models/authentication.py:4
7
msgid "Login ip"
msgstr "登录IP"
#: users/models/authentication.py:4
7
#: users/models/authentication.py:4
8
msgid "Login city"
msgstr "登录城市"
#: users/models/authentication.py:4
8
#: users/models/authentication.py:4
9
msgid "User agent"
msgstr "Agent"
#: users/models/authentication.py:
49
#: users/models/authentication.py:
50
msgid "Date login"
msgstr "登录日期"
#: users/models/user.py:29 users/models/user.py:2
57
#: users/models/user.py:29 users/models/user.py:2
62
msgid "Administrator"
msgstr "管理员"
...
...
@@ -2168,7 +2178,7 @@ msgstr "二次验证"
msgid "Public key"
msgstr "ssh公钥"
#: users/models/user.py:26
0
#: users/models/user.py:26
5
msgid "Administrator is the super user of system"
msgstr "Administrator是初始的超级管理员"
...
...
@@ -2239,7 +2249,7 @@ msgid " for more information"
msgstr "获取更多信息"
#: users/templates/users/forgot_password.html:26
#: users/templates/users/login.html:
64
#: users/templates/users/login.html:
73
msgid "Forgot password"
msgstr "忘记密码"
...
...
@@ -2247,7 +2257,7 @@ msgstr "忘记密码"
msgid "Input your email, that will send a mail to your"
msgstr "输入您的邮箱, 将会发一封重置邮件到您的邮箱中"
#: users/templates/users/login.html:
47
#: users/templates/users/login.html:
50
msgid "Captcha invalid"
msgstr "验证码错误"
...
...
@@ -2269,8 +2279,13 @@ msgstr "重置密码"
msgid "Password again"
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_list.html:16 users/views/user.py:7
2
#: users/templates/users/user_list.html:16 users/views/user.py:7
4
msgid "Create user"
msgstr "创建用户"
...
...
@@ -2279,7 +2294,7 @@ msgid "Reset link will be generated and sent to the user. "
msgstr "生成重置密码连接,通过邮件发送给用户"
#: users/templates/users/user_detail.html:19
#: users/templates/users/user_granted_asset.html:18 users/views/user.py:1
48
#: users/templates/users/user_granted_asset.html:18 users/views/user.py:1
50
msgid "User detail"
msgstr "用户详情"
...
...
@@ -2320,7 +2335,7 @@ msgstr "将失效用户当前密码,并发送重设密码邮件到用户邮箱
msgid ""
"The reset-ssh-public-key E-mail has been sent successfully. Please inform "
"the user to update his new ssh public key."
msgstr "重设
秘
钥邮件将会发送到用户邮箱"
msgstr "重设
密
钥邮件将会发送到用户邮箱"
#: users/templates/users/user_detail.html:350
#: users/templates/users/user_profile.html:140
...
...
@@ -2329,7 +2344,7 @@ msgstr "重置SSH密钥"
#: users/templates/users/user_detail.html:360
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_profile.html:166
...
...
@@ -2351,7 +2366,7 @@ msgstr "取消"
#: users/templates/users/user_group_granted_asset.html:18
#: users/views/group.py:80
msgid "User group detail"
msgstr "
资产
组详情"
msgstr "
用户
组详情"
#: users/templates/users/user_group_detail.html:86
msgid "Add user"
...
...
@@ -2399,8 +2414,8 @@ msgstr "用户删除失败"
msgid "OTP"
msgstr ""
#: users/templates/users/user_profile.html:100 users/views/user.py:17
7
#: users/views/user.py:2
29
#: users/templates/users/user_profile.html:100 users/views/user.py:17
9
#: users/views/user.py:2
33
msgid "User groups"
msgstr "用户组"
...
...
@@ -2420,9 +2435,9 @@ msgstr "指纹"
msgid "Update public key"
msgstr "更新密钥"
#: users/templates/users/user_update.html:4 users/views/user.py:9
1
#: users/templates/users/user_update.html:4 users/views/user.py:9
3
msgid "Update user"
msgstr "
编辑
用户"
msgstr "
更新
用户"
#: users/utils.py:35
msgid "Create account successfully"
...
...
@@ -2552,7 +2567,7 @@ msgstr "禁用或失效"
#: users/utils.py:154
msgid "Password or SSH public key invalid"
msgstr "密码或
秘
钥不合法"
msgstr "密码或
密
钥不合法"
#: users/views/group.py:29
msgid "User group list"
...
...
@@ -2560,78 +2575,81 @@ msgstr "用户组列表"
#: users/views/group.py:63
msgid "Update user group"
msgstr "编辑用户组"
msgstr "更新用户组"
#: users/views/group.py:96
msgid "User group granted asset"
msgstr "用户组授权资产"
#: users/views/login.py:5
6
#: users/views/login.py:5
7
msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie"
#: users/views/login.py:9
0
#: users/views/login.py:9
9
msgid "Logout success"
msgstr "退出登录成功"
#: users/views/login.py:
91
#: users/views/login.py:
100
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
#: users/views/login.py:1
07
#: users/views/login.py:1
16
msgid "Email address invalid, please input again"
msgstr "邮箱地址错误,重新输入"
#: users/views/login.py:12
0
#: users/views/login.py:12
9
msgid "Send reset password message"
msgstr "发送重置密码邮件"
#: users/views/login.py:1
21
#: users/views/login.py:1
30
msgid "Send reset password mail success, login your mail box and follow it "
msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
#: users/views/login.py:1
35
#: users/views/login.py:1
44
msgid "Reset password success"
msgstr "重置密码成功"
#: users/views/login.py:1
36
#: users/views/login.py:1
45
msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面"
#: users/views/login.py:1
53 users/views/login.py:166
#: users/views/login.py:1
62 users/views/login.py:175
msgid "Token invalid or expired"
msgstr "Token错误或失效"
#: users/views/login.py:1
62
#: users/views/login.py:1
71
msgid "Password not same"
msgstr "密码不一致"
#: users/views/login.py:20
0
#: users/views/login.py:20
9
msgid "First login"
msgstr "首次登陆"
#: users/views/login.py:25
0
#: users/views/login.py:25
9
msgid "Login log list"
msgstr "登录日志"
#: users/views/user.py:10
1
#: users/views/user.py:10
3
msgid "Bulk update user success"
msgstr "批量更新用户成功"
#: users/views/user.py:20
6
#: users/views/user.py:20
8
msgid "Invalid file."
msgstr "文件不合法"
#: users/views/user.py:30
1
#: users/views/user.py:30
5
msgid "User granted assets"
msgstr "用户授权资产"
#: users/views/user.py:33
1
#: users/views/user.py:33
4
msgid "Profile setting"
msgstr "个人信息设置"
#: users/views/user.py:3
49
#: users/views/user.py:3
52
msgid "Password update"
msgstr "密码更新"
#: users/views/user.py:37
1
#: users/views/user.py:37
4
msgid "Public key update"
msgstr "秘钥更新"
msgstr "密钥更新"
apps/jumpserver/settings.py
View file @
8e09151a
...
...
@@ -397,6 +397,6 @@ BOOTSTRAP3 = {
}
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
USER_GUIDE_URL
=
""
apps/jumpserver/urls.py
View file @
8e09151a
...
...
@@ -4,16 +4,16 @@ from __future__ import unicode_literals
from
django.conf.urls
import
url
,
include
from
django.conf
import
settings
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_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
])
urlpatterns
=
[
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'^assets/'
,
include
(
'assets.urls.views_urls'
,
namespace
=
'assets'
)),
url
(
r'^perms/'
,
include
(
'perms.urls.views_urls'
,
namespace
=
'perms'
)),
...
...
apps/jumpserver/views.py
View file @
8e09151a
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.db.models
import
Count
from
django.contrib.auth.mixins
import
LoginRequiredMixin
...
...
@@ -45,7 +46,8 @@ class IndexView(LoginRequiredMixin, TemplateView):
return
self
.
session_week
.
values
(
'user'
)
.
distinct
()
.
count
()
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
):
month_str
=
[
d
.
strftime
(
'
%
m-
%
d'
)
for
d
in
self
.
session_month_dates
]
or
[
'0'
]
...
...
@@ -149,3 +151,12 @@ class IndexView(LoginRequiredMixin, TemplateView):
kwargs
.
update
(
context
)
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
apps/perms/api.py
View file @
8e09151a
...
...
@@ -54,7 +54,11 @@ class UserGrantedAssetsApi(ListAPIView):
user
=
self
.
request
.
user
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
)
return
queryset
...
...
@@ -118,9 +122,16 @@ class UserGrantedNodesWithAssetsApi(ListAPIView):
user
=
get_object_or_404
(
User
,
id
=
user_id
)
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
asset
in
v
[
'assets'
]:
asset
.
system_users_granted
=
v
[
'system_users'
]
asset
.
system_users_granted
=
assets
[
asset
]
node
.
assets_granted
=
v
[
'assets'
]
queryset
.
append
(
node
)
return
queryset
...
...
apps/perms/serializers.py
View file @
8e09151a
...
...
@@ -12,7 +12,7 @@ class AssetPermissionCreateUpdateSerializer(serializers.ModelSerializer):
class
Meta
:
model
=
NodePermission
fields
=
[
'node'
,
'user_group'
,
'system_user'
,
'
id'
,
'
node'
,
'user_group'
,
'system_user'
,
'is_active'
,
'date_expired'
]
...
...
apps/perms/templates/perms/asset_permission_create_update.html
View file @
8e09151a
...
...
@@ -14,7 +14,7 @@
<div
class=
"col-sm-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<h5>
{
% trans 'Create asset permission ' %
}
</h5>
<h5>
{
{ action }
}
</h5>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
...
...
apps/perms/templates/perms/asset_permission_list.html
View file @
8e09151a
...
...
@@ -215,16 +215,6 @@ $(document).ready(function(){
initTable
();
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
()
{
var
$this
=
$
(
this
);
var
uid
=
$this
.
data
(
'uid'
);
...
...
@@ -241,7 +231,7 @@ $(document).ready(function(){
current_node
=
nodes
[
0
];
url
+=
"?node_id="
+
current_node
.
id
;
}
window
.
open
(
url
);
window
.
open
(
url
,
'_self'
);
})
</script>
...
...
apps/perms/utils.py
View file @
8e09151a
...
...
@@ -56,7 +56,7 @@ class NodePermissionUtil:
nodes_with_assets
=
dict
()
for
node
,
system_users
in
nodes
.
items
():
nodes_with_assets
[
node
]
=
{
'assets'
:
node
.
get_assets
(),
'assets'
:
node
.
get_a
ctive_a
ssets
(),
'system_users'
:
system_users
}
return
nodes_with_assets
...
...
@@ -87,7 +87,7 @@ class NodePermissionUtil:
nodes_with_assets
=
dict
()
for
node
,
system_users
in
nodes
.
items
():
nodes_with_assets
[
node
]
=
{
'assets'
:
node
.
get_assets
(),
'assets'
:
node
.
get_a
ctive_a
ssets
(),
'system_users'
:
system_users
}
return
nodes_with_assets
...
...
apps/static/css/jumpserver.css
View file @
8e09151a
...
...
@@ -427,3 +427,9 @@ div.dataTables_wrapper div.dataTables_filter {
text-align
:
center
;
padding
:
5px
0
;
}
.profile-dropdown
li
a
{
font-size
:
12px
!important
;
}
apps/static/css/style.css
View file @
8e09151a
...
...
@@ -3299,7 +3299,7 @@ body.tour-open .animated {
border-bottom
:
1px
solid
#e7eaec
;
}
body
{
font-family
:
"open sans"
,
"Helvetica Neue"
,
Helvetica
,
Arial
,
sans-serif
;
font-family
:
"open sans"
,
"Helvetica Neue"
,
"微软雅黑"
,
Helvetica
,
Arial
,
sans-serif
;
background-color
:
#2f4050
;
font-size
:
13px
;
color
:
#676a6c
;
...
...
apps/static/img/logo-text.png
View replaced file @
18841d6c
View file @
8e09151a
12.4 KB
|
W:
|
H:
17.7 KB
|
W:
|
H:
2-up
Swipe
Onion skin
apps/templates/_copyright.html
0 → 100644
View file @
8e09151a
<strong>
Copyright
</strong>
北京堆栈科技有限公司
©
2014-2018
\ No newline at end of file
apps/templates/_header_bar.html
View file @
8e09151a
...
...
@@ -14,8 +14,13 @@
{#
<span
class=
"m-r-sm text-muted welcome-message"
>
{% trans 'Welcome to use Jumpserver system' %}
</span>
#}
{#
</li>
#}
<li
class=
"dropdown"
>
<a
class=
"dropdown-toggle count-info"
data-toggle=
"dropdown"
href=
"#"
>
<span
class=
"m-r-sm text-muted welcome-message"
>
{% trans 'Help' %}
</span>
<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 '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>
</li>
<li
class=
"dropdown"
>
...
...
@@ -28,9 +33,8 @@
</span>
</span>
</a>
<ul
class=
"dropdown-menu animated fadeInRight m-t-xs"
>
<li><a
href=
"{% url 'users:user-profile' %}"
><i
class=
"fa fa-cogs"
>
</i><span>
{% trans 'Profile' %}
</span></a></li>
<li
class=
"divider"
></li>
<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>
{% if request.user.is_superuser %}
{% 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>
...
...
@@ -57,11 +61,11 @@
<li>
<a
href=
""
>
{% trans 'Dashboard' %}
</a>
</li>
<li>
{% if app %}
<li>
<a>
{{ app }}
</a>
{% endif %}
</li>
{% endif %}
{% if action %}
<li
class=
"active"
>
<strong>
{{ action }}
</strong>
...
...
apps/templates/_nav.html
View file @
8e09151a
{% load i18n %}
<li
id=
"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>
</li>
<li
id=
"users"
>
<a
href=
"#"
>
<i
class=
"fa fa-group"
style=
"
font-size: 13
px"
></i>
<span
class=
"nav-label"
>
{% trans 'Users' %}
</span><span
class=
"fa arrow"
></span>
<i
class=
"fa fa-group"
style=
"
width: 14
px"
></i>
<span
class=
"nav-label"
>
{% trans 'Users' %}
</span><span
class=
"fa arrow"
></span>
</a>
<ul
class=
"nav nav-second-level active"
>
<li
id=
"user"
><a
href=
"{% url 'users:user-list' %}"
>
{% trans 'User list' %}
</a></li>
...
...
@@ -16,7 +17,7 @@
</li>
<li
id=
"assets"
>
<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>
<ul
class=
"nav nav-second-level"
>
<li
id=
"asset"
><a
href=
"{% url 'assets:asset-list' %}"
>
{% trans 'Asset list' %}
</a></li>
...
...
@@ -26,7 +27,7 @@
</ul>
</li>
<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"
>
<li
id=
"asset-permission"
>
<a
href=
"{% url 'perms:asset-permission-list' %}"
>
{% trans 'Asset permission' %}
</a>
...
...
@@ -35,18 +36,23 @@
</li>
<li
id=
"terminal"
>
<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>
<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-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>
<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>
</ul>
</li>
<li
id=
"ops"
>
<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>
<ul
class=
"nav nav-second-level"
>
<li
id=
"task"
><a
href=
"{% url 'ops:task-list' %}"
>
{% trans 'Task list' %}
</a></li>
...
...
apps/templates/_nav_user.html
View file @
8e09151a
{% load i18n %}
<li
id=
"assets"
>
<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>
</li>
<li
id=
"users"
>
<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>
</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>
</a>
</li>
\ No newline at end of file
apps/templates/_user_profile.html
View file @
8e09151a
...
...
@@ -3,7 +3,7 @@
<li
class=
"nav-header"
>
<div
class=
"dropdown profile-element"
>
<div
href=
"http://www.jumpserver.org"
target=
"_blank"
>
<img
alt=
"
image"
height=
"55"
src=
"/static/img/logo-text.png"
style=
"margin-left: 1
0px"
/>
<img
alt=
"
logo"
height=
"55"
width=
"185"
src=
"/static/img/logo-text.png"
style=
"margin-left: 2
0px"
/>
</div>
</div>
<div
class=
"clearfix"
></div>
...
...
apps/templates/flash_message_standalone.html
View file @
8e09151a
...
...
@@ -49,7 +49,7 @@
<hr/>
<div
class=
"row"
>
<div
class=
"col-md-6"
>
Copyright Jumpserver.org
{% include '_copyright.html' %}
</div>
<div
class=
"col-md-6 text-right"
>
<small>
2014-2018
</small>
...
...
apps/templates/index.html
View file @
8e09151a
...
...
@@ -11,7 +11,7 @@
</div>
<div
class=
"ibox-content"
>
<h1
class=
"no-margins"
><a
href=
"{% url 'users:user-list' %}"
>
{{ users_count }}
</a></h1>
<small>
All user
</small>
<small>
All user
s
</small>
</div>
</div>
</div>
...
...
@@ -23,7 +23,7 @@
</div>
<div
class=
"ibox-content"
>
<h1
class=
"no-margins"
><a
href=
"{% url 'assets:asset-list' %}"
>
{{ assets_count }}
</a></h1>
<small>
All host
</small>
<small>
All host
s
</small>
</div>
</div>
</div>
...
...
@@ -36,7 +36,7 @@
</div>
<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>
<small>
Online user
</small>
<small>
Online user
s
</small>
</div>
</div>
</div>
...
...
@@ -57,7 +57,7 @@
<div
class=
"row"
>
<div
class=
"col-sm-2 border-bottom white-bg dashboard-header"
style=
"margin-left:15px;height: 346px"
>
<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"
>
{% for data in user_visit_count_top_five %}
<li
class=
"list-group-item fist-item"
>
...
...
apps/terminal/forms.py
View file @
8e09151a
...
...
@@ -25,18 +25,22 @@ def get_all_replay_storage():
class
TerminalForm
(
forms
.
ModelForm
):
command_storage
=
forms
.
ChoiceField
(
choices
=
get_all_command_storage
(),
label
=
_
(
"Command storage"
))
replay_storage
=
forms
.
ChoiceField
(
choices
=
get_all_replay_storage
(),
label
=
_
(
"Replay storage"
))
command_storage
=
forms
.
ChoiceField
(
choices
=
get_all_command_storage
(),
label
=
_
(
"Command storage"
)
)
replay_storage
=
forms
.
ChoiceField
(
choices
=
get_all_replay_storage
(),
label
=
_
(
"Replay storage"
)
)
class
Meta
:
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
=
{
'ssh_port'
:
_
(
"Coco ssh listen port"
),
'http_port'
:
_
(
"Coco http/ws listen port"
),
}
widgets
=
{
'name'
:
forms
.
TextInput
(
attrs
=
{
'readonly'
:
'readonly'
})
}
apps/terminal/models.py
View file @
8e09151a
...
...
@@ -4,6 +4,7 @@ import uuid
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils
import
timezone
from
django.conf
import
settings
from
users.models
import
User
...
...
@@ -127,6 +128,7 @@ class Session(models.Model):
has_replay
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
"Replay"
))
has_command
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
_
(
"Command"
))
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_end
=
models
.
DateTimeField
(
verbose_name
=
_
(
"Date end"
),
null
=
True
)
...
...
apps/terminal/tasks.py
View file @
8e09151a
# -*- coding: utf-8 -*-
#
import
datetime
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
RUNNING
=
False
# Todo: 定期清理上报history
@shared_task
def
clean_terminal_history
():
pass
@register_as_period_task
(
interval
=
3600
)
@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
()
apps/terminal/templates/terminal/session_list.html
View file @
8e09151a
...
...
@@ -75,6 +75,7 @@
<th
class=
"text-center"
>
{% trans 'Terminal' %}
</th>
<th
class=
"text-center"
>
{% trans 'Command' %}
</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 'Action' %}
</th>
{% endblock %}
...
...
@@ -94,6 +95,7 @@
<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_last_active }}
</td>
#}
<td
class=
"text-center"
>
{{ session.date_start|time_util_with_seconds:session.date_end }}
</td>
<td>
{% if session.is_finished %}
...
...
@@ -107,6 +109,21 @@
{% endfor %}
{% 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 %}
<script
src=
"{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"
></script>
<script>
...
...
apps/terminal/views/command.py
View file @
8e09151a
...
...
@@ -6,7 +6,7 @@ from django.conf import settings
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext
as
_
from
common.mixins
import
DatetimeSearchMixin
from
common.mixins
import
DatetimeSearchMixin
,
AdminUserRequiredMixin
from
..models
import
Command
from
..
import
utils
from
..backends
import
get_multi_command_store
...
...
@@ -15,7 +15,7 @@ __all__ = ['CommandListView']
common_storage
=
get_multi_command_store
()
class
CommandListView
(
DatetimeSearchMixin
,
ListView
):
class
CommandListView
(
DatetimeSearchMixin
,
AdminUserRequiredMixin
,
ListView
):
model
=
Command
template_name
=
"terminal/command_list.html"
context_object_name
=
'command_list'
...
...
apps/terminal/views/session.py
View file @
8e09151a
...
...
@@ -97,7 +97,7 @@ class SessionOfflineListView(SessionListView):
return
super
()
.
get_context_data
(
**
kwargs
)
class
SessionDetailView
(
SingleObjectMixin
,
ListView
):
class
SessionDetailView
(
SingleObjectMixin
,
AdminUserRequiredMixin
,
ListView
):
template_name
=
'terminal/session_detail.html'
model
=
Session
object
=
None
...
...
apps/users/api.py
View file @
8e09151a
...
...
@@ -145,7 +145,8 @@ class UserAuthApi(APIView):
if
not
login_ip
:
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
]
else
:
login_ip
=
request
.
META
.
get
(
"REMOTE_ADDR"
)
...
...
apps/users/apps.py
View file @
8e09151a
...
...
@@ -6,3 +6,6 @@ from django.apps import AppConfig
class
UsersConfig
(
AppConfig
):
name
=
'users'
def
ready
(
self
):
from
.
import
signals_handler
super
()
.
ready
()
apps/users/models/authentication.py
View file @
8e09151a
...
...
@@ -16,7 +16,8 @@ class AccessKey(models.Model):
default
=
uuid
.
uuid4
,
editable
=
False
)
secret
=
models
.
UUIDField
(
verbose_name
=
'AccessKeySecret'
,
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
):
return
str
(
self
.
id
)
...
...
apps/users/models/group.py
View file @
8e09151a
...
...
@@ -22,6 +22,7 @@ class UserGroup(NoDeleteModelMixin):
class
Meta
:
ordering
=
[
'name'
]
verbose_name
=
_
(
"User group"
)
@classmethod
def
initial
(
cls
):
...
...
apps/users/models/user.py
View file @
8e09151a
...
...
@@ -151,6 +151,10 @@ class User(AbstractUser):
def
save
(
self
,
*
args
,
**
kwargs
):
if
not
self
.
name
:
self
.
name
=
self
.
username
if
self
.
username
==
'admin'
:
self
.
role
=
'Admin'
self
.
is_active
=
True
super
()
.
save
(
*
args
,
**
kwargs
)
@property
...
...
@@ -247,6 +251,7 @@ class User(AbstractUser):
class
Meta
:
ordering
=
[
'username'
]
verbose_name
=
_
(
"User"
)
#: Use this method initial user
@classmethod
...
...
apps/users/signals.py
View file @
8e09151a
# -*- 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
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
)
post_user_create
=
Signal
(
providing_args
=
(
'user'
,))
apps/users/signals_handler.py
0 → 100644
View file @
8e09151a
# -*- 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
apps/users/templates/users/forgot_password.html
View file @
8e09151a
...
...
@@ -51,11 +51,8 @@
</div>
<hr/>
<div
class=
"row"
>
<div
class=
"col-md-6"
>
Copyright Jumpserver.org
</div>
<div
class=
"col-md-6 text-right"
>
<small>
© 2014-2018
</small>
<div
class=
"col-md-12"
>
{% include '_copyright.html' %}
</div>
</div>
</div>
...
...
apps/users/templates/users/login.html
View file @
8e09151a
...
...
@@ -22,24 +22,27 @@
<div
class=
"loginColumns animated fadeInDown"
>
<div
class=
"row"
>
<div
class=
"col-md-6"
>
<h2
class=
"font-bold"
>
欢迎使用Jumpserver开源
跳板
机
</h2>
<h2
class=
"font-bold"
>
欢迎使用Jumpserver开源
堡垒
机
</h2>
<p>
Jumpserver是一款使用Python, Django开发的开源跳板机系统, 助力互联网企业高效 用户、资产、权限、审计 管理
全球首款完全开源的堡垒机,使用GNU GPL v2.0开源协议,是符合 4A 的专业运维审计系统。
</p>
<p>
我们自五湖四海,我们对开源精神无比敬仰和崇拜,我们对完美、整洁、优雅 无止境的追求
使用Python / Django 进行开发,遵循 Web 2.0 规范,配备了业界领先的 Web Terminal 解决方案,交互界面美观、用户体验好。
</p>
<p>
专注自动化运维,努力打造 易用、稳定、安全、自动化 的跳板机, 这是我们的不懈的追求和动力
采纳分布式架构,支持多机房跨区域部署,中心节点提供 API,各机房部署登录节点,可横向扩展、无并发访问限制。
</p>
<p>
<small>
永远年轻,永远热泪盈眶 stay foolish stay hungry
</small>
改变世界,从一点点开始。
</p>
</div>
<div
class=
"col-md-6"
>
<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=
""
>
{% csrf_token %}
{% if form.errors %}
...
...
@@ -60,12 +63,16 @@
</div>
<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' %}"
>
<small>
{% trans 'Forgot password' %}?
</small>
</a>
<p
class=
"text-muted text-center"
>
</p>
</form>
<p
class=
"m-t"
>
</p>
...
...
@@ -74,11 +81,8 @@
</div>
<hr/>
<div
class=
"row"
>
<div
class=
"col-md-6"
>
Copyright 北京堆栈科技有限公司
</div>
<div
class=
"col-md-6 text-right"
>
<small>
© 2014-2018
</small>
<div
class=
"col-md-12"
>
{% include '_copyright.html' %}
</div>
</div>
</div>
...
...
apps/users/templates/users/reset_password.html
View file @
8e09151a
...
...
@@ -70,11 +70,8 @@
</div>
<hr/>
<div
class=
"row"
>
<div
class=
"col-md-6"
>
Copyright Jumpserver.org
</div>
<div
class=
"col-md-6 text-right"
>
<small>
© 2014-2018
</small>
<div
class=
"col-md-12"
>
{% include '_copyright.html' %}
</div>
</div>
</div>
...
...
apps/users/views/group.py
View file @
8e09151a
...
...
@@ -92,8 +92,8 @@ class UserGroupGrantedAssetView(AdminUserRequiredMixin, DetailView):
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
'User'
,
'action'
:
'User group granted asset'
,
'app'
:
_
(
'Users'
)
,
'action'
:
_
(
'User group granted asset'
)
,
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
apps/users/views/login.py
View file @
8e09151a
# ~*~ coding: utf-8 ~*~
from
__future__
import
unicode_literals
import
os
from
django
import
forms
from
django.shortcuts
import
render
from
django.contrib.auth
import
login
as
auth_login
,
logout
as
auth_logout
...
...
@@ -56,6 +57,7 @@ class UserLoginView(FormView):
return
HttpResponse
(
_
(
"Please enable cookies and try again."
))
auth_login
(
self
.
request
,
form
.
get_user
())
x_forwarded_for
=
self
.
request
.
META
.
get
(
'HTTP_X_FORWARDED_FOR'
,
''
)
.
split
(
','
)
if
x_forwarded_for
and
x_forwarded_for
[
0
]:
login_ip
=
x_forwarded_for
[
0
]
else
:
...
...
@@ -75,6 +77,13 @@ class UserLoginView(FormView):
self
.
redirect_field_name
,
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'
)
class
UserLogoutView
(
TemplateView
):
...
...
@@ -237,7 +246,7 @@ class LoginLogListView(DatetimeSearchMixin, ListView):
if
self
.
user
:
queryset
=
queryset
.
filter
(
username
=
self
.
user
)
if
self
.
keyword
:
queryset
=
self
.
queryset
.
filter
(
queryset
=
queryset
.
filter
(
Q
(
ip__contains
=
self
.
keyword
)
|
Q
(
city__contains
=
self
.
keyword
)
|
Q
(
username__contains
=
self
.
keyword
)
...
...
apps/users/views/user.py
View file @
8e09151a
...
...
@@ -6,6 +6,7 @@ import json
import
uuid
import
csv
import
codecs
import
chardet
from
io
import
StringIO
from
django.contrib
import
messages
...
...
@@ -20,6 +21,7 @@ from django.utils.translation import ugettext as _
from
django.utils.decorators
import
method_decorator
from
django.views
import
View
from
django.views.generic.base
import
TemplateView
from
django.db
import
transaction
from
django.views.generic.edit
import
(
CreateView
,
UpdateView
,
FormMixin
,
FormView
)
...
...
@@ -33,7 +35,7 @@ from common.utils import get_logger, get_object_or_none, is_uuid
from
..
import
forms
from
..models
import
User
,
UserGroup
from
..utils
import
AdminUserRequiredMixin
from
..signals
import
on_user_created
from
..signals
import
post_user_create
__all__
=
[
...
...
@@ -212,8 +214,10 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
# todo: need be patch, method to long
def
form_valid
(
self
,
form
):
file
=
form
.
cleaned_data
[
'file'
]
data
=
file
.
read
()
.
decode
(
'utf-8'
)
.
strip
(
codecs
.
BOM_UTF8
.
decode
(
'utf-8'
))
f
=
form
.
cleaned_data
[
'file'
]
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
)
reader
=
csv
.
reader
(
csv_file
)
csv_data
=
[
row
for
row
in
reader
]
...
...
@@ -252,15 +256,15 @@ class UserBulkImportView(AdminUserRequiredMixin, JSONResponseMixin, FormView):
else
:
continue
user_dict
[
k
]
=
v
user
=
get_object_or_none
(
User
,
id
=
id_
)
if
is_uuid
(
id_
)
else
None
user
=
get_object_or_none
(
User
,
id
=
id_
)
if
id_
and
is_uuid
(
id_
)
else
None
if
not
user
:
try
:
groups
=
user_dict
.
pop
(
'groups'
)
user
=
User
.
objects
.
create
(
**
user_dict
)
user
.
groups
.
set
(
groups
)
created
.
append
(
user_dict
[
'username'
])
on_user_created
.
send
(
self
.
__class__
,
user
=
user
)
with
transaction
.
atomic
():
groups
=
user_dict
.
pop
(
'groups'
)
user
=
User
.
objects
.
create
(
**
user_dict
)
user
.
groups
.
set
(
groups
)
created
.
append
(
user_dict
[
'username'
])
post_user_create
.
send
(
self
.
__class__
,
user
=
user
)
except
Exception
as
e
:
failed
.
append
(
'
%
s:
%
s'
%
(
user_dict
[
'username'
],
str
(
e
)))
else
:
...
...
@@ -309,7 +313,6 @@ class UserProfileView(LoginRequiredMixin, TemplateView):
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Users'
),
'action'
:
_
(
'Profile'
),
}
kwargs
.
update
(
context
)
...
...
docs/_static/img/structure.png
0 → 100644
View file @
8e09151a
29.1 KB
docs/index.rst
View file @
8e09151a
...
...
@@ -4,7 +4,7 @@
contain the root `toctree` directive.
Jumpserver 文档
====================
====================
==================
目录:
...
...
docs/intro.rst
0 → 100644
View file @
8e09151a
简介
============
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: 组件架构图
docs/user_guide.rst
View file @
8e09151a
用户使用文档
=============
==
=============
这部分给您介绍Jumpserver的用户使用方法。
这部分给您介绍Jumpserver的用户
管理模块的
使用方法。
.. toctree::
:maxdepth: 1
...
...
requirements/requirements.txt
View file @
8e09151a
...
...
@@ -56,8 +56,8 @@ uritemplate==3.0.0
urllib3==1.22
vine==1.1.4
gunicorn==19.7.1
https://github.com/celery/django-celery-beat/zipball/master#egg=django-celery-beat
#django_celery_beat==1.1.0
#
https://github.com/celery/django-celery-beat/zipball/master#egg=django-celery-beat
django_celery_beat==1.1.1
ephem==3.7.6.0
python-gssapi==0.6.4
jms-es-sdk
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment