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
968b395b
Commit
968b395b
authored
Jan 22, 2018
by
ibuler
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'es' into dev
parents
7f188219
0a931bbf
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
478 additions
and
57 deletions
+478
-57
cluster.py
apps/assets/views/cluster.py
+0
-5
api.py
apps/common/api.py
+0
-5
fields.py
apps/common/fields.py
+0
-1
forms.py
apps/common/forms.py
+36
-8
models.py
apps/common/models.py
+19
-6
_add_terminal_command_storage_modal.html
...templates/common/_add_terminal_command_storage_modal.html
+21
-0
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
+130
-0
view_urls.py
apps/common/urls/view_urls.py
+1
-0
views.py
apps/common/views.py
+33
-2
settings.py
apps/jumpserver/settings.py
+14
-1
django.mo
apps/locale/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/locale/zh/LC_MESSAGES/django.po
+0
-0
api.py
apps/terminal/api.py
+14
-3
__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
+28
-0
forms.py
apps/terminal/forms.py
+1
-1
models.py
apps/terminal/models.py
+31
-0
serializers.py
apps/terminal/serializers.py
+3
-3
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
forms.py
apps/users/forms.py
+0
-1
No files found.
apps/assets/views/cluster.py
View file @
968b395b
...
@@ -60,11 +60,6 @@ class ClusterUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView)
...
@@ -60,11 +60,6 @@ class ClusterUpdateView(AdminUserRequiredMixin, SuccessMessageMixin, UpdateView)
success_url
=
reverse_lazy
(
'assets:cluster-list'
)
success_url
=
reverse_lazy
(
'assets:cluster-list'
)
success_message
=
update_success_msg
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
):
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
context
=
{
'app'
:
_
(
'assets'
),
'app'
:
_
(
'assets'
),
...
...
apps/common/api.py
View file @
968b395b
...
@@ -63,8 +63,6 @@ class LDAPTestingAPI(APIView):
...
@@ -63,8 +63,6 @@ class LDAPTestingAPI(APIView):
search_filter
=
serializer
.
validated_data
[
"AUTH_LDAP_SEARCH_FILTER"
]
search_filter
=
serializer
.
validated_data
[
"AUTH_LDAP_SEARCH_FILTER"
]
attr_map
=
serializer
.
validated_data
[
"AUTH_LDAP_USER_ATTR_MAP"
]
attr_map
=
serializer
.
validated_data
[
"AUTH_LDAP_USER_ATTR_MAP"
]
print
(
serializer
.
validated_data
)
try
:
try
:
attr_map
=
json
.
loads
(
attr_map
)
attr_map
=
json
.
loads
(
attr_map
)
except
json
.
JSONDecodeError
:
except
json
.
JSONDecodeError
:
...
@@ -77,9 +75,6 @@ class LDAPTestingAPI(APIView):
...
@@ -77,9 +75,6 @@ class LDAPTestingAPI(APIView):
except
Exception
as
e
:
except
Exception
as
e
:
return
Response
({
"error"
:
str
(
e
)},
status
=
401
)
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"
:
"*"
}),
ok
=
conn
.
search
(
search_ou
,
search_filter
%
({
"user"
:
"*"
}),
attributes
=
list
(
attr_map
.
values
()))
attributes
=
list
(
attr_map
.
values
()))
if
not
ok
:
if
not
ok
:
...
...
apps/common/fields.py
View file @
968b395b
...
@@ -18,7 +18,6 @@ class DictField(forms.Field):
...
@@ -18,7 +18,6 @@ class DictField(forms.Field):
# we don't need to handle that explicitly.
# we don't need to handle that explicitly.
if
isinstance
(
value
,
six
.
string_types
):
if
isinstance
(
value
,
six
.
string_types
):
try
:
try
:
print
(
value
)
value
=
json
.
loads
(
value
)
value
=
json
.
loads
(
value
)
return
value
return
value
except
json
.
JSONDecodeError
:
except
json
.
JSONDecodeError
:
...
...
apps/common/forms.py
View file @
968b395b
...
@@ -4,7 +4,9 @@ import json
...
@@ -4,7 +4,9 @@ import json
from
django
import
forms
from
django
import
forms
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.html
import
escape
from
django.db
import
transaction
from
django.db
import
transaction
from
django.conf
import
settings
from
.models
import
Setting
from
.models
import
Setting
from
.fields
import
DictField
from
.fields
import
DictField
...
@@ -30,28 +32,32 @@ def to_form_value(value):
...
@@ -30,28 +32,32 @@ def to_form_value(value):
class
BaseForm
(
forms
.
Form
):
class
BaseForm
(
forms
.
Form
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
()
.
__init__
(
*
args
,
**
kwargs
)
super
()
.
__init__
(
*
args
,
**
kwargs
)
settings
=
Setting
.
objects
.
all
()
db_
settings
=
Setting
.
objects
.
all
()
for
name
,
field
in
self
.
fields
.
items
():
for
name
,
field
in
self
.
fields
.
items
():
db_value
=
getattr
(
settings
,
name
)
.
value
db_value
=
getattr
(
db_settings
,
name
)
.
value
if
db_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
)
field
.
initial
=
to_form_value
(
db_value
)
elif
django_value
is
False
or
django_value
:
field
.
initial
=
django_value
def
save
(
self
):
def
save
(
self
,
category
=
"default"
):
if
not
self
.
is_bound
:
if
not
self
.
is_bound
:
raise
ValueError
(
"Form is not bound"
)
raise
ValueError
(
"Form is not bound"
)
settings
=
Setting
.
objects
.
all
()
db_
settings
=
Setting
.
objects
.
all
()
if
self
.
is_valid
():
if
self
.
is_valid
():
with
transaction
.
atomic
():
with
transaction
.
atomic
():
for
name
,
value
in
self
.
cleaned_data
.
items
():
for
name
,
value
in
self
.
cleaned_data
.
items
():
field
=
self
.
fields
[
name
]
field
=
self
.
fields
[
name
]
if
isinstance
(
field
.
widget
,
forms
.
PasswordInput
)
and
not
value
:
if
isinstance
(
field
.
widget
,
forms
.
PasswordInput
)
and
not
value
:
continue
continue
if
value
==
to_form_value
(
getattr
(
settings
,
name
)
.
value
):
if
value
==
to_form_value
(
getattr
(
db_
settings
,
name
)
.
value
):
continue
continue
defaults
=
{
defaults
=
{
'name'
:
name
,
'name'
:
name
,
'category'
:
category
,
'value'
:
to_model_value
(
value
)
'value'
:
to_model_value
(
value
)
}
}
Setting
.
objects
.
update_or_create
(
defaults
=
defaults
,
name
=
name
)
Setting
.
objects
.
update_or_create
(
defaults
=
defaults
,
name
=
name
)
...
@@ -126,6 +132,28 @@ class LDAPSettingForm(BaseForm):
...
@@ -126,6 +132,28 @@ class LDAPSettingForm(BaseForm):
AUTH_LDAP_START_TLS
=
forms
.
BooleanField
(
AUTH_LDAP_START_TLS
=
forms
.
BooleanField
(
label
=
_
(
"Use SSL"
),
initial
=
False
,
required
=
False
label
=
_
(
"Use SSL"
),
initial
=
False
,
required
=
False
)
)
AUTH_LDAP
=
forms
.
BooleanField
(
label
=
_
(
"Enable LDAP Auth"
),
initial
=
False
,
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"
)
)
)
apps/common/models.py
View file @
968b395b
...
@@ -2,6 +2,7 @@ import json
...
@@ -2,6 +2,7 @@ import json
import
ldap
import
ldap
from
django.db
import
models
from
django.db
import
models
from
django.db.utils
import
ProgrammingError
,
OperationalError
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.conf
import
settings
from
django.conf
import
settings
from
django_auth_ldap.config
import
LDAPSearch
from
django_auth_ldap.config
import
LDAPSearch
...
@@ -24,6 +25,7 @@ class SettingManager(models.Manager):
...
@@ -24,6 +25,7 @@ class SettingManager(models.Manager):
class
Setting
(
models
.
Model
):
class
Setting
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
"Name"
))
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
"Name"
))
value
=
models
.
TextField
(
verbose_name
=
_
(
"Value"
))
value
=
models
.
TextField
(
verbose_name
=
_
(
"Value"
))
category
=
models
.
CharField
(
max_length
=
128
,
default
=
"default"
)
enabled
=
models
.
BooleanField
(
verbose_name
=
_
(
"Enabled"
),
default
=
True
)
enabled
=
models
.
BooleanField
(
verbose_name
=
_
(
"Enabled"
),
default
=
True
)
comment
=
models
.
TextField
(
verbose_name
=
_
(
"Comment"
))
comment
=
models
.
TextField
(
verbose_name
=
_
(
"Comment"
))
...
@@ -33,17 +35,28 @@ class Setting(models.Model):
...
@@ -33,17 +35,28 @@ class Setting(models.Model):
return
self
.
name
return
self
.
name
@property
@property
def
value_
(
self
):
def
cleaned_value
(
self
):
try
:
try
:
return
json
.
loads
(
self
.
value
)
return
json
.
loads
(
self
.
value
)
except
json
.
JSONDecodeError
:
except
json
.
JSONDecodeError
:
return
None
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
@classmethod
def
refresh_all_settings
(
cls
):
def
refresh_all_settings
(
cls
):
settings_list
=
cls
.
objects
.
all
()
try
:
for
setting
in
settings_list
:
settings_list
=
cls
.
objects
.
all
()
setting
.
refresh_setting
()
for
setting
in
settings_list
:
setting
.
refresh_setting
()
except
(
ProgrammingError
,
OperationalError
):
pass
def
refresh_setting
(
self
):
def
refresh_setting
(
self
):
try
:
try
:
...
@@ -53,9 +66,9 @@ class Setting(models.Model):
...
@@ -53,9 +66,9 @@ class Setting(models.Model):
setattr
(
settings
,
self
.
name
,
value
)
setattr
(
settings
,
self
.
name
,
value
)
if
self
.
name
==
"AUTH_LDAP"
:
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
)
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
)
settings
.
AUTHENTICATION_BACKENDS
.
remove
(
settings
.
AUTH_LDAP_BACKEND
)
if
self
.
name
==
"AUTH_LDAP_SEARCH_FILTER"
:
if
self
.
name
==
"AUTH_LDAP_SEARCH_FILTER"
:
...
...
apps/common/templates/common/_add_terminal_command_storage_modal.html
0 → 100644
View file @
968b395b
{% extends '_modal.html' %}
{% load i18n %}
{% block modal_id %}add_command_storage_model{% endblock %}
{% block modal_title%}{% trans "Add command storage" %}{% endblock %}
{% block modal_body %}
<form
method=
"post"
action=
""
id=
"add_command_storage_form"
>
{% csrf_token %}
<div
class=
"form-group"
>
<label
class=
"control-label"
for=
"id_assets"
>
{% trans "Template" %}
</label>
<a
href=
"{% url 'assets:asset-export' %}"
style=
"display: block"
>
{% trans 'Download' %}
</a>
</div>
<div
class=
"form-group"
>
<label
class=
"control-label"
for=
"id_users"
>
{% trans "Asset csv file" %}
</label>
<input
id=
"id_assets"
type=
"file"
name=
"file"
/>
<span
class=
"help-block red-fonts"
>
{% trans 'If set id, will use this id update asset existed' %}
</span>
</div>
</form>
{% endblock %}
{% block modal_confirm_id %}btn_asset_import{% endblock %}
apps/common/templates/common/basic_setting.html
View file @
968b395b
...
@@ -20,6 +20,9 @@
...
@@ -20,6 +20,9 @@
<li>
<li>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
</li>
<li>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</ul>
</div>
</div>
<div
class=
"tab-content"
>
<div
class=
"tab-content"
>
...
...
apps/common/templates/common/email_setting.html
View file @
968b395b
...
@@ -20,6 +20,9 @@
...
@@ -20,6 +20,9 @@
<li>
<li>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
</li>
<li>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</ul>
</div>
</div>
<div
class=
"tab-content"
>
<div
class=
"tab-content"
>
...
...
apps/common/templates/common/ldap_setting.html
View file @
968b395b
...
@@ -20,6 +20,9 @@
...
@@ -20,6 +20,9 @@
<li
class=
"active"
>
<li
class=
"active"
>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
<a
href=
"{% url 'settings:ldap-setting' %}"
class=
"text-center"
><i
class=
"fa fa-archive"
></i>
{% trans 'LDAP setting' %}
</a>
</li>
</li>
<li>
<a
href=
"{% url 'settings:terminal-setting' %}"
class=
"text-center"
><i
class=
"fa fa-hdd-o"
></i>
{% trans 'Terminal setting' %}
</a>
</li>
</ul>
</ul>
</div>
</div>
<div
class=
"tab-content"
>
<div
class=
"tab-content"
>
...
...
apps/common/templates/common/terminal_setting.html
0 → 100644
View file @
968b395b
{% 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>
{% include 'common/_add_terminal_command_storage_modal.html' %}
{% 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 %}
apps/common/urls/view_urls.py
View file @
968b395b
...
@@ -10,4 +10,5 @@ urlpatterns = [
...
@@ -10,4 +10,5 @@ urlpatterns = [
url
(
r'^$'
,
views
.
BasicSettingView
.
as_view
(),
name
=
'basic-setting'
),
url
(
r'^$'
,
views
.
BasicSettingView
.
as_view
(),
name
=
'basic-setting'
),
url
(
r'^email/$'
,
views
.
EmailSettingView
.
as_view
(),
name
=
'email-setting'
),
url
(
r'^email/$'
,
views
.
EmailSettingView
.
as_view
(),
name
=
'email-setting'
),
url
(
r'^ldap/$'
,
views
.
LDAPSettingView
.
as_view
(),
name
=
'ldap-setting'
),
url
(
r'^ldap/$'
,
views
.
LDAPSettingView
.
as_view
(),
name
=
'ldap-setting'
),
url
(
r'^terminal/$'
,
views
.
TerminalSettingView
.
as_view
(),
name
=
'terminal-setting'
),
]
]
apps/common/views.py
View file @
968b395b
from
django.views.generic
import
View
,
TemplateView
from
django.views.generic
import
TemplateView
from
django.shortcuts
import
render
,
redirect
from
django.shortcuts
import
render
,
redirect
from
django.contrib
import
messages
from
django.contrib
import
messages
from
django.utils.translation
import
ugettext
as
_
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
.mixins
import
AdminUserRequiredMixin
from
.signals
import
ldap_auth_enable
from
.signals
import
ldap_auth_enable
...
@@ -86,3 +89,31 @@ class LDAPSettingView(AdminUserRequiredMixin, TemplateView):
...
@@ -86,3 +89,31 @@ class LDAPSettingView(AdminUserRequiredMixin, TemplateView):
context
=
self
.
get_context_data
()
context
=
self
.
get_context_data
()
context
.
update
({
"form"
:
form
})
context
.
update
({
"form"
:
form
})
return
render
(
request
,
self
.
template_name
,
context
)
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
)
apps/jumpserver/settings.py
View file @
968b395b
...
@@ -373,7 +373,20 @@ CAPTCHA_FOREGROUND_COLOR = '#001100'
...
@@ -373,7 +373,20 @@ CAPTCHA_FOREGROUND_COLOR = '#001100'
CAPTCHA_NOISE_FUNCTIONS
=
(
'captcha.helpers.noise_dots'
,)
CAPTCHA_NOISE_FUNCTIONS
=
(
'captcha.helpers.noise_dots'
,)
CAPTCHA_TEST_MODE
=
CONFIG
.
CAPTCHA_TEST_MODE
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
# Django bootstrap3 setting, more see http://django-bootstrap3.readthedocs.io/en/latest/settings.html
BOOTSTRAP3
=
{
BOOTSTRAP3
=
{
...
...
apps/locale/zh/LC_MESSAGES/django.mo
View file @
968b395b
No preview for this file type
apps/locale/zh/LC_MESSAGES/django.po
View file @
968b395b
This diff is collapsed.
Click to expand it.
apps/terminal/api.py
View file @
968b395b
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
#
#
from
collections
import
OrderedDict
from
collections
import
OrderedDict
import
copy
import
logging
import
logging
import
os
import
os
import
uuid
import
uuid
...
@@ -21,7 +20,8 @@ from .serializers import TerminalSerializer, StatusSerializer, \
...
@@ -21,7 +20,8 @@ from .serializers import TerminalSerializer, StatusSerializer, \
SessionSerializer
,
TaskSerializer
,
ReplaySerializer
SessionSerializer
,
TaskSerializer
,
ReplaySerializer
from
.hands
import
IsSuperUserOrAppUser
,
IsAppUser
,
\
from
.hands
import
IsSuperUserOrAppUser
,
IsAppUser
,
\
IsSuperUserOrAppUserOrUserReadonly
IsSuperUserOrAppUserOrUserReadonly
from
.backends
import
get_command_store
,
SessionCommandSerializer
from
.backends
import
get_command_store
,
get_multi_command_store
,
\
SessionCommandSerializer
logger
=
logging
.
getLogger
(
__file__
)
logger
=
logging
.
getLogger
(
__file__
)
...
@@ -197,6 +197,7 @@ class CommandViewSet(viewsets.ViewSet):
...
@@ -197,6 +197,7 @@ class CommandViewSet(viewsets.ViewSet):
"""
"""
command_store
=
get_command_store
()
command_store
=
get_command_store
()
multi_command_storage
=
get_multi_command_store
()
serializer_class
=
SessionCommandSerializer
serializer_class
=
SessionCommandSerializer
permission_classes
=
(
IsSuperUserOrAppUser
,)
permission_classes
=
(
IsSuperUserOrAppUser
,)
...
@@ -217,7 +218,7 @@ class CommandViewSet(viewsets.ViewSet):
...
@@ -217,7 +218,7 @@ class CommandViewSet(viewsets.ViewSet):
return
Response
({
"msg"
:
msg
},
status
=
401
)
return
Response
({
"msg"
:
msg
},
status
=
401
)
def
list
(
self
,
request
,
*
args
,
**
kwargs
):
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
)
serializer
=
self
.
serializer_class
(
queryset
,
many
=
True
)
return
Response
(
serializer
.
data
)
return
Response
(
serializer
.
data
)
...
@@ -260,3 +261,13 @@ class SessionReplayViewSet(viewsets.ViewSet):
...
@@ -260,3 +261,13 @@ class SessionReplayViewSet(viewsets.ViewSet):
return
redirect
(
url
)
return
redirect
(
url
)
else
:
else
:
return
HttpResponseNotFound
()
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
)
apps/terminal/backends/__init__.py
View file @
968b395b
...
@@ -2,9 +2,39 @@ from importlib import import_module
...
@@ -2,9 +2,39 @@ from importlib import import_module
from
django.conf
import
settings
from
django.conf
import
settings
from
.command.serializers
import
SessionCommandSerializer
from
.command.serializers
import
SessionCommandSerializer
TYPE_ENGINE_MAPPING
=
{
'elasticsearch'
:
'terminal.backends.command.es'
,
}
def
get_command_store
():
def
get_command_store
():
command_engine
=
import_module
(
settings
.
COMMAND_STORAGE_BACKEND
)
params
=
settings
.
COMMAND_STORAGE
command_store
=
command_engine
.
CommandStore
()
engine_class
=
import_module
(
params
[
'ENGINE'
])
return
command_store
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
apps/terminal/backends/command/base.py
View file @
968b395b
...
@@ -19,3 +19,9 @@ class CommandBase(object):
...
@@ -19,3 +19,9 @@ class CommandBase(object):
input
=
None
,
session
=
None
):
input
=
None
,
session
=
None
):
pass
pass
@abc.abstractmethod
def
count
(
self
,
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
pass
apps/terminal/backends/command/db.py
View file @
968b395b
...
@@ -8,7 +8,7 @@ from .base import CommandBase
...
@@ -8,7 +8,7 @@ from .base import CommandBase
class
CommandStore
(
CommandBase
):
class
CommandStore
(
CommandBase
):
def
__init__
(
self
):
def
__init__
(
self
,
params
):
from
terminal.models
import
Command
from
terminal.models
import
Command
self
.
model
=
Command
self
.
model
=
Command
...
@@ -37,9 +37,11 @@ class CommandStore(CommandBase):
...
@@ -37,9 +37,11 @@ class CommandStore(CommandBase):
))
))
return
self
.
model
.
objects
.
bulk_create
(
_commands
)
return
self
.
model
.
objects
.
bulk_create
(
_commands
)
def
filter
(
self
,
date_from
=
None
,
date_to
=
None
,
@staticmethod
user
=
None
,
asset
=
None
,
system_user
=
None
,
def
make_filter_kwargs
(
input
=
None
,
session
=
None
):
date_from
=
None
,
date_to
=
None
,
user
=
None
,
asset
=
None
,
system_user
=
None
,
input
=
None
,
session
=
None
):
filter_kwargs
=
{}
filter_kwargs
=
{}
date_from_default
=
timezone
.
now
()
-
datetime
.
timedelta
(
days
=
7
)
date_from_default
=
timezone
.
now
()
-
datetime
.
timedelta
(
days
=
7
)
date_to_default
=
timezone
.
now
()
date_to_default
=
timezone
.
now
()
...
@@ -60,10 +62,28 @@ class CommandStore(CommandBase):
...
@@ -60,10 +62,28 @@ class CommandStore(CommandBase):
if
session
:
if
session
:
filter_kwargs
[
'session'
]
=
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
)
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
()
apps/terminal/backends/command/es.py
0 → 100644
View file @
968b395b
# -*- 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
apps/terminal/backends/command/models.py
View file @
968b395b
...
@@ -18,5 +18,26 @@ class AbstractSessionCommand(models.Model):
...
@@ -18,5 +18,26 @@ class AbstractSessionCommand(models.Model):
class
Meta
:
class
Meta
:
abstract
=
True
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
):
def
__str__
(
self
):
return
self
.
input
return
self
.
input
apps/terminal/backends/command/multi.py
0 → 100644
View file @
968b395b
# -*- 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"
])
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
\ No newline at end of file
apps/terminal/forms.py
View file @
968b395b
...
@@ -10,7 +10,7 @@ from .models import Terminal
...
@@ -10,7 +10,7 @@ from .models import Terminal
class
TerminalForm
(
forms
.
ModelForm
):
class
TerminalForm
(
forms
.
ModelForm
):
class
Meta
:
class
Meta
:
model
=
Terminal
model
=
Terminal
fields
=
[
'name'
,
'remote_addr'
,
'ssh_port'
,
'http_port'
,
'comment'
]
fields
=
[
'name'
,
'remote_addr'
,
'ssh_port'
,
'http_port'
,
'comment'
,
'command_storage'
]
help_texts
=
{
help_texts
=
{
'ssh_port'
:
_
(
"Coco ssh listen port"
),
'ssh_port'
:
_
(
"Coco ssh listen port"
),
'http_port'
:
_
(
"Coco http/ws listen port"
),
'http_port'
:
_
(
"Coco http/ws listen port"
),
...
...
apps/terminal/models.py
View file @
968b395b
...
@@ -4,17 +4,28 @@ import uuid
...
@@ -4,17 +4,28 @@ import uuid
from
django.db
import
models
from
django.db
import
models
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.conf
import
settings
from
users.models
import
User
from
users.models
import
User
from
.backends.command.models
import
AbstractSessionCommand
from
.backends.command.models
import
AbstractSessionCommand
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
Terminal
(
models
.
Model
):
class
Terminal
(
models
.
Model
):
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
name
=
models
.
CharField
(
max_length
=
32
,
verbose_name
=
_
(
'Name'
))
name
=
models
.
CharField
(
max_length
=
32
,
verbose_name
=
_
(
'Name'
))
remote_addr
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Remote Address'
))
remote_addr
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
'Remote Address'
))
ssh_port
=
models
.
IntegerField
(
verbose_name
=
_
(
'SSH Port'
),
default
=
2222
)
ssh_port
=
models
.
IntegerField
(
verbose_name
=
_
(
'SSH Port'
),
default
=
2222
)
http_port
=
models
.
IntegerField
(
verbose_name
=
_
(
'HTTP Port'
),
default
=
5000
)
http_port
=
models
.
IntegerField
(
verbose_name
=
_
(
'HTTP Port'
),
default
=
5000
)
command_storage
=
models
.
CharField
(
max_length
=
128
,
verbose_name
=
_
(
"Command storage"
),
default
=
'default'
,
choices
=
get_all_command_storage
())
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
)
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_accepted
=
models
.
BooleanField
(
default
=
False
,
verbose_name
=
'Is Accepted'
)
is_deleted
=
models
.
BooleanField
(
default
=
False
)
is_deleted
=
models
.
BooleanField
(
default
=
False
)
...
@@ -33,6 +44,26 @@ class Terminal(models.Model):
...
@@ -33,6 +44,26 @@ class Terminal(models.Model):
self
.
user
.
is_active
=
active
self
.
user
.
is_active
=
active
self
.
user
.
save
()
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
):
def
create_app_user
(
self
):
random
=
uuid
.
uuid4
()
.
hex
[:
6
]
random
=
uuid
.
uuid4
()
.
hex
[:
6
]
user
,
access_key
=
User
.
create_app_user
(
name
=
"{}-{}"
.
format
(
self
.
name
,
random
),
comment
=
self
.
comment
)
user
,
access_key
=
User
.
create_app_user
(
name
=
"{}-{}"
.
format
(
self
.
name
,
random
),
comment
=
self
.
comment
)
...
...
apps/terminal/serializers.py
View file @
968b395b
...
@@ -5,7 +5,7 @@ from django.utils import timezone
...
@@ -5,7 +5,7 @@ from django.utils import timezone
from
rest_framework
import
serializers
from
rest_framework
import
serializers
from
.models
import
Terminal
,
Status
,
Session
,
Task
from
.models
import
Terminal
,
Status
,
Session
,
Task
from
.backends
import
get_command_store
from
.backends
import
get_
multi_
command_store
class
TerminalSerializer
(
serializers
.
ModelSerializer
):
class
TerminalSerializer
(
serializers
.
ModelSerializer
):
...
@@ -43,14 +43,14 @@ class TerminalSerializer(serializers.ModelSerializer):
...
@@ -43,14 +43,14 @@ class TerminalSerializer(serializers.ModelSerializer):
class
SessionSerializer
(
serializers
.
ModelSerializer
):
class
SessionSerializer
(
serializers
.
ModelSerializer
):
command_amount
=
serializers
.
SerializerMethodField
()
command_amount
=
serializers
.
SerializerMethodField
()
command_store
=
get_command_store
()
command_store
=
get_
multi_
command_store
()
class
Meta
:
class
Meta
:
model
=
Session
model
=
Session
fields
=
'__all__'
fields
=
'__all__'
def
get_command_amount
(
self
,
obj
):
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
):
class
StatusSerializer
(
serializers
.
ModelSerializer
):
...
...
apps/terminal/templates/terminal/terminal_modal_accept.html
View file @
968b395b
...
@@ -12,6 +12,7 @@
...
@@ -12,6 +12,7 @@
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.ssh_port layout="horizontal" %}
{% bootstrap_field form.ssh_port layout="horizontal" %}
{% bootstrap_field form.http_port layout="horizontal" %}
{% bootstrap_field form.http_port layout="horizontal" %}
{% bootstrap_field form.command_storage layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
</form>
</form>
...
...
apps/terminal/templates/terminal/terminal_update.html
View file @
968b395b
...
@@ -35,6 +35,7 @@
...
@@ -35,6 +35,7 @@
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.remote_addr layout="horizontal" %}
{% bootstrap_field form.ssh_port layout="horizontal" %}
{% bootstrap_field form.ssh_port layout="horizontal" %}
{% bootstrap_field form.http_port layout="horizontal" %}
{% bootstrap_field form.http_port layout="horizontal" %}
{% bootstrap_field form.command_storage layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
<h3>
{% trans 'Other' %}
</h3>
...
...
apps/terminal/templatetags/terminal_tags.py
View file @
968b395b
# ~*~ coding: utf-8 ~*~
# ~*~ coding: utf-8 ~*~
from
django
import
template
from
django
import
template
from
..backends
import
get_command_store
from
..backends
import
get_
multi_
command_store
register
=
template
.
Library
()
register
=
template
.
Library
()
command_store
=
get_command_store
()
command_store
=
get_
multi_
command_store
()
@register.filter
@register.filter
def
get_session_command_amount
(
session_id
):
def
get_session_command_amount
(
session_id
):
return
len
(
command_store
.
filter
(
session
=
str
(
session_id
)))
return
command_store
.
count
(
session
=
session_id
)
apps/terminal/urls/api_urls.py
View file @
968b395b
...
@@ -20,7 +20,8 @@ urlpatterns = [
...
@@ -20,7 +20,8 @@ urlpatterns = [
url
(
r'^v1/sessions/(?P<pk>[0-9a-zA-Z\-]{36})/replay/$'
,
url
(
r'^v1/sessions/(?P<pk>[0-9a-zA-Z\-]{36})/replay/$'
,
api
.
SessionReplayViewSet
.
as_view
({
'get'
:
'retrieve'
,
'post'
:
'create'
}),
api
.
SessionReplayViewSet
.
as_view
({
'get'
:
'retrieve'
,
'post'
:
'create'
}),
name
=
'session-replay'
),
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
urlpatterns
+=
router
.
urls
apps/terminal/views/command.py
View file @
968b395b
...
@@ -9,10 +9,10 @@ from django.utils.translation import ugettext as _
...
@@ -9,10 +9,10 @@ from django.utils.translation import ugettext as _
from
common.mixins
import
DatetimeSearchMixin
from
common.mixins
import
DatetimeSearchMixin
from
..models
import
Command
from
..models
import
Command
from
..
import
utils
from
..
import
utils
from
..backends
import
get_command_store
from
..backends
import
get_
multi_
command_store
__all__
=
[
'CommandListView'
]
__all__
=
[
'CommandListView'
]
comm
and_store
=
get
_command_store
()
comm
on_storage
=
get_multi
_command_store
()
class
CommandListView
(
DatetimeSearchMixin
,
ListView
):
class
CommandListView
(
DatetimeSearchMixin
,
ListView
):
...
@@ -39,7 +39,7 @@ class CommandListView(DatetimeSearchMixin, ListView):
...
@@ -39,7 +39,7 @@ class CommandListView(DatetimeSearchMixin, ListView):
filter_kwargs
[
'system_user'
]
=
self
.
system_user
filter_kwargs
[
'system_user'
]
=
self
.
system_user
if
self
.
command
:
if
self
.
command
:
filter_kwargs
[
'input'
]
=
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
return
queryset
def
get_context_data
(
self
,
**
kwargs
):
def
get_context_data
(
self
,
**
kwargs
):
...
...
apps/terminal/views/session.py
View file @
968b395b
...
@@ -10,7 +10,7 @@ from django.conf import settings
...
@@ -10,7 +10,7 @@ from django.conf import settings
from
users.utils
import
AdminUserRequiredMixin
from
users.utils
import
AdminUserRequiredMixin
from
common.mixins
import
DatetimeSearchMixin
from
common.mixins
import
DatetimeSearchMixin
from
..models
import
Session
,
Command
,
Terminal
from
..models
import
Session
,
Command
,
Terminal
from
..backends
import
get_command_store
from
..backends
import
get_
multi_
command_store
from
..
import
utils
from
..
import
utils
...
@@ -19,7 +19,7 @@ __all__ = [
...
@@ -19,7 +19,7 @@ __all__ = [
'SessionDetailView'
,
'SessionDetailView'
,
]
]
command_store
=
get_command_store
()
command_store
=
get_
multi_
command_store
()
class
SessionListView
(
AdminUserRequiredMixin
,
DatetimeSearchMixin
,
ListView
):
class
SessionListView
(
AdminUserRequiredMixin
,
DatetimeSearchMixin
,
ListView
):
...
...
apps/users/forms.py
View file @
968b395b
...
@@ -172,7 +172,6 @@ class UserBulkUpdateForm(forms.ModelForm):
...
@@ -172,7 +172,6 @@ class UserBulkUpdateForm(forms.ModelForm):
if
self
.
data
.
get
(
field
)
is
not
None
:
if
self
.
data
.
get
(
field
)
is
not
None
:
changed_fields
.
append
(
field
)
changed_fields
.
append
(
field
)
print
(
changed_fields
)
cleaned_data
=
{
k
:
v
for
k
,
v
in
self
.
cleaned_data
.
items
()
cleaned_data
=
{
k
:
v
for
k
,
v
in
self
.
cleaned_data
.
items
()
if
k
in
changed_fields
}
if
k
in
changed_fields
}
users
=
cleaned_data
.
pop
(
'users'
,
''
)
users
=
cleaned_data
.
pop
(
'users'
,
''
)
...
...
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