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
f37b3316
Commit
f37b3316
authored
7 years ago
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
Merge with dev
parents
5bbad019
9dbf4983
Hide whitespace changes
Inline
Side-by-side
Showing
69 changed files
with
772 additions
and
467 deletions
+772
-467
README.md
README.md
+1
-30
api.py
apps/assets/api.py
+3
-5
hands.py
apps/assets/hands.py
+1
-1
label.py
apps/assets/models/label.py
+1
-1
user.py
apps/assets/models/user.py
+0
-1
serializers.py
apps/assets/serializers.py
+1
-11
admin_user_assets.html
apps/assets/templates/assets/admin_user_assets.html
+1
-1
asset_group_detail.html
apps/assets/templates/assets/asset_group_detail.html
+1
-1
asset_group_list.html
apps/assets/templates/assets/asset_group_list.html
+0
-4
cluster_assets.html
apps/assets/templates/assets/cluster_assets.html
+1
-1
label_list.html
apps/assets/templates/assets/label_list.html
+2
-5
system_user_asset.html
apps/assets/templates/assets/system_user_asset.html
+1
-1
cluster.py
apps/assets/views/cluster.py
+0
-5
api.py
apps/common/api.py
+0
-5
fields.py
apps/common/fields.py
+6
-5
forms.py
apps/common/forms.py
+38
-10
models.py
apps/common/models.py
+19
-6
basic_setting.html
apps/common/templates/common/basic_setting.html
+3
-0
email_setting.html
apps/common/templates/common/email_setting.html
+3
-0
ldap_setting.html
apps/common/templates/common/ldap_setting.html
+3
-0
terminal_setting.html
apps/common/templates/common/terminal_setting.html
+129
-0
view_urls.py
apps/common/urls/view_urls.py
+1
-0
views.py
apps/common/views.py
+35
-4
settings.py
apps/jumpserver/settings.py
+16
-3
django.mo
apps/locale/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/locale/zh/LC_MESSAGES/django.po
+214
-159
models.py
apps/ops/models.py
+1
-1
utils.py
apps/ops/utils.py
+3
-1
jumpserver.css
apps/static/css/jumpserver.css
+1
-1
admin.png
apps/static/img/avatar/admin.png
+0
-0
user.png
apps/static/img/avatar/user.png
+0
-0
logo-text.png
apps/static/img/logo-text.png
+0
-0
_footer.html
apps/templates/_footer.html
+2
-1
_header_bar.html
apps/templates/_header_bar.html
+6
-7
_user_profile.html
apps/templates/_user_profile.html
+2
-5
flash_message_standalone.html
apps/templates/flash_message_standalone.html
+1
-1
index.html
apps/templates/index.html
+1
-1
api.py
apps/terminal/api.py
+17
-4
__init__.py
apps/terminal/backends/__init__.py
+33
-3
base.py
apps/terminal/backends/command/base.py
+6
-0
db.py
apps/terminal/backends/command/db.py
+28
-8
es.py
apps/terminal/backends/command/es.py
+38
-0
models.py
apps/terminal/backends/command/models.py
+21
-0
multi.py
apps/terminal/backends/command/multi.py
+27
-0
forms.py
apps/terminal/forms.py
+13
-1
models.py
apps/terminal/models.py
+23
-0
serializers.py
apps/terminal/serializers.py
+3
-3
signals_handler.py
apps/terminal/signals_handler.py
+0
-4
terminal_modal_accept.html
apps/terminal/templates/terminal/terminal_modal_accept.html
+1
-0
terminal_update.html
apps/terminal/templates/terminal/terminal_update.html
+1
-0
terminal_tags.py
apps/terminal/templatetags/terminal_tags.py
+3
-4
api_urls.py
apps/terminal/urls/api_urls.py
+2
-1
command.py
apps/terminal/views/command.py
+3
-3
session.py
apps/terminal/views/session.py
+2
-2
api.py
apps/users/api.py
+20
-4
forms.py
apps/users/forms.py
+0
-1
hands.py
apps/users/hands.py
+1
-1
serializers.py
apps/users/serializers.py
+6
-0
_user.html
apps/users/templates/users/_user.html
+1
-7
forgot_password.html
apps/users/templates/users/forgot_password.html
+1
-1
login.html
apps/users/templates/users/login.html
+1
-1
reset_password.html
apps/users/templates/users/reset_password.html
+1
-1
user_detail.html
apps/users/templates/users/user_detail.html
+7
-6
user_list.html
apps/users/templates/users/user_list.html
+1
-1
api_urls.py
apps/users/urls/api_urls.py
+2
-0
utils.py
apps/users/utils.py
+4
-2
login.py
apps/users/views/login.py
+5
-2
install.md
docs/install.md
+1
-129
requirements.txt
requirements/requirements.txt
+3
-1
No files found.
README.md
View file @
f37b3316
...
...
@@ -26,36 +26,7 @@ Jumpserver是一款使用Python, Django开发的开源跳板机系统, 助力互
### Install 安装
1. 安装 Python3
略
2. 安装依赖
```
$ cd requirements && yum -y install $(cat rpm_requirements.txt) && pip install -r requirements.txt
```
3. 修改配置文件
```
$ cp config_example.py config.py
```
4. 修改表结构
```
$ cd apps && python manage.py makemigrations && python manage.py migrate
```
5. 运行
```
$ python run_server.py
```
6. 其它
整合luna,coco需要nginx来配合, 详见详细安装文档
[
详细安装
](
https://github.com/jumpserver/jumpserver/wiki/v0.5.0-%E5%9F%BA%E4%BA%8E-CentOS7
)
### Usage 使用
...
...
This diff is collapsed.
Click to expand it.
apps/assets/api.py
View file @
f37b3316
# ~*~ coding: utf-8 ~*~
# Copyright (C) 2014-201
7
Beijing DuiZhan Technology Co.,Ltd. All Rights Reserved.
# Copyright (C) 2014-201
8
Beijing DuiZhan Technology Co.,Ltd. All Rights Reserved.
#
# Licensed under the GNU General Public License v2.0 (the "License");
# you may not use this file except in compliance with the License.
...
...
@@ -87,7 +87,7 @@ class AssetGroupViewSet(CustomFilterMixin, BulkModelViewSet):
"""
Asset group api set, for add,delete,update,list,retrieve resource
"""
queryset
=
AssetGroup
.
objects
.
all
()
queryset
=
AssetGroup
.
objects
.
all
()
.
annotate
(
asset_count
=
Count
(
"assets"
))
serializer_class
=
serializers
.
AssetGroupSerializer
permission_classes
=
(
IsSuperUser
,)
...
...
@@ -298,9 +298,7 @@ class SystemUserTestConnectiveApi(generics.RetrieveAPIView):
class
LabelViewSet
(
BulkModelViewSet
):
queryset
=
Label
.
objects
.
annotate
(
asset_count
=
Count
(
"assets"
))
\
.
annotate
(
admin_user_count
=
Count
(
"adminuser"
))
\
.
annotate
(
system_user_count
=
Count
(
"systemuser"
))
queryset
=
Label
.
objects
.
annotate
(
asset_count
=
Count
(
"assets"
))
permission_classes
=
(
IsSuperUser
,)
serializer_class
=
serializers
.
LabelSerializer
...
...
This diff is collapsed.
Click to expand it.
apps/assets/hands.py
View file @
f37b3316
...
...
@@ -6,7 +6,7 @@
Other module of this app shouldn't connect with other app.
:copyright: (c) 2014-201
7
by Jumpserver Team.
:copyright: (c) 2014-201
8
by Jumpserver Team.
:license: GPL v2, see LICENSE for more details.
"""
...
...
This diff is collapsed.
Click to expand it.
apps/assets/models/label.py
View file @
f37b3316
...
...
@@ -16,7 +16,7 @@ class Label(models.Model):
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
name
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"Name"
))
value
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"Value"
))
category
=
models
.
CharField
(
max_length
=
128
,
choices
=
CATEGORY_CHOICES
,
verbose_name
=
_
(
"Category"
))
category
=
models
.
CharField
(
max_length
=
128
,
choices
=
CATEGORY_CHOICES
,
default
=
USER_CATEGORY
,
verbose_name
=
_
(
"Category"
))
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
"Is active"
))
comment
=
models
.
TextField
(
blank
=
True
,
null
=
True
,
verbose_name
=
_
(
"Comment"
))
date_created
=
models
.
DateTimeField
(
...
...
This diff is collapsed.
Click to expand it.
apps/assets/models/user.py
View file @
f37b3316
...
...
@@ -30,7 +30,6 @@ class AssetUser(models.Model):
_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'
))
labels
=
models
.
ManyToManyField
(
'assets.Label'
,
blank
=
True
,
verbose_name
=
_
(
"Labels"
))
comment
=
models
.
TextField
(
blank
=
True
,
verbose_name
=
_
(
'Comment'
))
date_created
=
models
.
DateTimeField
(
auto_now_add
=
True
)
date_updated
=
models
.
DateTimeField
(
auto_now
=
True
)
...
...
This diff is collapsed.
Click to expand it.
apps/assets/serializers.py
View file @
f37b3316
...
...
@@ -22,7 +22,7 @@ class AssetGroupSerializer(BulkSerializerMixin, serializers.ModelSerializer):
@staticmethod
def
get_assets_amount
(
obj
):
return
obj
.
asset
s
.
count
()
return
obj
.
asset
_count
class
AssetUpdateSystemUserSerializer
(
serializers
.
ModelSerializer
):
...
...
@@ -288,8 +288,6 @@ class MyAssetGroupGrantedSerializer(serializers.ModelSerializer):
class
LabelSerializer
(
serializers
.
ModelSerializer
):
asset_count
=
serializers
.
SerializerMethodField
()
admin_user_count
=
serializers
.
SerializerMethodField
()
system_user_count
=
serializers
.
SerializerMethodField
()
class
Meta
:
model
=
Label
...
...
@@ -300,14 +298,6 @@ class LabelSerializer(serializers.ModelSerializer):
def
get_asset_count
(
obj
):
return
obj
.
asset_count
@staticmethod
def
get_admin_user_count
(
obj
):
return
obj
.
admin_user_count
@staticmethod
def
get_system_user_count
(
obj
):
return
obj
.
system_user_count
def
get_field_names
(
self
,
declared_fields
,
info
):
fields
=
super
()
.
get_field_names
(
declared_fields
,
info
)
fields
.
extend
([
'get_category_display'
])
...
...
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/admin_user_assets.html
View file @
f37b3316
...
...
@@ -121,7 +121,7 @@ function initTable() {
{
data
:
"type"
},
{
data
:
"is_connective"
}],
op_html
:
$
(
'#actions'
).
html
()
};
jumpserver
.
initDataTable
(
options
);
jumpserver
.
init
ServerSide
DataTable
(
options
);
}
$
(
document
).
ready
(
function
()
{
...
...
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/asset_group_detail.html
View file @
f37b3316
...
...
@@ -184,7 +184,7 @@ function initTable() {
{
data
:
"get_type_display"
},
{
data
:
"is_connective"
},
{
data
:
"id"
}],
op_html
:
$
(
'#actions'
).
html
()
};
jumpserver
.
initDataTable
(
options
);
jumpserver
.
init
ServerSide
DataTable
(
options
);
}
...
...
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/asset_group_list.html
View file @
f37b3316
...
...
@@ -34,10 +34,6 @@ $(document).ready(function(){
var
detail_btn
=
'<a href="{% url "assets:asset-group-detail" pk=DEFAULT_PK %}">'
+
cellData
+
'</a>'
;
$
(
td
).
html
(
detail_btn
.
replace
(
'{{ DEFAULT_PK }}'
,
rowData
.
id
));
}},
{
targets
:
3
,
createdCell
:
function
(
td
,
cellData
)
{
var
innerHtml
=
cellData
.
length
>
30
?
cellData
.
substring
(
0
,
30
)
+
'...'
:
cellData
;
$
(
td
).
html
(
'<a href="javascript:void(0);" data-toggle="tooltip" title="'
+
cellData
+
'">'
+
innerHtml
+
'</a>'
);
}},
{
targets
:
4
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
update_btn
=
'<a href="{% url "assets:asset-group-update" pk=DEFAULT_PK %}" class="btn btn-xs m-l-xs btn-info">{% trans "Update" %}</a>'
.
replace
(
'{{ DEFAULT_PK }}'
,
cellData
);
var
del_btn
=
'<a class="btn btn-xs btn-danger m-l-xs btn_asset_group_delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'
.
replace
(
'{{ DEFAULT_PK }}'
,
cellData
);
...
...
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/cluster_assets.html
View file @
f37b3316
...
...
@@ -176,7 +176,7 @@ function initTable() {
{
data
:
"get_type_display"
},
{
data
:
"is_connective"
},
{
data
:
"id"
}],
op_html
:
$
(
'#actions'
).
html
()
};
jumpserver
.
initDataTable
(
options
);
jumpserver
.
init
ServerSide
DataTable
(
options
);
}
...
...
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/label_list.html
View file @
f37b3316
...
...
@@ -14,8 +14,6 @@
<th
class=
"text-center"
>
{% trans 'Name' %}
</th>
<th
class=
"text-center"
>
{% trans 'Value' %}
</th>
<th
class=
"text-center"
>
{% trans 'Asset' %}
</th>
<th
class=
"text-center"
>
{% trans 'Admin user' %}
</th>
<th
class=
"text-center"
>
{% trans 'System user' %}
</th>
<th
class=
"text-center"
>
{% trans 'Action' %}
</th>
</tr>
</thead>
...
...
@@ -36,7 +34,7 @@ function initTable() {
$
(
td
).
html
(
detail_btn
.
replace
(
'{{ DEFAULT_PK }}'
,
rowData
.
id
));
}},
{
targets
:
6
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
{
targets
:
4
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
update_btn
=
'<a href="{% url "assets:cluster-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'
.
replace
(
'{{ DEFAULT_PK }}'
,
cellData
);
var
del_btn
=
'<a class="btn btn-xs btn-danger m-l-xs btn_cluster_delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'
.
replace
(
'{{ DEFAULT_PK }}'
,
cellData
);
$
(
td
).
html
(
update_btn
+
del_btn
)
...
...
@@ -44,8 +42,7 @@ function initTable() {
ajax_url
:
'{% url "api-assets:label-list" %}?sort=name'
,
columns
:
[
{
data
:
"id"
},
{
data
:
"name"
},
{
data
:
"value"
},
{
data
:
"asset_count"
},
{
data
:
"admin_user_count"
},
{
data
:
"system_user_count"
},
{
data
:
"id"
}
{
data
:
"asset_count"
},
{
data
:
"id"
}
],
op_html
:
$
(
'#actions'
).
html
()
};
...
...
This diff is collapsed.
Click to expand it.
apps/assets/templates/assets/system_user_asset.html
View file @
f37b3316
...
...
@@ -121,7 +121,7 @@ function initAssetsTable() {
columns
:
[{
data
:
"hostname"
},
{
data
:
"ip"
},
{
data
:
"port"
},
{
data
:
"hostname"
}],
op_html
:
$
(
'#actions'
).
html
()
};
jumpserver
.
initDataTable
(
options
);
jumpserver
.
init
ServerSide
DataTable
(
options
);
}
$
(
document
).
ready
(
function
()
{
...
...
This diff is collapsed.
Click to expand it.
apps/assets/views/cluster.py
View file @
f37b3316
...
...
@@ -60,11 +60,6 @@ class ClusterUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView)
success_url
=
reverse_lazy
(
'assets:cluster-list'
)
success_message
=
update_success_msg
def
form_valid
(
self
,
form
):
cluster
=
form
.
save
(
commit
=
False
)
cluster
.
save
()
return
super
()
.
form_valid
(
form
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'assets'
),
...
...
This diff is collapsed.
Click to expand it.
apps/common/api.py
View file @
f37b3316
...
...
@@ -63,8 +63,6 @@ class LDAPTestingAPI(APIView):
search_filter
=
serializer
.
validated_data
[
"AUTH_LDAP_SEARCH_FILTER"
]
attr_map
=
serializer
.
validated_data
[
"AUTH_LDAP_USER_ATTR_MAP"
]
print
(
serializer
.
validated_data
)
try
:
attr_map
=
json
.
loads
(
attr_map
)
except
json
.
JSONDecodeError
:
...
...
@@ -77,9 +75,6 @@ class LDAPTestingAPI(APIView):
except
Exception
as
e
:
return
Response
({
"error"
:
str
(
e
)},
status
=
401
)
print
(
search_ou
)
print
(
search_filter
%
({
"user"
:
"*"
}))
print
(
attr_map
.
values
())
ok
=
conn
.
search
(
search_ou
,
search_filter
%
({
"user"
:
"*"
}),
attributes
=
list
(
attr_map
.
values
()))
if
not
ok
:
...
...
This diff is collapsed.
Click to expand it.
apps/common/fields.py
View file @
f37b3316
...
...
@@ -5,6 +5,7 @@ import json
from
django
import
forms
from
django.utils
import
six
from
django.core.exceptions
import
ValidationError
from
django.utils.translation
import
ugettext
as
_
class
DictField
(
forms
.
Field
):
...
...
@@ -18,16 +19,16 @@ class DictField(forms.Field):
# we don't need to handle that explicitly.
if
isinstance
(
value
,
six
.
string_types
):
try
:
print
(
value
)
value
=
json
.
loads
(
value
)
return
value
except
json
.
JSONDecodeError
:
pass
value
=
{}
return
value
return
ValidationError
(
_
(
"Not a valid json"
))
else
:
return
ValidationError
(
_
(
"Not a string type"
))
def
validate
(
self
,
value
):
print
(
value
)
if
isinstance
(
value
,
ValidationError
):
raise
value
if
not
value
and
self
.
required
:
raise
ValidationError
(
self
.
error_messages
[
'required'
],
code
=
'required'
)
...
...
This diff is collapsed.
Click to expand it.
apps/common/forms.py
View file @
f37b3316
...
...
@@ -4,7 +4,9 @@ import json
from
django
import
forms
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.html
import
escape
from
django.db
import
transaction
from
django.conf
import
settings
from
.models
import
Setting
from
.fields
import
DictField
...
...
@@ -24,34 +26,38 @@ def to_form_value(value):
data
=
value
return
data
except
json
.
JSONDecodeError
:
return
''
return
""
class
BaseForm
(
forms
.
Form
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
settings
=
Setting
.
objects
.
all
()
db_
settings
=
Setting
.
objects
.
all
()
for
name
,
field
in
self
.
fields
.
items
():
db_value
=
getattr
(
settings
,
name
)
.
value
if
db_value
:
db_value
=
getattr
(
db_settings
,
name
)
.
value
django_value
=
getattr
(
settings
,
name
)
if
hasattr
(
settings
,
name
)
else
None
if
db_value
is
False
or
db_value
:
field
.
initial
=
to_form_value
(
db_value
)
elif
django_value
is
False
or
django_value
:
field
.
initial
=
to_form_value
(
to_model_value
(
django_value
))
def
save
(
self
):
def
save
(
self
,
category
=
"default"
):
if
not
self
.
is_bound
:
raise
ValueError
(
"Form is not bound"
)
settings
=
Setting
.
objects
.
all
()
db_
settings
=
Setting
.
objects
.
all
()
if
self
.
is_valid
():
with
transaction
.
atomic
():
for
name
,
value
in
self
.
cleaned_data
.
items
():
field
=
self
.
fields
[
name
]
if
isinstance
(
field
.
widget
,
forms
.
PasswordInput
)
and
not
value
:
continue
if
value
==
to_form_value
(
getattr
(
settings
,
name
)
.
value
):
if
value
==
to_form_value
(
getattr
(
db_
settings
,
name
)
.
value
):
continue
defaults
=
{
'name'
:
name
,
'category'
:
category
,
'value'
:
to_model_value
(
value
)
}
Setting
.
objects
.
update_or_create
(
defaults
=
defaults
,
name
=
name
)
...
...
@@ -72,9 +78,6 @@ class BasicSettingForm(BaseForm):
max_length
=
1024
,
label
=
_
(
"Email Subject Prefix"
),
initial
=
"[Jumpserver] "
)
AUTH_LDAP
=
forms
.
BooleanField
(
label
=
_
(
"Enable LDAP Auth"
),
initial
=
False
,
required
=
False
)
class
EmailSettingForm
(
BaseForm
):
...
...
@@ -129,3 +132,28 @@ class LDAPSettingForm(BaseForm):
AUTH_LDAP_START_TLS
=
forms
.
BooleanField
(
label
=
_
(
"Use SSL"
),
initial
=
False
,
required
=
False
)
class
TerminalSettingForm
(
BaseForm
):
SORT_BY_CHOICES
=
(
(
'hostname'
,
_
(
'Hostname'
)),
(
'ip'
,
_
(
'IP'
)),
)
TERMINAL_ASSET_LIST_SORT_BY
=
forms
.
ChoiceField
(
choices
=
SORT_BY_CHOICES
,
initial
=
'hostname'
,
label
=
_
(
"List sort by"
)
)
TERMINAL_HEARTBEAT_INTERVAL
=
forms
.
IntegerField
(
initial
=
5
,
label
=
_
(
"Heartbeat interval"
),
help_text
=
_
(
"Units: seconds"
)
)
TERMINAL_PASSWORD_AUTH
=
forms
.
BooleanField
(
initial
=
True
,
required
=
False
,
label
=
_
(
"Password auth"
)
)
TERMINAL_PUBLIC_KEY_AUTH
=
forms
.
BooleanField
(
initial
=
True
,
required
=
False
,
label
=
_
(
"Public key auth"
)
)
TERMINAL_COMMAND_STORAGE
=
DictField
(
label
=
_
(
"Command storage"
),
help_text
=
_
(
"Set terminal storage setting, `default` is the using as default,"
"You can set other storage and some terminal using"
)
)
This diff is collapsed.
Click to expand it.
apps/common/models.py
View file @
f37b3316
...
...
@@ -2,6 +2,7 @@ import json
import
ldap
from
django.db
import
models
from
django.db.utils
import
ProgrammingError
,
OperationalError
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.conf
import
settings
from
django_auth_ldap.config
import
LDAPSearch
...
...
@@ -24,6 +25,7 @@ class SettingManager(models.Manager):
class
Setting
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
"Name"
))
value
=
models
.
TextField
(
verbose_name
=
_
(
"Value"
))
category
=
models
.
CharField
(
max_length
=
128
,
default
=
"default"
)
enabled
=
models
.
BooleanField
(
verbose_name
=
_
(
"Enabled"
),
default
=
True
)
comment
=
models
.
TextField
(
verbose_name
=
_
(
"Comment"
))
...
...
@@ -33,17 +35,28 @@ class Setting(models.Model):
return
self
.
name
@property
def
value_
(
self
):
def
cleaned_value
(
self
):
try
:
return
json
.
loads
(
self
.
value
)
except
json
.
JSONDecodeError
:
return
None
@cleaned_value.setter
def
cleaned_value
(
self
,
item
):
try
:
v
=
json
.
dumps
(
item
)
self
.
value
=
v
except
json
.
JSONDecodeError
as
e
:
raise
ValueError
(
"Json dump error: {}"
.
format
(
str
(
e
)))
@classmethod
def
refresh_all_settings
(
cls
):
settings_list
=
cls
.
objects
.
all
()
for
setting
in
settings_list
:
setting
.
refresh_setting
()
try
:
settings_list
=
cls
.
objects
.
all
()
for
setting
in
settings_list
:
setting
.
refresh_setting
()
except
(
ProgrammingError
,
OperationalError
):
pass
def
refresh_setting
(
self
):
try
:
...
...
@@ -53,9 +66,9 @@ class Setting(models.Model):
setattr
(
settings
,
self
.
name
,
value
)
if
self
.
name
==
"AUTH_LDAP"
:
if
self
.
value_
and
settings
.
AUTH_LDAP_BACKEND
not
in
settings
.
AUTHENTICATION_BACKENDS
:
if
self
.
cleaned_value
and
settings
.
AUTH_LDAP_BACKEND
not
in
settings
.
AUTHENTICATION_BACKENDS
:
settings
.
AUTHENTICATION_BACKENDS
.
insert
(
0
,
settings
.
AUTH_LDAP_BACKEND
)
elif
not
self
.
value_
and
settings
.
AUTH_LDAP_BACKEND
in
settings
.
AUTHENTICATION_BACKENDS
:
elif
not
self
.
cleaned_value
and
settings
.
AUTH_LDAP_BACKEND
in
settings
.
AUTHENTICATION_BACKENDS
:
settings
.
AUTHENTICATION_BACKENDS
.
remove
(
settings
.
AUTH_LDAP_BACKEND
)
if
self
.
name
==
"AUTH_LDAP_SEARCH_FILTER"
:
...
...
This diff is collapsed.
Click to expand it.
apps/common/templates/common/basic_setting.html
View file @
f37b3316
...
...
@@ -20,6 +20,9 @@
<li>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
This diff is collapsed.
Click to expand it.
apps/common/templates/common/email_setting.html
View file @
f37b3316
...
...
@@ -20,6 +20,9 @@
<li>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
This diff is collapsed.
Click to expand it.
apps/common/templates/common/ldap_setting.html
View file @
f37b3316
...
...
@@ -20,6 +20,9 @@
<li
class=
"active"
>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
...
...
This diff is collapsed.
Click to expand it.
apps/common/templates/common/terminal_setting.html
0 → 100644
View file @
f37b3316
{% extends 'base.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% load common_tags %}
{% block content %}
<div
class=
"wrapper wrapper-content animated fadeInRight"
>
<div
class=
"row"
>
<div
class=
"col-sm-12"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"panel-options"
>
<ul
class=
"nav nav-tabs"
>
<li>
<a
href=
"{% url 'settings:basic-setting' %}"
class=
"text-center"
><i
class=
"fa fa-cubes"
></i>
{% trans 'Basic setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:email-setting' %}"
class=
"text-center"
><i
class=
"fa fa-envelope"
></i>
{% trans 'Email setting' %}
</a>
</li>
<li>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
<li
class=
"active"
>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
<div
class=
"col-sm-12"
style=
"padding-left:0"
>
<div
class=
"ibox-content"
style=
"border-width: 0;padding-top: 40px;"
>
<form
action=
""
method=
"post"
class=
"form-horizontal"
>
{% if form.non_field_errors %}
<div
class=
"alert alert-danger"
>
{{ form.non_field_errors }}
</div>
{% endif %}
{% csrf_token %}
<h3>
{% trans "Basic setting" %}
</h3>
{% for field in form %}
{% if not field.field|is_bool_field %}
{% bootstrap_field field layout="horizontal" %}
{% else %}
<div
class=
"form-group"
>
<label
for=
"{{ field.id_for_label }}"
class=
"col-sm-2 control-label"
>
{{ field.label }}
</label>
<div
class=
"col-sm-8"
>
<div
class=
"col-sm-1"
>
{{ field }}
</div>
<div
class=
"col-sm-9"
>
<span
class=
"help-block"
>
{{ field.help_text }}
</span>
</div>
</div>
</div>
{% endif %}
{% endfor %}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans "Command storage" %}
</h3>
<table
class=
"table table-hover "
id=
"task-history-list-table"
>
<thead>
<tr>
<th>
{% trans 'Name' %}
</th>
<th>
{% trans 'Type' %}
</th>
</tr>
</thead>
<tbody>
{% for name, setting in command_storage.items %}
<tr>
<td>
{{ name }}
</td>
<td>
{{ setting.TYPE }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{#
<button
class=
"btn btn-default btn-circle btn-add-command-storage"
data-toggle=
"modal"
data-target=
"#add_command_storage_model"
tabindex=
"0"
type=
"button"
><i
class=
"fa fa-plus"
></i></button>
#}
{#
<div
class=
"hr-line-dashed"
></div>
#}
{#
<h3>
{% trans "Replay storage" %}
</h3>
#}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"form-group"
>
<div
class=
"col-sm-4 col-sm-offset-2"
>
<button
class=
"btn btn-default"
type=
"reset"
>
{% trans 'Reset' %}
</button>
<button
id=
"submit_button"
class=
"btn btn-primary"
type=
"submit"
>
{% trans 'Submit' %}
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
$
(
document
).
ready
(
function
()
{
})
.
on
(
"click"
,
".btn-test"
,
function
()
{
var
data
=
{};
var
form
=
$
(
"form"
).
serializeArray
();
$
.
each
(
form
,
function
(
i
,
field
)
{
data
[
field
.
name
]
=
field
.
value
;
});
var
the_url
=
"{% url 'api-common:ldap-testing' %}"
;
function
error
(
message
)
{
toastr
.
error
(
message
)
}
function
success
(
message
)
{
toastr
.
success
(
message
.
msg
)
}
APIUpdateAttr
({
url
:
the_url
,
body
:
JSON
.
stringify
(
data
),
method
:
"POST"
,
flash_message
:
false
,
success
:
success
,
error
:
error
});
})
.
on
(
'click'
,
''
,
function
()
{
})
</script>
{% endblock %}
This diff is collapsed.
Click to expand it.
apps/common/urls/view_urls.py
View file @
f37b3316
...
...
@@ -10,4 +10,5 @@ urlpatterns = [
url
(
r'^$'
,
views
.
BasicSettingView
.
as_view
(),
name
=
'basic-setting'
),
url
(
r'^email/$'
,
views
.
EmailSettingView
.
as_view
(),
name
=
'email-setting'
),
url
(
r'^ldap/$'
,
views
.
LDAPSettingView
.
as_view
(),
name
=
'ldap-setting'
),
url
(
r'^terminal/$'
,
views
.
TerminalSettingView
.
as_view
(),
name
=
'terminal-setting'
),
]
This diff is collapsed.
Click to expand it.
apps/common/views.py
View file @
f37b3316
from
django.views.generic
import
View
,
TemplateView
from
django.views.generic
import
TemplateView
from
django.shortcuts
import
render
,
redirect
from
django.contrib
import
messages
from
django.utils.translation
import
ugettext
as
_
from
django.conf
import
settings
from
.forms
import
EmailSettingForm
,
LDAPSettingForm
,
BasicSettingForm
from
.forms
import
EmailSettingForm
,
LDAPSettingForm
,
BasicSettingForm
,
\
TerminalSettingForm
from
.models
import
Setting
from
.mixins
import
AdminUserRequiredMixin
from
.signals
import
ldap_auth_enable
...
...
@@ -25,8 +28,6 @@ class BasicSettingView(AdminUserRequiredMixin, TemplateView):
form
=
self
.
form_class
(
request
.
POST
)
if
form
.
is_valid
():
form
.
save
()
if
"AUTH_LDAP"
in
form
.
cleaned_data
:
ldap_auth_enable
.
send
(
form
.
cleaned_data
[
"AUTH_LDAP"
])
msg
=
_
(
"Update setting successfully, please restart program"
)
messages
.
success
(
request
,
msg
)
return
redirect
(
'settings:basic-setting'
)
...
...
@@ -79,6 +80,8 @@ class LDAPSettingView(AdminUserRequiredMixin, TemplateView):
form
=
self
.
form_class
(
request
.
POST
)
if
form
.
is_valid
():
form
.
save
()
if
"AUTH_LDAP"
in
form
.
cleaned_data
:
ldap_auth_enable
.
send
(
form
.
cleaned_data
[
"AUTH_LDAP"
])
msg
=
_
(
"Update setting successfully, please restart program"
)
messages
.
success
(
request
,
msg
)
return
redirect
(
'settings:ldap-setting'
)
...
...
@@ -86,3 +89,31 @@ class LDAPSettingView(AdminUserRequiredMixin, TemplateView):
context
=
self
.
get_context_data
()
context
.
update
({
"form"
:
form
})
return
render
(
request
,
self
.
template_name
,
context
)
class
TerminalSettingView
(
AdminUserRequiredMixin
,
TemplateView
):
form_class
=
TerminalSettingForm
template_name
=
"common/terminal_setting.html"
def
get_context_data
(
self
,
**
kwargs
):
command_storage
=
settings
.
TERMINAL_COMMAND_STORAGE
context
=
{
'app'
:
_
(
'Settings'
),
'action'
:
_
(
'Terminal setting'
),
'form'
:
self
.
form_class
(),
'command_storage'
:
command_storage
,
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
def
post
(
self
,
request
):
form
=
self
.
form_class
(
request
.
POST
)
if
form
.
is_valid
():
form
.
save
()
msg
=
_
(
"Update setting successfully, please restart program"
)
messages
.
success
(
request
,
msg
)
return
redirect
(
'settings:terminal-setting'
)
else
:
context
=
self
.
get_context_data
()
context
.
update
({
"form"
:
form
})
return
render
(
request
,
self
.
template_name
,
context
)
This diff is collapsed.
Click to expand it.
apps/jumpserver/settings.py
View file @
f37b3316
...
...
@@ -274,7 +274,7 @@ EMAIL_HOST_USER = CONFIG.EMAIL_HOST_USER
EMAIL_HOST_PASSWORD
=
CONFIG
.
EMAIL_HOST_PASSWORD
EMAIL_USE_SSL
=
CONFIG
.
EMAIL_USE_SSL
EMAIL_USE_TLS
=
CONFIG
.
EMAIL_USE_TLS
EMAIL_SUBJECT_PREFIX
=
CONFIG
.
EMAIL_SUBJECT_PREFIX
EMAIL_SUBJECT_PREFIX
=
CONFIG
.
EMAIL_SUBJECT_PREFIX
or
''
REST_FRAMEWORK
=
{
# Use Django's standard `django.contrib.auth` permissions,
...
...
@@ -298,7 +298,7 @@ REST_FRAMEWORK = {
'DATETIME_FORMAT'
:
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S
%
z'
,
'DATETIME_INPUT_FORMATS'
:
[
'
%
Y-
%
m-
%
d
%
H:
%
M:
%
S
%
z'
],
# 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE'
:
15
#
'PAGE_SIZE': 15
}
AUTHENTICATION_BACKENDS
=
[
...
...
@@ -373,7 +373,20 @@ CAPTCHA_FOREGROUND_COLOR = '#001100'
CAPTCHA_NOISE_FUNCTIONS
=
(
'captcha.helpers.noise_dots'
,)
CAPTCHA_TEST_MODE
=
CONFIG
.
CAPTCHA_TEST_MODE
COMMAND_STORAGE_BACKEND
=
'terminal.backends.command.db'
COMMAND_STORAGE
=
{
'ENGINE'
:
'terminal.backends.command.db'
,
}
TERMINAL_COMMAND_STORAGE
=
{
"default"
:
{
"TYPE"
:
"server"
,
},
# 'ali-es': {
# 'TYPE': 'elasticsearch',
# 'HOSTS': ['http://elastic:changeme@localhost:9200'],
# },
}
# Django bootstrap3 setting, more see http://django-bootstrap3.readthedocs.io/en/latest/settings.html
BOOTSTRAP3
=
{
...
...
This diff is collapsed.
Click to expand it.
apps/locale/zh/LC_MESSAGES/django.mo
View file @
f37b3316
No preview for this file type
This diff is collapsed.
Click to expand it.
apps/locale/zh/LC_MESSAGES/django.po
View file @
f37b3316
...
...
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Jumpserver 0.3.3\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-01-
12 18:51
+0800\n"
"POT-Creation-Date: 2018-01-
23 11:56
+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"
...
...
@@ -18,7 +18,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
#: assets/forms.py:23 assets/forms.py:53 assets/forms.py:99 perms/forms.py:37
#: perms/templates/perms/asset_permission_asset.html:116 users/forms.py:24
6
#: perms/templates/perms/asset_permission_asset.html:116 users/forms.py:24
5
msgid "Select asset groups"
msgstr "选择资产组"
...
...
@@ -44,7 +44,7 @@ msgstr "默认使用管理用户"
#: assets/forms.py:76 assets/forms.py:81 assets/forms.py:127
#: assets/templates/assets/asset_group_detail.html:75 perms/forms.py:34
#: perms/templates/perms/asset_permission_asset.html:88 users/forms.py:24
3
#: perms/templates/perms/asset_permission_asset.html:88 users/forms.py:24
2
msgid "Select assets"
msgstr "选择资产"
...
...
@@ -66,7 +66,7 @@ msgstr "端口"
#: assets/templates/assets/system_user_list.html:26 perms/models.py:17
#: perms/templates/perms/asset_permission_create_update.html:40
#: perms/templates/perms/asset_permission_list.html:28 templates/_nav.html:22
#: terminal/backends/command/models.py:11 terminal/models.py:
93
#: terminal/backends/command/models.py:11 terminal/models.py:
116
#: terminal/templates/terminal/command_list.html:40
#: terminal/templates/terminal/command_list.html:73
#: terminal/templates/terminal/session_list.html:41
...
...
@@ -77,7 +77,7 @@ msgid "Asset"
msgstr "资产"
#: assets/forms.py:161 perms/forms.py:40
#: perms/templates/perms/asset_permission_detail.html:144 users/forms.py:24
9
#: perms/templates/perms/asset_permission_detail.html:144 users/forms.py:24
8
msgid "Select system users"
msgstr "选择系统用户"
...
...
@@ -99,14 +99,15 @@ msgstr "选择的系统用户将会在该集群资产上创建"
#: assets/templates/assets/cluster_detail.html:57
#: assets/templates/assets/cluster_list.html:19
#: assets/templates/assets/system_user_detail.html:58
#: assets/templates/assets/system_user_list.html:24 common/models.py:25
#: ops/models.py:31 ops/templates/ops/task_detail.html:56
#: ops/templates/ops/task_list.html:34 perms/models.py:14
#: assets/templates/assets/system_user_list.html:24 common/models.py:26
#: common/templates/common/terminal_setting.html:62 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_create_update.html:33
#: perms/templates/perms/asset_permission_detail.html:62
#: perms/templates/perms/asset_permission_list.html:25
#: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:1
4
#: terminal/models.py:1
18
terminal/templates/terminal/terminal_detail.html:43
#: perms/templates/perms/asset_permission_user.html:54 terminal/models.py:1
5
#: terminal/models.py:1
41
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:62
...
...
@@ -126,10 +127,10 @@ msgstr "集群级别管理用户"
#: assets/forms.py:200
msgid "Password or private key password"
msgstr "密码或秘钥
不合法
"
msgstr "密码或秘钥
密码
"
#: assets/forms.py:201 assets/forms.py:262 assets/models/user.py:30
#: common/forms.py:11
0
users/forms.py:16 users/forms.py:24
#: common/forms.py:11
3
users/forms.py:16 users/forms.py:24
#: users/templates/users/login.html:56
#: users/templates/users/reset_password.html:52
#: users/templates/users/user_create.html:11
...
...
@@ -239,7 +240,7 @@ msgstr "测试环境"
#: assets/templates/assets/asset_list.html:31
#: assets/templates/assets/cluster_assets.html:52
#: assets/templates/assets/system_user_asset.html:53
#: assets/templates/assets/user_asset_list.html:20
#: assets/templates/assets/user_asset_list.html:20
common/forms.py:140
#: perms/templates/perms/asset_permission_asset.html:55
#: users/templates/users/login_log_list.html:52
#: users/templates/users/user_granted_asset.html:49
...
...
@@ -253,7 +254,7 @@ msgstr "IP"
#: assets/templates/assets/asset_list.html:30
#: assets/templates/assets/cluster_assets.html:51
#: assets/templates/assets/system_user_asset.html:52
#: assets/templates/assets/user_asset_list.html:19
#: assets/templates/assets/user_asset_list.html:19
common/forms.py:139
#: perms/templates/perms/asset_permission_asset.html:54
#: users/templates/users/user_granted_asset.html:48
#: users/templates/users/user_group_granted_asset.html:49
...
...
@@ -400,9 +401,9 @@ msgstr "创建日期"
#: assets/templates/assets/asset_group_list.html:17
#: assets/templates/assets/cluster_detail.html:97
#: assets/templates/assets/system_user_detail.html:100
#: assets/templates/assets/system_user_list.html:30 common/models.py:
28
#: assets/templates/assets/system_user_list.html:30 common/models.py:
30
#: ops/models.py:37 perms/models.py:24
#: perms/templates/perms/asset_permission_detail.html:98 terminal/models.py:2
2
#: perms/templates/perms/asset_permission_detail.html:98 terminal/models.py:2
5
#: terminal/templates/terminal/terminal_detail.html:63 users/models/group.py:15
#: users/models/user.py:47 users/templates/users/user_detail.html:110
#: users/templates/users/user_group_detail.html:67
...
...
@@ -494,7 +495,7 @@ msgstr "Shell"
#: assets/models/user.py:269 perms/models.py:19
#: perms/templates/perms/asset_permission_detail.html:136
#: perms/templates/perms/asset_permission_list.html:30 templates/_nav.html:26
#: terminal/backends/command/models.py:12 terminal/models.py:
94
#: terminal/backends/command/models.py:12 terminal/models.py:
117
#: terminal/templates/terminal/command_list.html:48
#: terminal/templates/terminal/command_list.html:74
#: terminal/templates/terminal/session_list.html:49
...
...
@@ -576,9 +577,9 @@ msgstr "仅修改你需要更新的字段"
#: assets/views/admin_user.py:106 assets/views/asset.py:48
#: assets/views/asset.py:61 assets/views/asset.py:84 assets/views/asset.py:144
#: assets/views/asset.py:161 assets/views/asset.py:185
#: assets/views/cluster.py:26 assets/views/cluster.py:8
5
#: assets/views/cluster.py:
102 assets/views/group.py:34
#: assets/views/group.py:
52 assets/views/group.py:
69 assets/views/group.py:87
#: assets/views/cluster.py:26 assets/views/cluster.py:8
0
#: assets/views/cluster.py:
97 assets/views/group.py:34 assets/views/group.py:52
#: assets/views/group.py:69 assets/views/group.py:87
#: assets/views/system_user.py:28 assets/views/system_user.py:44
#: assets/views/system_user.py:60 assets/views/system_user.py:75
#: templates/_nav.html:19
...
...
@@ -650,7 +651,7 @@ msgstr "自动生成秘钥"
#: assets/templates/assets/asset_update.html:47
#: assets/templates/assets/cluster_create_update.html:46
#: perms/templates/perms/asset_permission_create_update.html:45
#: terminal/templates/terminal/terminal_update.html:4
0
#: terminal/templates/terminal/terminal_update.html:4
1
msgid "Other"
msgstr "其它"
...
...
@@ -661,12 +662,13 @@ msgstr "其它"
#: assets/templates/assets/asset_group_create.html:16
#: assets/templates/assets/asset_update.html:55
#: assets/templates/assets/cluster_create_update.html:54
#: common/templates/common/basic_setting.html:56
#: common/templates/common/email_setting.html:56
#: common/templates/common/ldap_setting.html:56
#: 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:82
#: perms/templates/perms/asset_permission_create_update.html:67
#: terminal/templates/terminal/terminal_update.html:4
5
#: users/templates/users/_user.html:4
9
#: terminal/templates/terminal/terminal_update.html:4
6
#: users/templates/users/_user.html:4
3
#: users/templates/users/user_bulk_update.html:23
#: users/templates/users/user_password_update.html:58
#: users/templates/users/user_profile.html:139
...
...
@@ -681,15 +683,16 @@ msgstr "重置"
#: assets/templates/assets/asset_bulk_update.html:24
#: assets/templates/assets/asset_create.html:41
#: assets/templates/assets/asset_group_create.html:17
#: assets/templates/assets/asset_list.html:5
5
#: assets/templates/assets/asset_list.html:5
3
#: assets/templates/assets/asset_update.html:56
#: assets/templates/assets/cluster_create_update.html:55
#: common/templates/common/basic_setting.html:57
#: common/templates/common/email_setting.html:57
#: common/templates/common/ldap_setting.html:57
#: 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:83
#: perms/templates/perms/asset_permission_create_update.html:68
#: terminal/templates/terminal/terminal_update.html:4
6
#: users/templates/users/_user.html:
50
#: terminal/templates/terminal/terminal_update.html:4
7
#: users/templates/users/_user.html:
44
#: users/templates/users/first_login.html:62
#: users/templates/users/forgot_password.html:44
#: users/templates/users/user_bulk_update.html:24
...
...
@@ -726,8 +729,8 @@ msgstr "资产列表"
#: assets/templates/assets/asset_detail.html:24
#: assets/templates/assets/asset_group_detail.html:18
#: assets/templates/assets/asset_group_detail.html:177
#: assets/templates/assets/asset_group_list.html:
42
#: assets/templates/assets/asset_list.html:9
5
#: assets/templates/assets/asset_group_list.html:
38
#: assets/templates/assets/asset_list.html:9
8
#: assets/templates/assets/cluster_assets.html:170
#: assets/templates/assets/cluster_detail.html:25
#: assets/templates/assets/cluster_list.html:43
...
...
@@ -750,8 +753,8 @@ msgstr "更新"
#: assets/templates/assets/admin_user_list.html:84
#: assets/templates/assets/asset_detail.html:28
#: assets/templates/assets/asset_group_detail.html:22
#: assets/templates/assets/asset_group_list.html:
43
#: assets/templates/assets/asset_list.html:9
6
#: assets/templates/assets/asset_group_list.html:
39
#: assets/templates/assets/asset_list.html:9
9
#: assets/templates/assets/cluster_detail.html:29
#: assets/templates/assets/cluster_list.html:44
#: assets/templates/assets/system_user_detail.html:30
...
...
@@ -776,9 +779,9 @@ msgstr "资产列表"
#: assets/templates/assets/admin_user_assets.html:62
#: assets/templates/assets/asset_group_detail.html:53
#: assets/templates/assets/asset_list.html:34
#: assets/templates/assets/cluster_assets.html:54
#: assets/templates/assets/user_asset_list.html:22
#: common/templates/common/terminal_setting.html:63
#: users/templates/users/login_log_list.html:50
msgid "Type"
msgstr "类型"
...
...
@@ -786,7 +789,7 @@ msgstr "类型"
#: assets/templates/assets/admin_user_assets.html:63
#: assets/templates/assets/admin_user_list.html:25
#: assets/templates/assets/asset_detail.html:376
#: assets/templates/assets/asset_list.html:3
8
#: assets/templates/assets/asset_list.html:3
6
#: assets/templates/assets/system_user_asset.html:55
#: assets/templates/assets/system_user_list.html:27
msgid "Reachable"
...
...
@@ -827,8 +830,8 @@ msgstr "使用集群管理用户"
#: assets/templates/assets/admin_user_detail.html:101
#: assets/templates/assets/asset_detail.html:230
#: assets/templates/assets/asset_group_list.html:8
5
#: assets/templates/assets/asset_list.html:2
14
#: assets/templates/assets/asset_group_list.html:8
1
#: assets/templates/assets/asset_list.html:2
20
#: assets/templates/assets/cluster_assets.html:104
#: assets/templates/assets/cluster_list.html:89
#: assets/templates/assets/system_user_detail.html:164
...
...
@@ -859,7 +862,7 @@ msgstr "比例"
#: assets/templates/assets/admin_user_list.html:29
#: assets/templates/assets/asset_group_detail.html:55
#: assets/templates/assets/asset_group_list.html:18
#: assets/templates/assets/asset_list.html:3
9
#: assets/templates/assets/asset_list.html:3
7
#: assets/templates/assets/cluster_assets.html:56
#: assets/templates/assets/cluster_list.html:23
#: assets/templates/assets/system_user_list.html:31
...
...
@@ -879,7 +882,7 @@ msgid "Group"
msgstr "组"
#: assets/templates/assets/asset_detail.html:20 assets/views/asset.py:186
#: assets/views/cluster.py:
103
#: assets/views/cluster.py:
98
msgid "Asset detail"
msgstr "资产详情"
...
...
@@ -909,7 +912,7 @@ msgid "Quick modify"
msgstr "快速修改"
#: assets/templates/assets/asset_detail.html:175
#: assets/templates/assets/asset_list.html:3
7
#: assets/templates/assets/asset_list.html:3
5
#: assets/templates/assets/user_asset_list.html:25 perms/models.py:20
#: perms/templates/perms/asset_permission_create_update.html:47
#: perms/templates/perms/asset_permission_detail.html:116
...
...
@@ -970,8 +973,8 @@ msgstr "移除"
msgid "Create asset group"
msgstr "创建资产组"
#: assets/templates/assets/asset_group_list.html:
80
#: assets/templates/assets/asset_list.html:2
09
#: assets/templates/assets/asset_group_list.html:
76
#: assets/templates/assets/asset_list.html:2
15
#: assets/templates/assets/cluster_list.html:84
#: assets/templates/assets/system_user_list.html:129
#: users/templates/users/user_detail.html:333
...
...
@@ -981,29 +984,29 @@ msgstr "创建资产组"
msgid "Are you sure?"
msgstr "你确认吗?"
#: assets/templates/assets/asset_group_list.html:
81
#: assets/templates/assets/asset_group_list.html:
77
#: users/templates/users/user_group_list.html:78
msgid "This will delete the selected groups !!!"
msgstr "删除选择组"
#: assets/templates/assets/asset_group_list.html:8
9
#: assets/templates/assets/asset_group_list.html:8
5
msgid "Group deleted"
msgstr "组已被删除"
#: assets/templates/assets/asset_group_list.html:
90
#: assets/templates/assets/asset_group_list.html:9
5
#: assets/templates/assets/asset_group_list.html:
86
#: assets/templates/assets/asset_group_list.html:9
1
msgid "Group Delete"
msgstr "删除"
#: assets/templates/assets/asset_group_list.html:9
4
#: assets/templates/assets/asset_group_list.html:9
0
msgid "Group deleting failed."
msgstr "删除失败"
#: assets/templates/assets/asset_group_list.html:15
7
#: assets/templates/assets/asset_group_list.html:15
3
msgid "The selected asset groups has been updated successfully."
msgstr "更新成功"
#: assets/templates/assets/asset_group_list.html:15
8
#: assets/templates/assets/asset_group_list.html:15
4
msgid "AssetGroup Updated"
msgstr "资产组更新"
...
...
@@ -1021,52 +1024,47 @@ msgstr "导出"
msgid "Create asset"
msgstr "创建资产"
#: assets/templates/assets/asset_list.html:35
#: assets/templates/assets/user_asset_list.html:23
msgid "Env"
msgstr "环境"
#: assets/templates/assets/asset_list.html:36
#: assets/templates/assets/asset_list.html:34
#: assets/templates/assets/user_asset_list.html:24
msgid "Hardware"
msgstr "硬件"
#: assets/templates/assets/asset_list.html:4
8
#: assets/templates/assets/asset_list.html:4
6
#: users/templates/users/user_list.html:37
msgid "Delete selected"
msgstr "批量删除"
#: assets/templates/assets/asset_list.html:4
9
#: assets/templates/assets/asset_list.html:4
7
#: users/templates/users/user_list.html:38
msgid "Update selected"
msgstr "批量更新"
#: assets/templates/assets/asset_list.html:
50
#: assets/templates/assets/asset_list.html:
48
#: users/templates/users/user_list.html:39
msgid "Deactive selected"
msgstr "禁用所选"
#: assets/templates/assets/asset_list.html:
51
#: assets/templates/assets/asset_list.html:
49
#: users/templates/users/user_list.html:40
msgid "Active selected"
msgstr "激活所选"
#: assets/templates/assets/asset_list.html:21
0
#: assets/templates/assets/asset_list.html:21
6
msgid "This will delete the selected assets !!!"
msgstr "删除选择资产"
# msgid "Deleted!"
# msgstr "删除"
#: assets/templates/assets/asset_list.html:2
18
#: assets/templates/assets/asset_list.html:2
24
msgid "Asset Deleted."
msgstr "已被删除"
#: assets/templates/assets/asset_list.html:2
19
#: assets/templates/assets/asset_list.html:2
24
#: assets/templates/assets/asset_list.html:2
25
#: assets/templates/assets/asset_list.html:2
30
msgid "Asset Delete"
msgstr "删除"
#: assets/templates/assets/asset_list.html:22
3
#: assets/templates/assets/asset_list.html:22
9
msgid "Asset Deleting failed."
msgstr "删除失败"
...
...
@@ -1202,6 +1200,10 @@ msgstr "删除系统用户"
msgid "System Users Deleting failed."
msgstr "系统用户删除失败"
#: assets/templates/assets/user_asset_list.html:23
msgid "Env"
msgstr "环境"
#: assets/templates/assets/user_asset_list.html:26
msgid "Connective"
msgstr "连接性"
...
...
@@ -1238,16 +1240,16 @@ msgstr "已经存在"
msgid "Cluster list"
msgstr "集群列表"
#: assets/views/cluster.py:42 assets/views/cluster.py:
70
#: assets/views/cluster.py:42 assets/views/cluster.py:
65
#: assets/views/system_user.py:96
msgid "assets"
msgstr "资产管理"
#: assets/views/cluster.py:
71
#: assets/views/cluster.py:
66
msgid "Update Cluster"
msgstr "更新Cluster"
#: assets/views/cluster.py:8
6
#: assets/views/cluster.py:8
1
msgid "Cluster detail"
msgstr "集群详情"
...
...
@@ -1293,82 +1295,119 @@ msgstr "<b>%(name)s</b> 创建成功"
msgid "<b>%(name)s</b> was updated successfully"
msgstr "<b>%(name)s</b> 更新成功"
#: common/forms.py:64
#: common/fields.py:25
#, fuzzy
#| msgid "Not a valid ssh public key"
msgid "Not a valid json"
msgstr "ssh密钥不合法"
#: common/fields.py:27
msgid "Not a string type"
msgstr ""
#: common/forms.py:70
msgid "Current SITE URL"
msgstr "当前站点URL"
#: common/forms.py:
68
#: common/forms.py:
74
msgid "User Guide URL"
msgstr "用户向导URL"
#: common/forms.py:
69
#: common/forms.py:
75
msgid "User first login update profile done redirect to it"
msgstr "用户第一次登录,修改profile后重定向到地址"
#: common/forms.py:7
2
#: common/forms.py:7
8
msgid "Email Subject Prefix"
msgstr "Email主题前缀"
#: common/forms.py:76
msgid "Enable LDAP Auth"
msgstr "二次验证"
#: common/forms.py:82
#: common/forms.py:85
msgid "SMTP host"
msgstr "SMTP主机"
#: common/forms.py:8
4
#: common/forms.py:8
7
msgid "SMTP port"
msgstr "SMTP端口"
#: common/forms.py:8
6
#: common/forms.py:8
9
msgid "SMTP user"
msgstr "SMTP账号"
#: common/forms.py:
89
#: common/forms.py:
92
msgid "SMTP password"
msgstr "SMTP密码"
#: common/forms.py:9
0
#: common/forms.py:9
3
msgid "Some provider use token except password"
msgstr "一些邮件提供商需要输入的是Token"
#: common/forms.py:9
3 common/forms.py:130
#: common/forms.py:9
6 common/forms.py:133
msgid "Use SSL"
msgstr "使用SSL"
#: common/forms.py:9
4
#: common/forms.py:9
7
msgid "If SMTP port is 465, may be select"
msgstr "如果SMTP端口是465,通常需要启用SSL"
#: common/forms.py:
97
#: common/forms.py:
100
msgid "Use TLS"
msgstr "使用TLS"
#: common/forms.py:
98
#: common/forms.py:
101
msgid "If SMTP port is 587, may be select"
msgstr "如果SMTP端口是587,通常需要启用TLS"
#: common/forms.py:10
4
#: common/forms.py:10
7
msgid "LDAP server"
msgstr "LDAP地址"
#: common/forms.py:1
07
#: common/forms.py:1
10
msgid "Bind DN"
msgstr "绑定DN"
#: common/forms.py:11
4
#: common/forms.py:11
7
msgid "User OU"
msgstr "用户OU"
#: common/forms.py:1
17
#: common/forms.py:1
20
msgid "User search filter"
msgstr "用户过滤器"
#: common/forms.py:12
0
#: common/forms.py:12
3
msgid "User attr map"
msgstr "LDAP属性映射"
#: common/forms.py:143
msgid "List sort by"
msgstr "资产列表排序"
#: common/forms.py:146
msgid "Heartbeat interval"
msgstr "心跳间隔"
#: common/forms.py:146 ops/models.py:32
msgid "Units: seconds"
msgstr "单位: 秒"
#: common/forms.py:149
msgid "Password auth"
msgstr "密码认证"
#: common/forms.py:152
msgid "Public key auth"
msgstr "秘钥认证"
#: common/forms.py:155 common/templates/common/terminal_setting.html:58
#: terminal/forms.py:21 terminal/models.py:19
msgid "Command storage"
msgstr "命令存储"
#: common/forms.py:156
msgid ""
"Set terminal storage setting, `default` is the using as default,You can set "
"other storage and some terminal using"
msgstr "设置终端命令存储,default是默认用的存储方式"
#: common/mixins.py:29
msgid "is discard"
msgstr ""
...
...
@@ -1377,55 +1416,61 @@ msgstr ""
msgid "discard time"
msgstr ""
#: common/models.py:2
6
#: common/models.py:2
7
msgid "Value"
msgstr "值"
#: common/models.py:2
7
#: common/models.py:2
9
msgid "Enabled"
msgstr "启用"
#: common/templates/common/basic_setting.html:15
#: common/templates/common/email_setting.html:15
#: common/templates/common/ldap_setting.html:15 common/views.py:18
#: common/templates/common/ldap_setting.html:15
#: common/templates/common/terminal_setting.html:15
#: common/templates/common/terminal_setting.html:38 common/views.py:21
msgid "Basic setting"
msgstr "基本设置"
#: common/templates/common/basic_setting.html:18
#: common/templates/common/email_setting.html:18
#: common/templates/common/ldap_setting.html:18 common/views.py:45
#: common/templates/common/ldap_setting.html:18
#: common/templates/common/terminal_setting.html:18 common/views.py:47
msgid "Email setting"
msgstr "邮件设置"
#: common/templates/common/basic_setting.html:21
#: common/templates/common/email_setting.html:21
#: common/templates/common/ldap_setting.html:21 common/views.py:70
#: common/templates/common/ldap_setting.html:21
#: common/templates/common/terminal_setting.html:21 common/views.py:73
msgid "LDAP setting"
msgstr "LDAP设置"
#: common/templates/common/basic_setting.html:55
#: common/templates/common/email_setting.html:55
#: common/templates/common/ldap_setting.html:55
#: common/templates/common/basic_setting.html:24
#: common/templates/common/email_setting.html:24
#: common/templates/common/ldap_setting.html:24
#: common/templates/common/terminal_setting.html:24 common/views.py:102
msgid "Terminal setting"
msgstr "终端设置"
#: common/templates/common/email_setting.html:58
#: common/templates/common/ldap_setting.html:58
msgid "Test connection"
msgstr "测试连接"
#: common/views.py:
17 common/views.py:44 common/views.py:69
#: common/views.py:
20 common/views.py:46 common/views.py:72 common/views.py:101
#: templates/_nav.html:69
msgid "Settings"
msgstr "系统设置"
#: common/views.py:3
0 common/views.py:55 common/views.py:80
msgid "Update setting successfully"
msgstr "更新设置成功"
#: common/views.py:3
1 common/views.py:57 common/views.py:85 common/views.py:113
msgid "Update setting successfully
, please restart program
"
msgstr "更新设置成功
, 请手动重启程序
"
#: ops/models.py:32
msgid "Interval"
msgstr "间隔"
#: ops/models.py:32
msgid "Units: seconds"
msgstr "单位: 秒"
#: ops/models.py:33
msgid "Crontab"
msgstr "Crontab"
...
...
@@ -1569,7 +1614,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
01
#: ops/templates/ops/task_history.html:55 terminal/models.py:1
24
#: terminal/templates/terminal/session_list.html:77
msgid "Date start"
msgstr "开始日期"
...
...
@@ -1686,18 +1731,18 @@ msgid "Task run history"
msgstr "执行历史"
#: perms/forms.py:16 users/forms.py:147 users/forms.py:152 users/forms.py:164
#: users/forms.py:19
5
#: users/forms.py:19
4
msgid "Select users"
msgstr "选择用户"
#: perms/forms.py:18 perms/models.py:15
#: perms/templates/perms/asset_permission_create_update.html:36
#: perms/templates/perms/asset_permission_list.html:26 templates/_nav.html:12
#: terminal/backends/command/models.py:10 terminal/models.py:
92
#: terminal/backends/command/models.py:10 terminal/models.py:
115
#: 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:19
1
#: terminal/templates/terminal/session_list.html:71 users/forms.py:19
0
#: users/models/user.py:30 users/templates/users/user_group_detail.html:78
#: users/views/user.py:337
msgid "User"
...
...
@@ -1842,16 +1887,12 @@ msgstr "资产授权包含用户"
msgid "Asset permission asset list"
msgstr "资产组授权包含资产"
#: templates/_header_bar.html:14
msgid "Welcome to use Jumpserver system"
msgstr "欢迎使用Jumpserver开源跳板机系统"
#: templates/_header_bar.html:18
msgid "Help"
msgstr "帮助"
#: templates/_header_bar.html:3
3
templates/_nav_user.html:9
#: users/templates/users/_user.html:
42
#: templates/_header_bar.html:3
2
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
...
...
@@ -1860,24 +1901,24 @@ msgstr "帮助"
msgid "Profile"
msgstr "个人信息"
#: templates/_header_bar.html:3
7
#: templates/_header_bar.html:3
6
msgid "Admin page"
msgstr "管理页面"
#: templates/_header_bar.html:3
9
#: templates/_header_bar.html:3
8
msgid "User page"
msgstr "用户页面"
#: templates/_header_bar.html:4
2
#: templates/_header_bar.html:4
1
msgid "Logout"
msgstr "注销登录"
#: templates/_header_bar.html:4
6
users/templates/users/login.html:42
#: templates/_header_bar.html:4
5
users/templates/users/login.html:42
#: users/templates/users/login.html:61
msgid "Login"
msgstr "登录"
#: templates/_header_bar.html:5
9
templates/_nav.html:4
#: templates/_header_bar.html:5
8
templates/_nav.html:4
msgid "Dashboard"
msgstr "仪表盘"
...
...
@@ -1912,8 +1953,8 @@ 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:19
4
#: users/views/login.py:24
3
users/views/user.py:57 users/views/user.py:72
#: users/views/group.py:62 users/views/group.py:79 users/views/login.py:19
7
#: users/views/login.py:24
6
users/views/user.py:57 users/views/user.py:72
#: users/views/user.py:91 users/views/user.py:147 users/views/user.py:304
#: users/views/user.py:318 users/views/user.py:355 users/views/user.py:377
msgid "Users"
...
...
@@ -1952,7 +1993,7 @@ msgstr "在线会话"
msgid "Session offline"
msgstr "离线会话"
#: templates/_nav.html:53 terminal/models.py:
99
#: templates/_nav.html:53 terminal/models.py:
122
#: terminal/templates/terminal/command_list.html:55
#: terminal/templates/terminal/command_list.html:71
#: terminal/templates/terminal/session_detail.html:48
...
...
@@ -1993,64 +2034,68 @@ msgstr "输出"
msgid "Session"
msgstr "会话"
#: terminal/forms.py:
15
#: terminal/forms.py:
27
msgid "Coco ssh listen port"
msgstr "SSH 监听端口"
#: terminal/forms.py:
16
#: terminal/forms.py:
28
msgid "Coco http/ws listen port"
msgstr "Http/Websocket 监听端口"
#: terminal/models.py:1
5
#: terminal/models.py:1
6
msgid "Remote Address"
msgstr "远端地址"
#: terminal/models.py:1
6
#: terminal/models.py:1
7
msgid "SSH Port"
msgstr "SSH端口"
#: terminal/models.py:1
7
#: terminal/models.py:1
8
msgid "HTTP Port"
msgstr "HTTP端口"
#: terminal/models.py:68
#: terminal/models.py:20
msgid "Replay storage"
msgstr "录像存储"
#: terminal/models.py:91
msgid "Session Online"
msgstr "在线会话"
#: terminal/models.py:
69
#: terminal/models.py:
92
msgid "CPU Usage"
msgstr "CPU使用"
#: terminal/models.py:
70
#: terminal/models.py:
93
msgid "Memory Used"
msgstr "内存使用"
#: terminal/models.py:
71
#: terminal/models.py:
94
msgid "Connections"
msgstr "连接数"
#: terminal/models.py:
72
#: terminal/models.py:
95
msgid "Threads"
msgstr "线程数"
#: terminal/models.py:
73
#: terminal/models.py:
96
msgid "Boot Time"
msgstr "运行时间"
#: terminal/models.py:
96
terminal/templates/terminal/session_list.html:74
#: terminal/models.py:
119
terminal/templates/terminal/session_list.html:74
#: terminal/templates/terminal/terminal_detail.html:47
msgid "Remote addr"
msgstr "远端地址"
#: terminal/models.py:
98
terminal/templates/terminal/session_list.html:100
#: terminal/models.py:
121
terminal/templates/terminal/session_list.html:100
msgid "Replay"
msgstr "回放"
#: terminal/models.py:1
02
#: terminal/models.py:1
25
msgid "Date end"
msgstr "结束日期"
#: terminal/models.py:1
19
#: terminal/models.py:1
42
msgid "Args"
msgstr "参数"
...
...
@@ -2404,7 +2449,7 @@ msgstr "忘记密码"
#: users/templates/users/forgot_password.html:33
msgid "Input your email, that will send a mail to your"
msgstr "输入您的邮箱, 将会发一封重置
短信
邮件到您的邮箱中"
msgstr "输入您的邮箱, 将会发一封重置邮件到您的邮箱中"
#: users/templates/users/login.html:47
msgid "Captcha invalid"
...
...
@@ -2473,10 +2518,8 @@ msgid "An e-mail has been sent to the user\\'s mailbox."
msgstr "已发送邮件到用户邮箱"
#: users/templates/users/user_detail.html:334
msgid ""
"This will reset the user's password. A password-reset email will be sent to "
"the user\\'s mailbox."
msgstr "重设密码邮件将会发送到用户邮箱"
msgid "This will reset the user password and send a reset mail"
msgstr "将失效用户当前密码,并发送重设密码邮件到用户邮箱"
#: users/templates/users/user_detail.html:348
msgid ""
...
...
@@ -2490,8 +2533,8 @@ msgid "Reset SSH public key"
msgstr "重置SSH密钥"
#: users/templates/users/user_detail.html:359
msgid "This will reset the user
\\
"
msgstr "
重置
"
msgid "This will reset the user
public key and send a reset mail
"
msgstr "
将会失效用户当前秘钥,并发送重置邮件到用户邮箱
"
#: users/templates/users/user_detail.html:376
#: users/templates/users/user_profile.html:170
...
...
@@ -2740,48 +2783,48 @@ msgstr "编辑用户组"
msgid "Please enable cookies and try again."
msgstr "设置你的浏览器支持cookie"
#: users/views/login.py:8
4
#: users/views/login.py:8
7
msgid "Logout success"
msgstr "退出登录成功"
#: users/views/login.py:8
5
#: users/views/login.py:8
8
msgid "Logout success, return login page"
msgstr "退出登录成功,返回到登录页面"
#: users/views/login.py:10
1
#: users/views/login.py:10
4
msgid "Email address invalid, please input again"
msgstr "邮箱地址错误,重新输入"
#: users/views/login.py:11
4
#: users/views/login.py:11
7
msgid "Send reset password message"
msgstr "发送重置密码邮件"
#: users/views/login.py:11
5
#: users/views/login.py:11
8
msgid "Send reset password mail success, login your mail box and follow it "
msgstr ""
"发送重置邮件成功, 请登录邮箱查看, 按照提示操作 (如果没收到,请等待3-5分钟)"
#: users/views/login.py:1
29
#: users/views/login.py:1
32
msgid "Reset password success"
msgstr "重置密码成功"
#: users/views/login.py:13
0
#: users/views/login.py:13
3
msgid "Reset password success, return to login page"
msgstr "重置密码成功,返回到登录页面"
#: users/views/login.py:1
47 users/views/login.py:160
#: users/views/login.py:1
50 users/views/login.py:163
msgid "Token invalid or expired"
msgstr "Token错误或失效"
#: users/views/login.py:15
6
#: users/views/login.py:15
9
msgid "Password not same"
msgstr "密码不一致"
#: users/views/login.py:19
4
#: users/views/login.py:19
7
msgid "First login"
msgstr "首次登陆"
#: users/views/login.py:24
4
#: users/views/login.py:24
7
msgid "Login log list"
msgstr "登录日志"
...
...
@@ -2813,5 +2856,17 @@ msgstr "密码更新"
msgid "Public key update"
msgstr "秘钥更新"
#~ msgid "Add command storage"
#~ msgstr "添加命令存储"
#~ msgid "Welcome to use Jumpserver system"
#~ msgstr "欢迎使用Jumpserver开源跳板机系统"
#~ msgid "This will reset the user\\"
#~ msgstr "重置"
#~ msgid "Enable LDAP Auth"
#~ msgstr "LDAP认证"
#~ msgid "Connect"
#~ msgstr "连接"
This diff is collapsed.
Click to expand it.
apps/ops/models.py
View file @
f37b3316
...
...
@@ -165,7 +165,7 @@ class AdHoc(models.Model):
if
item
and
isinstance
(
item
,
list
):
self
.
_tasks
=
json
.
dumps
(
item
)
else
:
raise
SyntaxError
(
'Tasks should be a list
'
)
raise
SyntaxError
(
'Tasks should be a list
: {}'
.
format
(
item
)
)
@property
def
hosts
(
self
):
...
...
This diff is collapsed.
Click to expand it.
apps/ops/utils.py
View file @
f37b3316
...
...
@@ -16,6 +16,8 @@ def update_or_create_ansible_task(
run_as_admin
=
False
,
run_as
=
""
,
become_info
=
None
,
created_by
=
None
,
):
if
not
hosts
or
not
tasks
or
not
task_name
:
return
defaults
=
{
'name'
:
task_name
,
...
...
@@ -41,7 +43,7 @@ def update_or_create_ansible_task(
new_adhoc
.
become
=
become_info
if
not
adhoc
or
adhoc
!=
new_adhoc
:
logger
.
debug
(
"Task create new adhoc: {}"
.
format
(
task_name
))
print
(
"Task create new adhoc: {}"
.
format
(
task_name
))
new_adhoc
.
save
()
task
.
latest_adhoc
=
new_adhoc
created
=
True
...
...
This diff is collapsed.
Click to expand it.
apps/static/css/jumpserver.css
View file @
f37b3316
...
...
@@ -303,7 +303,7 @@ div.dataTables_wrapper div.dataTables_filter {
.profile-element
div
:first-child
{
line-height
:
60px
;
width
:
70px
;
/*width: 70px;*/
float
:
left
;
text-align
:
center
;
}
...
...
This diff is collapsed.
Click to expand it.
apps/static/img/avatar/admin.png
View replaced file @
5bbad019
View file @
f37b3316
106 KB
|
W:
0px
|
H:
0px
11.5 KB
|
W:
0px
|
H:
0px
2-up
Swipe
Onion skin
This diff is collapsed.
Click to expand it.
apps/static/img/avatar/user.png
View replaced file @
5bbad019
View file @
f37b3316
61.3 KB
|
W:
0px
|
H:
0px
11.5 KB
|
W:
0px
|
H:
0px
2-up
Swipe
Onion skin
This diff is collapsed.
Click to expand it.
apps/static/img/logo-text.png
0 → 100644
View file @
f37b3316
12.4 KB
This diff is collapsed.
Click to expand it.
apps/templates/_footer.html
View file @
f37b3316
...
...
@@ -4,6 +4,6 @@
<img
style=
"display: none"
src=
"http://www.jumpserver.org/img/evaluate_avatar1.jpg"
>
</div>
<div>
<strong>
Copyright
</strong>
北京堆栈科技有限公司
©
2014-201
7
<strong>
Copyright
</strong>
北京堆栈科技有限公司
©
2014-201
8
</div>
</div>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
apps/templates/_header_bar.html
View file @
f37b3316
...
...
@@ -10,9 +10,9 @@
<!--</form>-->
</div>
<ul
class=
"nav navbar-top-links navbar-right"
>
<li>
<span
class=
"m-r-sm text-muted welcome-message"
>
{% trans 'Welcome to use Jumpserver system' %}
</span>
</li>
{#
<li>
#}
{#
<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>
...
...
@@ -22,11 +22,10 @@
{% if request.user.is_authenticated %}
<a
data-toggle=
"dropdown"
class=
"dropdown-toggle"
href=
"#"
>
<span
class=
"m-r-sm text-muted welcome-message"
>
<img
alt=
"image"
class=
"img-circle"
width=
"40"
height=
"40"
src=
"{{ request.user.avatar_url }}"
/>
<strong
class=
"font-bold"
>
{{ request.user.name }}
<span
style=
"color: #8095a8"
></span>
<img
alt=
"image"
class=
"img-circle"
width=
"30"
height=
"30"
src=
"{{ request.user.avatar_url }}"
/>
<span
style=
"font-size: 13px;font-weight: 400"
>
{{ request.user.name }}
<b
class=
"caret"
></b>
</s
trong
>
</s
pan
>
</span>
</a>
<ul
class=
"dropdown-menu animated fadeInRight m-t-xs"
>
...
...
This diff is collapsed.
Click to expand it.
apps/templates/_user_profile.html
View file @
f37b3316
...
...
@@ -2,11 +2,8 @@
{% load i18n %}
<li
class=
"nav-header"
>
<div
class=
"dropdown profile-element"
>
<div>
<img
alt=
"image"
height=
"40"
src=
"/static/img/logo.png"
/>
</div>
<div>
<a
href=
"http://www.jumpserver.org"
target=
"_blank"
>
Jumpserver
</a>
<div
href=
"http://www.jumpserver.org"
target=
"_blank"
>
<img
alt=
"image"
height=
"55"
src=
"/static/img/logo-text.png"
style=
"margin-left: 10px"
/>
</div>
</div>
<div
class=
"clearfix"
></div>
...
...
This diff is collapsed.
Click to expand it.
apps/templates/flash_message_standalone.html
View file @
f37b3316
...
...
@@ -52,7 +52,7 @@
Copyright Jumpserver.org
</div>
<div
class=
"col-md-6 text-right"
>
<small>
2014-201
7
</small>
<small>
2014-201
8
</small>
</div>
</div>
</div>
...
...
This diff is collapsed.
Click to expand it.
apps/templates/index.html
View file @
f37b3316
...
...
@@ -164,7 +164,7 @@
{% for login in last_login_ten %}
<div
class=
"feed-element"
>
<a
href=
"#"
class=
"pull-left"
>
<img
alt=
"image"
class=
"img-circle"
src=
"
/static/img/root.png
"
>
<img
alt=
"image"
class=
"img-circle"
src=
"
{% static 'img/avatar/user.png' %}
"
>
</a>
<div
class=
"media-body "
>
{% ifequal login.is_finished 0 %}
...
...
This diff is collapsed.
Click to expand it.
apps/terminal/api.py
View file @
f37b3316
# -*- coding: utf-8 -*-
#
from
collections
import
OrderedDict
import
copy
import
logging
import
os
import
uuid
...
...
@@ -21,7 +20,8 @@ from .serializers import TerminalSerializer, StatusSerializer, \
SessionSerializer
,
TaskSerializer
,
ReplaySerializer
from
.hands
import
IsSuperUserOrAppUser
,
IsAppUser
,
\
IsSuperUserOrAppUserOrUserReadonly
from
.backends
import
get_command_store
,
SessionCommandSerializer
from
.backends
import
get_command_store
,
get_multi_command_store
,
\
SessionCommandSerializer
logger
=
logging
.
getLogger
(
__file__
)
...
...
@@ -141,7 +141,9 @@ class StatusViewSet(viewsets.ModelViewSet):
session
=
serializer
.
save
()
return
session
else
:
msg
=
"session data is not valid {}"
.
format
(
serializer
.
errors
)
msg
=
"session data is not valid {}: {}"
.
format
(
serializer
.
errors
,
str
(
serializer
.
data
)
)
logger
.
error
(
msg
)
return
None
...
...
@@ -195,6 +197,7 @@ class CommandViewSet(viewsets.ViewSet):
"""
command_store
=
get_command_store
()
multi_command_storage
=
get_multi_command_store
()
serializer_class
=
SessionCommandSerializer
permission_classes
=
(
IsSuperUserOrAppUser
,)
...
...
@@ -215,7 +218,7 @@ class CommandViewSet(viewsets.ViewSet):
return
Response
({
"msg"
:
msg
},
status
=
401
)
def
list
(
self
,
request
,
*
args
,
**
kwargs
):
queryset
=
list
(
self
.
command_store
.
all
()
)
queryset
=
self
.
multi_command_storage
.
filter
(
)
serializer
=
self
.
serializer_class
(
queryset
,
many
=
True
)
return
Response
(
serializer
.
data
)
...
...
@@ -258,3 +261,13 @@ class SessionReplayViewSet(viewsets.ViewSet):
return
redirect
(
url
)
else
:
return
HttpResponseNotFound
()
class
TerminalConfig
(
APIView
):
permission_classes
=
(
IsAppUser
,)
def
get
(
self
,
request
):
user
=
request
.
user
terminal
=
user
.
terminal
configs
=
terminal
.
config
return
Response
(
configs
,
status
=
200
)
This diff is collapsed.
Click to expand it.
apps/terminal/backends/__init__.py
View file @
f37b3316
...
...
@@ -2,9 +2,39 @@ from importlib import import_module
from
django.conf
import
settings
from
.command.serializers
import
SessionCommandSerializer
TYPE_ENGINE_MAPPING
=
{
'elasticsearch'
:
'terminal.backends.command.es'
,
}
def
get_command_store
():
command_engine
=
import_module
(
settings
.
COMMAND_STORAGE_BACKEND
)
command_store
=
command_engine
.
CommandStore
()
return
command_store
params
=
settings
.
COMMAND_STORAGE
engine_class
=
import_module
(
params
[
'ENGINE'
])
storage
=
engine_class
.
CommandStore
(
params
)
return
storage
def
get_terminal_command_store
():
storage_list
=
{}
for
name
,
params
in
settings
.
TERMINAL_COMMAND_STORAGE
.
items
():
tp
=
params
[
'TYPE'
]
if
tp
==
'server'
:
storage
=
get_command_store
()
else
:
if
not
TYPE_ENGINE_MAPPING
.
get
(
tp
):
raise
AssertionError
(
"Command storage type should in {}"
.
format
(
', '
.
join
(
TYPE_ENGINE_MAPPING
.
keys
()))
)
engine_class
=
import_module
(
TYPE_ENGINE_MAPPING
[
tp
])
storage
=
engine_class
.
CommandStore
(
params
)
storage_list
[
name
]
=
storage
return
storage_list
def
get_multi_command_store
():
from
.command.multi
import
CommandStore
storage_list
=
get_terminal_command_store
()
.
values
()
storage
=
CommandStore
(
storage_list
)
return
storage
This diff is collapsed.
Click to expand it.
apps/terminal/backends/command/base.py
View file @
f37b3316
...
...
@@ -19,3 +19,9 @@ class CommandBase(object):
input
=
None
,
session
=
None
):
pass
@abc.abstractmethod
def
count
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
pass
This diff is collapsed.
Click to expand it.
apps/terminal/backends/command/db.py
View file @
f37b3316
...
...
@@ -8,7 +8,7 @@ from .base import CommandBase
class
CommandStore
(
CommandBase
):
def
__init__
(
self
):
def
__init__
(
self
,
params
):
from
terminal.models
import
Command
self
.
model
=
Command
...
...
@@ -37,9 +37,11 @@ class CommandStore(CommandBase):
))
return
self
.
model
.
objects
.
bulk_create
(
_commands
)
def
filter
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
@staticmethod
def
make_filter_kwargs
(
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
filter_kwargs
=
{}
date_from_default
=
timezone
.
now
()
-
datetime
.
timedelta
(
days
=
7
)
date_to_default
=
timezone
.
now
()
...
...
@@ -60,10 +62,28 @@ class CommandStore(CommandBase):
if
session
:
filter_kwargs
[
'session'
]
=
session
return
filter_kwargs
def
filter
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
filter_kwargs
=
self
.
make_filter_kwargs
(
date_from
=
date_from
,
date_to
=
date_to
,
user
=
user
,
asset
=
asset
,
system_user
=
system_user
,
input
=
input
,
session
=
session
,
)
queryset
=
self
.
model
.
objects
.
filter
(
**
filter_kwargs
)
return
queryset
return
[
command
.
to_dict
()
for
command
in
queryset
]
def
count
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
filter_kwargs
=
self
.
make_filter_kwargs
(
date_from
=
date_from
,
date_to
=
date_to
,
user
=
user
,
asset
=
asset
,
system_user
=
system_user
,
input
=
input
,
session
=
session
,
)
count
=
self
.
model
.
objects
.
filter
(
**
filter_kwargs
)
.
count
()
return
count
def
all
(
self
):
"""返回所有数据"""
return
self
.
model
.
objects
.
iterator
()
This diff is collapsed.
Click to expand it.
apps/terminal/backends/command/es.py
0 → 100644
View file @
f37b3316
# -*- coding: utf-8 -*-
#
from
jms_es_sdk
import
ESStore
from
.base
import
CommandBase
class
CommandStore
(
CommandBase
,
ESStore
):
def
__init__
(
self
,
params
):
hosts
=
params
.
get
(
'HOSTS'
,
[
'http://localhost'
])
ESStore
.
__init__
(
self
,
hosts
=
hosts
)
def
save
(
self
,
command
):
return
ESStore
.
save
(
self
,
command
)
def
bulk_save
(
self
,
commands
):
return
ESStore
.
bulk_save
(
self
,
commands
)
def
filter
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
data
=
ESStore
.
filter
(
self
,
date_from
=
date_from
,
date_to
=
date_to
,
user
=
user
,
asset
=
asset
,
system_user
=
system_user
,
input
=
input
,
session
=
session
)
return
[
item
[
"_source"
]
for
item
in
data
[
"hits"
]
if
item
]
def
count
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
amount
=
ESStore
.
count
(
self
,
date_from
=
date_from
,
date_to
=
date_to
,
user
=
user
,
asset
=
asset
,
system_user
=
system_user
,
input
=
input
,
session
=
session
)
return
amount
This diff is collapsed.
Click to expand it.
apps/terminal/backends/command/models.py
View file @
f37b3316
...
...
@@ -18,5 +18,26 @@ class AbstractSessionCommand(models.Model):
class
Meta
:
abstract
=
True
@classmethod
def
from_dict
(
cls
,
d
):
self
=
cls
()
for
k
,
v
in
d
.
items
():
setattr
(
self
,
k
,
v
)
return
self
@classmethod
def
from_multi_dict
(
cls
,
l
):
commands
=
[]
for
d
in
l
:
command
=
cls
.
from_dict
(
d
)
commands
.
append
(
command
)
return
commands
def
to_dict
(
self
):
d
=
{}
for
field
in
self
.
_meta
.
fields
:
d
[
field
.
name
]
=
getattr
(
self
,
field
.
name
)
return
d
def
__str__
(
self
):
return
self
.
input
This diff is collapsed.
Click to expand it.
apps/terminal/backends/command/multi.py
0 → 100644
View file @
f37b3316
# -*- coding: utf-8 -*-
#
from
.base
import
CommandBase
class
CommandStore
(
CommandBase
):
def
__init__
(
self
,
storage_list
):
self
.
storage_list
=
storage_list
def
filter
(
self
,
**
kwargs
):
queryset
=
[]
for
storage
in
self
.
storage_list
:
queryset
.
extend
(
storage
.
filter
(
**
kwargs
))
return
sorted
(
queryset
,
key
=
lambda
command
:
command
[
"timestamp"
],
reverse
=
True
)
def
count
(
self
,
**
kwargs
):
amount
=
0
for
storage
in
self
.
storage_list
:
amount
+=
storage
.
count
(
**
kwargs
)
return
amount
def
save
(
self
,
command
):
pass
def
bulk_save
(
self
,
commands
):
pass
This diff is collapsed.
Click to expand it.
apps/terminal/forms.py
View file @
f37b3316
...
...
@@ -2,15 +2,27 @@
#
from
django
import
forms
from
django.conf
import
settings
from
django.utils.translation
import
ugettext_lazy
as
_
from
.models
import
Terminal
def
get_all_command_storage
():
# storage_choices = []
from
common.models
import
Setting
Setting
.
refresh_all_settings
()
for
k
,
v
in
settings
.
TERMINAL_COMMAND_STORAGE
.
items
():
yield
(
k
,
k
)
class
TerminalForm
(
forms
.
ModelForm
):
command_storage
=
forms
.
ChoiceField
(
choices
=
get_all_command_storage
(),
label
=
_
(
"Command storage"
))
class
Meta
:
model
=
Terminal
fields
=
[
'name'
,
'remote_addr'
,
'ssh_port'
,
'http_port'
,
'comment'
]
fields
=
[
'name'
,
'remote_addr'
,
'ssh_port'
,
'http_port'
,
'comment'
,
'command_storage'
]
help_texts
=
{
'ssh_port'
:
_
(
"Coco ssh listen port"
),
'http_port'
:
_
(
"Coco http/ws listen port"
),
...
...
This diff is collapsed.
Click to expand it.
apps/terminal/models.py
View file @
f37b3316
...
...
@@ -4,6 +4,7 @@ import uuid
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.conf
import
settings
from
users.models
import
User
from
.backends.command.models
import
AbstractSessionCommand
...
...
@@ -15,6 +16,8 @@ class Terminal(models.Model):
remote_addr
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Remote Address'
))
ssh_port
=
models
.
IntegerField
(
verbose_name
=
_
(
'SSH Port'
),
default
=
2222
)
http_port
=
models
.
IntegerField
(
verbose_name
=
_
(
'HTTP Port'
),
default
=
5000
)
command_storage
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"Command storage"
),
default
=
'default'
)
replay_storage
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"Replay storage"
),
default
=
'default'
)
user
=
models
.
OneToOneField
(
User
,
related_name
=
'terminal'
,
verbose_name
=
'Application User'
,
null
=
True
,
on_delete
=
models
.
CASCADE
)
is_accepted
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
'Is Accepted'
)
is_deleted
=
models
.
BooleanField
(
default
=
False
)
...
...
@@ -33,6 +36,26 @@ class Terminal(models.Model):
self
.
user
.
is_active
=
active
self
.
user
.
save
()
def
get_common_storage
(
self
):
storage_all
=
settings
.
TERMINAL_COMMAND_STORAGE
if
self
.
command_storage
in
storage_all
:
storage
=
storage_all
.
get
(
self
.
command_storage
)
else
:
storage
=
storage_all
.
get
(
'default'
)
return
{
"TERMINAL_COMMAND_STORAGE"
:
storage
}
def
get_replay_storage
(
self
):
pass
@property
def
config
(
self
):
configs
=
{}
for
k
in
dir
(
settings
):
if
k
.
startswith
(
'TERMINAL'
):
configs
[
k
]
=
getattr
(
settings
,
k
)
configs
.
update
(
self
.
get_common_storage
())
return
configs
def
create_app_user
(
self
):
random
=
uuid
.
uuid4
()
.
hex
[:
6
]
user
,
access_key
=
User
.
create_app_user
(
name
=
"{}-{}"
.
format
(
self
.
name
,
random
),
comment
=
self
.
comment
)
...
...
This diff is collapsed.
Click to expand it.
apps/terminal/serializers.py
View file @
f37b3316
...
...
@@ -5,7 +5,7 @@ from django.utils import timezone
from
rest_framework
import
serializers
from
.models
import
Terminal
,
Status
,
Session
,
Task
from
.backends
import
get_command_store
from
.backends
import
get_
multi_
command_store
class
TerminalSerializer
(
serializers
.
ModelSerializer
):
...
...
@@ -43,14 +43,14 @@ class TerminalSerializer(serializers.ModelSerializer):
class
SessionSerializer
(
serializers
.
ModelSerializer
):
command_amount
=
serializers
.
SerializerMethodField
()
command_store
=
get_command_store
()
command_store
=
get_
multi_
command_store
()
class
Meta
:
model
=
Session
fields
=
'__all__'
def
get_command_amount
(
self
,
obj
):
return
len
(
self
.
command_store
.
filter
(
session
=
obj
.
session
))
return
self
.
command_store
.
count
(
session
=
str
(
obj
.
id
))
class
StatusSerializer
(
serializers
.
ModelSerializer
):
...
...
This diff is collapsed.
Click to expand it.
apps/terminal/signals_handler.py
View file @
f37b3316
...
...
@@ -13,10 +13,6 @@ RUNNING = False
logger
=
get_logger
(
__file__
)
@shared_task
@register_as_period_task
(
interval
=
3600
)
@after_app_ready_start
@after_app_shutdown_clean
def
set_session_info_cache
():
logger
.
debug
(
""
)
from
.utils
import
get_session_asset_list
,
get_session_user_list
,
\
...
...
This diff is collapsed.
Click to expand it.
apps/terminal/templates/terminal/terminal_modal_accept.html
View file @
f37b3316
...
...
@@ -12,6 +12,7 @@
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.ssh_port layout="horizontal" %}
{% bootstrap_field form.http_port layout="horizontal" %}
{% bootstrap_field form.command_storage layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
</form>
...
...
This diff is collapsed.
Click to expand it.
apps/terminal/templates/terminal/terminal_update.html
View file @
f37b3316
...
...
@@ -35,6 +35,7 @@
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.ssh_port layout="horizontal" %}
{% bootstrap_field form.http_port layout="horizontal" %}
{% bootstrap_field form.command_storage layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
...
...
This diff is collapsed.
Click to expand it.
apps/terminal/templatetags/terminal_tags.py
View file @
f37b3316
# ~*~ coding: utf-8 ~*~
from
django
import
template
from
..backends
import
get_command_store
from
..backends
import
get_
multi_
command_store
register
=
template
.
Library
()
command_store
=
get_command_store
()
command_store
=
get_
multi_
command_store
()
@register.filter
def
get_session_command_amount
(
session_id
):
return
len
(
command_store
.
filter
(
session
=
str
(
session_id
)))
return
command_store
.
count
(
session
=
session_id
)
This diff is collapsed.
Click to expand it.
apps/terminal/urls/api_urls.py
View file @
f37b3316
...
...
@@ -20,7 +20,8 @@ urlpatterns = [
url
(
r'^v1/sessions/(?P<pk>[0-9a-zA-Z\-]{36})/replay/$'
,
api
.
SessionReplayViewSet
.
as_view
({
'get'
:
'retrieve'
,
'post'
:
'create'
}),
name
=
'session-replay'
),
url
(
r'^v1/terminal/(?P<terminal>[a-zA-Z0-9\-]{36})/access-key'
,
api
.
TerminalTokenApi
.
as_view
(),
name
=
'terminal-access-key'
)
url
(
r'^v1/terminal/(?P<terminal>[a-zA-Z0-9\-]{36})/access-key'
,
api
.
TerminalTokenApi
.
as_view
(),
name
=
'terminal-access-key'
),
url
(
r'^v1/terminal/config'
,
api
.
TerminalConfig
.
as_view
(),
name
=
'terminal-config'
),
]
urlpatterns
+=
router
.
urls
This diff is collapsed.
Click to expand it.
apps/terminal/views/command.py
View file @
f37b3316
...
...
@@ -9,10 +9,10 @@ from django.utils.translation import ugettext as _
from
common.mixins
import
DatetimeSearchMixin
from
..models
import
Command
from
..
import
utils
from
..backends
import
get_command_store
from
..backends
import
get_
multi_
command_store
__all__
=
[
'CommandListView'
]
comm
and_store
=
get
_command_store
()
comm
on_storage
=
get_multi
_command_store
()
class
CommandListView
(
DatetimeSearchMixin
,
ListView
):
...
...
@@ -39,7 +39,7 @@ class CommandListView(DatetimeSearchMixin, ListView):
filter_kwargs
[
'system_user'
]
=
self
.
system_user
if
self
.
command
:
filter_kwargs
[
'input'
]
=
self
.
command
queryset
=
comm
and_stor
e
.
filter
(
**
filter_kwargs
)
queryset
=
comm
on_storag
e
.
filter
(
**
filter_kwargs
)
return
queryset
def
get_context_data
(
self
,
**
kwargs
):
...
...
This diff is collapsed.
Click to expand it.
apps/terminal/views/session.py
View file @
f37b3316
...
...
@@ -10,7 +10,7 @@ from django.conf import settings
from
users.utils
import
AdminUserRequiredMixin
from
common.mixins
import
DatetimeSearchMixin
from
..models
import
Session
,
Command
,
Terminal
from
..backends
import
get_command_store
from
..backends
import
get_
multi_
command_store
from
..
import
utils
...
...
@@ -19,7 +19,7 @@ __all__ = [
'SessionDetailView'
,
]
command_store
=
get_command_store
()
command_store
=
get_
multi_
command_store
()
class
SessionListView
(
AdminUserRequiredMixin
,
DatetimeSearchMixin
,
ListView
):
...
...
This diff is collapsed.
Click to expand it.
apps/users/api.py
View file @
f37b3316
# ~*~ coding: utf-8 ~*~
from
rest_framework
import
generics
from
rest_framework.permissions
import
AllowAny
from
rest_framework.permissions
import
AllowAny
,
IsAuthenticated
from
rest_framework.response
import
Response
from
rest_framework.views
import
APIView
from
rest_framework_bulk
import
BulkModelViewSet
from
.serializers
import
UserSerializer
,
UserGroupSerializer
,
\
UserGroupUpdateMemeberSerializer
,
UserPKUpdateSerializer
,
\
UserUpdateGroupSerializer
UserUpdateGroupSerializer
,
ChangeUserPasswordSerializer
from
.tasks
import
write_login_log_async
from
.models
import
User
,
UserGroup
from
.permissions
import
IsSuperUser
,
IsValidUser
,
IsCurrentUserOrReadOnly
...
...
@@ -24,10 +24,21 @@ class UserViewSet(CustomFilterMixin, BulkModelViewSet):
queryset
=
User
.
objects
.
exclude
(
role
=
"App"
)
# queryset = User.objects.all().exclude(role="App").order_by("date_joined")
serializer_class
=
UserSerializer
permission_classes
=
(
IsSuperUser
,)
permission_classes
=
(
IsSuperUser
,
IsAuthenticated
)
filter_fields
=
(
'username'
,
'email'
,
'name'
,
'id'
)
class
ChangeUserPasswordApi
(
generics
.
RetrieveUpdateAPIView
):
permission_classes
=
(
IsSuperUser
,)
queryset
=
User
.
objects
.
all
()
serializer_class
=
ChangeUserPasswordSerializer
def
perform_update
(
self
,
serializer
):
user
=
self
.
get_object
()
user
.
password_raw
=
serializer
.
validated_data
[
"password"
]
user
.
save
()
class
UserUpdateGroupApi
(
generics
.
RetrieveUpdateAPIView
):
queryset
=
User
.
objects
.
all
()
serializer_class
=
UserUpdateGroupSerializer
...
...
@@ -37,6 +48,7 @@ class UserUpdateGroupApi(generics.RetrieveUpdateAPIView):
class
UserResetPasswordApi
(
generics
.
UpdateAPIView
):
queryset
=
User
.
objects
.
all
()
serializer_class
=
UserSerializer
permission_classes
=
(
IsAuthenticated
,)
def
perform_update
(
self
,
serializer
):
# Note: we are not updating the user object here.
...
...
@@ -128,7 +140,11 @@ class UserAuthApi(APIView):
user_agent
=
request
.
data
.
get
(
'HTTP_USER_AGENT'
,
''
)
if
not
login_ip
:
login_ip
=
request
.
META
.
get
(
'HTTP_X_FORWARDED_FOR'
)
or
request
.
META
.
get
(
"REMOTE_ADDR"
)
x_forwarded_for
=
request
.
META
.
get
(
'HTTP_X_FORWARDED_FOR'
,
''
)
.
split
(
','
)
if
x_forwarded_for
:
login_ip
=
x_forwarded_for
[
0
]
else
:
login_ip
=
request
.
META
.
get
(
"REMOTE_ADDR"
)
user
,
msg
=
check_user_valid
(
username
=
username
,
password
=
password
,
...
...
This diff is collapsed.
Click to expand it.
apps/users/forms.py
View file @
f37b3316
...
...
@@ -172,7 +172,6 @@ class UserBulkUpdateForm(forms.ModelForm):
if
self
.
data
.
get
(
field
)
is
not
None
:
changed_fields
.
append
(
field
)
print
(
changed_fields
)
cleaned_data
=
{
k
:
v
for
k
,
v
in
self
.
cleaned_data
.
items
()
if
k
in
changed_fields
}
users
=
cleaned_data
.
pop
(
'users'
,
''
)
...
...
This diff is collapsed.
Click to expand it.
apps/users/hands.py
View file @
f37b3316
...
...
@@ -6,7 +6,7 @@
Other module of this app shouldn't connect with other app.
:copyright: (c) 2014-201
7
by Jumpserver Team.
:copyright: (c) 2014-201
8
by Jumpserver Team.
:license: GPL v2, see LICENSE for more details.
"""
...
...
This diff is collapsed.
Click to expand it.
apps/users/serializers.py
View file @
f37b3316
...
...
@@ -71,3 +71,9 @@ class UserGroupUpdateMemeberSerializer(serializers.ModelSerializer):
model
=
UserGroup
fields
=
[
'id'
,
'users'
]
class
ChangeUserPasswordSerializer
(
serializers
.
ModelSerializer
):
class
Meta
:
model
=
User
fields
=
[
'password'
]
This diff is collapsed.
Click to expand it.
apps/users/templates/users/_user.html
View file @
f37b3316
...
...
@@ -11,8 +11,8 @@
<form
method=
"post"
class=
"form-horizontal"
action=
""
enctype=
"multipart/form-data"
>
{% csrf_token %}
<h3>
{% trans 'Account' %}
</h3>
{% bootstrap_field form.username layout="horizontal" %}
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.username layout="horizontal" %}
{% bootstrap_field form.email layout="horizontal" %}
{% bootstrap_field form.groups layout="horizontal" %}
...
...
@@ -32,12 +32,6 @@
<span
class=
"help-block "
>
{{ form.date_expired.errors }}
</span>
</div>
</div>
{#
<div
class=
"form-group"
>
#}
{#
<label
for=
"{{ form.enable_otp.id_for_label }}"
class=
"col-sm-2 control-label"
>
{% trans 'Enable OTP' %}
</label>
#}
{#
<div
class=
"col-sm-8"
>
#}
{# {{ form.enable_otp }}#}
{#
</div>
#}
{#
</div>
#}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Profile' %}
</h3>
{% bootstrap_field form.phone layout="horizontal" %}
...
...
This diff is collapsed.
Click to expand it.
apps/users/templates/users/forgot_password.html
View file @
f37b3316
...
...
@@ -55,7 +55,7 @@
Copyright Jumpserver.org
</div>
<div
class=
"col-md-6 text-right"
>
<small>
© 2014-201
7
</small>
<small>
© 2014-201
8
</small>
</div>
</div>
</div>
...
...
This diff is collapsed.
Click to expand it.
apps/users/templates/users/login.html
View file @
f37b3316
...
...
@@ -78,7 +78,7 @@
Copyright Jumpserver.org
</div>
<div
class=
"col-md-6 text-right"
>
<small>
© 2014-201
7
</small>
<small>
© 2014-201
8
</small>
</div>
</div>
</div>
...
...
This diff is collapsed.
Click to expand it.
apps/users/templates/users/reset_password.html
View file @
f37b3316
...
...
@@ -74,7 +74,7 @@
Copyright Jumpserver.org
</div>
<div
class=
"col-md-6 text-right"
>
<small>
© 2014-201
7
</small>
<small>
© 2014-201
8
</small>
</div>
</div>
</div>
...
...
This diff is collapsed.
Click to expand it.
apps/users/templates/users/user_detail.html
View file @
f37b3316
...
...
@@ -24,8 +24,9 @@
<li
class=
"pull-right"
>
<a
class=
"btn btn-outline btn-default"
href=
"{% url 'users:user-update' pk=user_object.id %}"
><i
class=
"fa fa-edit"
></i>
{% trans 'Update' %}
</a>
</li>
<li
class=
"pull-right"
>
<a
class=
"btn btn-outline
btn-danger btn-delete-user
"
>
<a
class=
"btn btn-outline
{% if request.user != user_object and user_object.username != "
admin
"
%}
btn-danger
btn-delete-user
{%
else
%}
disabled
{%
endif
%}
"
>
<i
class=
"fa fa-trash-o"
></i>
{% trans 'Delete' %}
</a>
</li>
...
...
@@ -128,7 +129,7 @@
<td><span
class=
"pull-right"
>
<div
class=
"switch"
>
<div
class=
"onoffswitch"
>
<input
type=
"checkbox"
{%
if
user_object
.
is_active
%}
checked
{%
endif
%}
class=
"onoffswitch-checkbox"
id=
"is_active"
>
<input
type=
"checkbox"
{%
if
user_object
.
is_active
%}
checked
{%
endif
%}
{%
if
request
.
user =
=
user_object
%}
disabled
{%
endif
%}
class=
"onoffswitch-checkbox"
id=
"is_active"
>
<label
class=
"onoffswitch-label"
for=
"is_active"
>
<span
class=
"onoffswitch-inner"
></span>
<span
class=
"onoffswitch-switch"
></span>
...
...
@@ -156,7 +157,7 @@
<td>
{% trans 'Send reset password mail' %}:
</td>
<td>
<span
class=
"pull-right"
>
<button
type=
"button"
class=
"btn btn-primary btn-xs"
id=
"btn-reset-password"
style=
"width: 54px"
>
{% trans 'Send' %}
</button>
<button
type=
"button"
class=
"btn btn-primary btn-xs"
{%
if
request
.
user =
=
user_object
%}
disabled=
"disabled"
{%
endif
%}
id=
"btn-reset-password"
style=
"width: 54px"
>
{% trans 'Send' %}
</button>
</span>
</td>
</tr>
...
...
@@ -164,7 +165,7 @@
<td>
{% trans 'Send reset ssh key mail' %}:
</td>
<td>
<span
class=
"pull-right"
>
<button
type=
"button"
class=
"btn btn-primary btn-xs"
id=
"btn-reset-pk"
style=
"width: 54px;"
>
{% trans 'Send' %}
</button>
<button
type=
"button"
class=
"btn btn-primary btn-xs"
{%
if
request
.
user =
=
user_object
%}
disabled=
"disabled"
{%
endif
%}
id=
"btn-reset-pk"
style=
"width: 54px;"
>
{% trans 'Send' %}
</button>
</span>
</td>
</tr>
...
...
@@ -331,7 +332,7 @@ $(document).ready(function() {
}
swal({
title: "{% trans '
Are
you
sure
?
' %}",
text: "{% trans "This will reset the user
'
s
password
.
A
password
-
reset
email
will
be
sent
to
the
user
\
's mailbox."
%}",
text: "{% trans "This will reset the user
password and send a reset mail"
%}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
...
...
@@ -356,7 +357,7 @@ $(document).ready(function() {
}
swal({
title: "{% trans '
Are
you
sure
?
' %}",
text: "{% trans '
This
will
reset
the
user
\
's public key.
'
%
}
",
text: "{% trans '
This
will
reset
the
user
public
key
and
send
a
reset
mail
' %}",
type: "warning",
showCancelButton: true,
confirmButtonColor: "#DD6B55",
...
...
This diff is collapsed.
Click to expand it.
apps/users/templates/users/user_list.html
View file @
f37b3316
...
...
@@ -76,7 +76,7 @@ function initTable() {
var
update_btn
=
'<a href="{% url "users:user-update" pk=DEFAULT_PK %}" class="btn btn-xs btn-info">{% trans "Update" %}</a>'
.
replace
(
'00000000-0000-0000-0000-000000000000'
,
cellData
);
var
del_btn
=
""
;
if
(
rowData
.
id
===
1
||
rowData
.
username
===
"admin"
||
rowData
.
username
===
"{{ user.username }}"
)
{
if
(
rowData
.
id
===
1
||
rowData
.
username
===
"admin"
||
rowData
.
username
===
"{{
request.
user.username }}"
)
{
del_btn
=
'<a class="btn btn-xs btn-danger m-l-xs" disabled>{% trans "Delete" %}</a>'
.
replace
(
'{{ DEFAULT_PK }}'
,
cellData
)
.
replace
(
'99991938'
,
rowData
.
name
);
...
...
This diff is collapsed.
Click to expand it.
apps/users/urls/api_urls.py
View file @
f37b3316
...
...
@@ -19,6 +19,8 @@ urlpatterns = [
url
(
r'^v1/token/$'
,
api
.
UserToken
.
as_view
(),
name
=
'user-token'
),
url
(
r'^v1/profile/$'
,
api
.
UserProfile
.
as_view
(),
name
=
'user-profile'
),
url
(
r'^v1/auth/$'
,
api
.
UserAuthApi
.
as_view
(),
name
=
'user-auth'
),
url
(
r'^v1/users/(?P<pk>[0-9a-zA-Z\-]{36})/password/$'
,
api
.
ChangeUserPasswordApi
.
as_view
(),
name
=
'change-user-password'
),
url
(
r'^v1/users/(?P<pk>[0-9a-zA-Z\-]{36})/password/reset/$'
,
api
.
UserResetPasswordApi
.
as_view
(),
name
=
'user-reset-password'
),
url
(
r'^v1/users/(?P<pk>[0-9a-zA-Z\-]{36})/pubkey/reset/$'
,
...
...
This diff is collapsed.
Click to expand it.
apps/users/utils.py
View file @
f37b3316
...
...
@@ -180,8 +180,10 @@ def validate_ip(ip):
def
write_login_log
(
username
,
type
=
''
,
ip
=
''
,
user_agent
=
''
):
if
not
(
ip
and
validate_ip
(
ip
)):
ip
=
'0.0.0.0'
city
=
get_ip_city
(
ip
)
ip
=
ip
[:
15
]
city
=
"Unknown"
else
:
city
=
get_ip_city
(
ip
)
LoginLog
.
objects
.
create
(
username
=
username
,
type
=
type
,
ip
=
ip
,
city
=
city
,
user_agent
=
user_agent
...
...
This diff is collapsed.
Click to expand it.
apps/users/views/login.py
View file @
f37b3316
...
...
@@ -53,8 +53,11 @@ class UserLoginView(FormView):
if
not
self
.
request
.
session
.
test_cookie_worked
():
return
HttpResponse
(
_
(
"Please enable cookies and try again."
))
auth_login
(
self
.
request
,
form
.
get_user
())
login_ip
=
self
.
request
.
META
.
get
(
'HTTP_X_FORWARDED_FOR'
)
or
\
self
.
request
.
META
.
get
(
'REMOTE_ADDR'
,
''
)
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
:
login_ip
=
self
.
request
.
META
.
get
(
'REMOTE_ADDR'
,
''
)
user_agent
=
self
.
request
.
META
.
get
(
'HTTP_USER_AGENT'
,
''
)
write_login_log_async
.
delay
(
self
.
request
.
user
.
username
,
type
=
'W'
,
...
...
This diff is collapsed.
Click to expand it.
docs/install.md
View file @
f37b3316
## Jumpserver v0.4.0 版本安装详细过程
### 环境
-
系统: CentOS 6.5 x86
\_
64 mini
-
Python: 版本 3.6 大部分功能兼容 2.7
-
安装目录
-
/opt/jumpserver
-
/opt/coco
#### 一. 环境准备
##### 1.1 安装基本工具和库
$ yum -y install sqlite-devel git epel-release
$ yum -y install sshpass python-devel libffi-devel openssl-devel
$ yum -y install gcc gcc-c++
##### 1.2 安装Python 3.6 和 虚拟环境
略
#### 二. Jumpserver安装
##### 2.1 下载仓库代码
$ cd /opt
$ git clone https://github.com/jumpserver/jumpserver.git
$ cd jumpserver
$ git checkout dev
##### 2.2 安装依赖
$ cd requirements
$ sudo yum -y install `cat rpm_requirements.txt`
$ pip install -r requirements.txt -i https://pypi.doubanio.com/simple
// 解决Mac安装ldap提示 Modules/LDAPObject.c:18:10: fatal error: 'sasl.h' file not found
pip install python-ldap \
--global-option=build_ext \
--global-option="-I$(xcrun --show-sdk-path)/usr/include/sasl"
##### 2.3 准备配置文件
$ cd ..
$ cp config_example.py config.py
$ vim config.py
// 默认使用的是 DevelpmentConfig 所以应该去修改这部分
class DevelopmentConfig(Config):
EMAIL_HOST = 'smtp.exmail.qq.com'
EMAIL_PORT = 465
EMAIL_HOST_USER = 'ask@jumpserver.org'
EMAIL_HOST_PASSWORD = 'xxx'
EMAIL_USE_SSL = True // 端口是 465 设置 True 否则 False
EMAIL_USE_TLS = False // 端口是 587 设置为 True 否则 False
SITE_URL = 'http://localhost:8080' // 发送邮件会使用这个地址
##### 2.4 初始化数据库
$ cd utils
$ sh make_migrations.sh
$ sh init_db.sh
##### 2.5 安装redis server
$ yum -y install redis
$ service redis start
**2.6 启动**
```
$ cd ..
$ python run_server.py
```
访问 http://ip:8080
账号密码: admin admin
**2.7 测试使用**
-
创建用户
会发送邮件,测试是否正常修改密码,登录
-
创建管理用户
创建一个管理用户, 创建资产时需要关联
-
创建资产
创建一个 资产,关联刚创建的管理用户
-
创建系统用户
系统用户是用来登录资产的,授权时需要
-
创建授权规则
关联用户,资产,系统用户 形成授权规则,授权的系统用户会自动推送到资产上
#### 三. 安装 SSH SERVER - COCO
**3.1 下载代码库**
```
$ cd /opt
$ git clone https://github.com/jumpserver/coco.git
```
**3.2 安装依赖**
```
$ cd coco
$ pip install -r requirements.txt # -i https://pypi.doubanio.com/simple
```
**3.3 启动**
```
$ python run_server.py
```
说明: Coco启动后会向jumpserver注册,请去 jumpserver页面 - 应用程序 - terminal - coco - Accept 允许, 这时 coco就 运行在 2222端口,可以ssh来连接
命令行:
```
ssh admin@YourServerIP -p2222
```
**3.5 测试**
-
测试登录 ssh server
-
测试跳转
-
测试命令记录回
[
1
]:
https://segmentfault.com/a/1190000000654227
[
2
]:
https://github.com/jumpserver/jumpserver.git
[
3
]:
https://github.com/jumpserver/coco.git
More see
[
安装文档
](
https://github.com/jumpserver/jumpserver/wiki/v0.5.0-%E5%9F%BA%E4%BA%8E-CentOS7
)
This diff is collapsed.
Click to expand it.
requirements/requirements.txt
View file @
f37b3316
...
...
@@ -56,6 +56,8 @@ uritemplate==3.0.0
urllib3==1.22
vine==1.1.4
gunicorn==19.7.1
django_celery_beat==1.1.0
https://github.com/celery/django-celery-beat/zipball/master#egg=django-celery-beat
#django_celery_beat==1.1.0
ephem==3.7.6.0
python-gssapi==0.6.4
jms-es-sdk
This diff is collapsed.
Click to expand it.
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