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
0665644f
Unverified
Commit
0665644f
authored
Oct 12, 2018
by
老广
Committed by
GitHub
Oct 12, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1905 from jumpserver/dev
支持命令过滤
parents
1341983f
7bafa546
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
898 additions
and
28 deletions
+898
-28
__init__.py
apps/__init__.py
+1
-1
__init__.py
apps/assets/api/__init__.py
+1
-0
cmd_filter.py
apps/assets/api/cmd_filter.py
+32
-0
system_user.py
apps/assets/api/system_user.py
+16
-3
__init__.py
apps/assets/forms/__init__.py
+1
-0
asset.py
apps/assets/forms/asset.py
+2
-2
cmd_filter.py
apps/assets/forms/cmd_filter.py
+27
-0
user.py
apps/assets/forms/user.py
+7
-3
__init__.py
apps/assets/models/__init__.py
+2
-1
asset.py
apps/assets/models/asset.py
+1
-1
cmd_filter.py
apps/assets/models/cmd_filter.py
+60
-0
node.py
apps/assets/models/node.py
+4
-6
user.py
apps/assets/models/user.py
+9
-1
__init__.py
apps/assets/serializers/__init__.py
+1
-0
cmd_filter.py
apps/assets/serializers/cmd_filter.py
+23
-0
_system_user.html
apps/assets/templates/assets/_system_user.html
+5
-0
admin_user_detail.html
apps/assets/templates/assets/admin_user_detail.html
+1
-1
cmd_filter_create_update.html
apps/assets/templates/assets/cmd_filter_create_update.html
+20
-0
cmd_filter_detail.html
apps/assets/templates/assets/cmd_filter_detail.html
+168
-0
cmd_filter_list.html
apps/assets/templates/assets/cmd_filter_list.html
+89
-0
cmd_filter_rule_create_update.html
...ssets/templates/assets/cmd_filter_rule_create_update.html
+75
-0
cmd_filter_rule_list.html
apps/assets/templates/assets/cmd_filter_rule_list.html
+115
-0
system_user_asset.html
apps/assets/templates/assets/system_user_asset.html
+2
-1
system_user_detail.html
apps/assets/templates/assets/system_user_detail.html
+0
-0
api_urls.py
apps/assets/urls/api_urls.py
+13
-2
views_urls.py
apps/assets/urls/views_urls.py
+8
-0
__init__.py
apps/assets/views/__init__.py
+1
-0
cmd_filter.py
apps/assets/views/cmd_filter.py
+169
-0
system_user.py
apps/assets/views/system_user.py
+4
-3
fields.py
apps/common/fields.py
+18
-0
common_tags.py
apps/common/templatetags/common_tags.py
+6
-0
django.mo
apps/locale/zh/LC_MESSAGES/django.mo
+0
-0
django.po
apps/locale/zh/LC_MESSAGES/django.po
+0
-0
views.py
apps/orgs/views.py
+2
-1
_footer.html
apps/templates/_footer.html
+1
-1
_nav.html
apps/templates/_nav.html
+6
-0
views_urls.py
apps/terminal/urls/views_urls.py
+1
-0
terminal.py
apps/terminal/views/terminal.py
+6
-1
requirements.txt
requirements/requirements.txt
+1
-0
No files found.
apps/__init__.py
View file @
0665644f
...
...
@@ -2,4 +2,4 @@
# -*- coding: utf-8 -*-
#
__version__
=
"1.4.
2
"
__version__
=
"1.4.
3
"
apps/assets/api/__init__.py
View file @
0665644f
...
...
@@ -4,3 +4,4 @@ from .label import *
from
.system_user
import
*
from
.node
import
*
from
.domain
import
*
from
.cmd_filter
import
*
apps/assets/api/cmd_filter.py
0 → 100644
View file @
0665644f
# -*- coding: utf-8 -*-
#
from
rest_framework_bulk
import
BulkModelViewSet
from
django.shortcuts
import
get_object_or_404
from
..hands
import
IsOrgAdmin
from
..models
import
CommandFilter
,
CommandFilterRule
from
..
import
serializers
__all__
=
[
'CommandFilterViewSet'
,
'CommandFilterRuleViewSet'
]
class
CommandFilterViewSet
(
BulkModelViewSet
):
permission_classes
=
(
IsOrgAdmin
,)
queryset
=
CommandFilter
.
objects
.
all
()
serializer_class
=
serializers
.
CommandFilterSerializer
class
CommandFilterRuleViewSet
(
BulkModelViewSet
):
permission_classes
=
(
IsOrgAdmin
,)
serializer_class
=
serializers
.
CommandFilterRuleSerializer
def
get_queryset
(
self
):
fpk
=
self
.
kwargs
.
get
(
'filter_pk'
)
if
not
fpk
:
return
CommandFilterRule
.
objects
.
none
()
group
=
get_object_or_404
(
CommandFilter
,
pk
=
fpk
)
return
group
.
rules
.
all
()
.
order_by
(
'priority'
)
apps/assets/api/system_user.py
View file @
0665644f
...
...
@@ -33,7 +33,8 @@ __all__ = [
'SystemUserViewSet'
,
'SystemUserAuthInfoApi'
,
'SystemUserPushApi'
,
'SystemUserTestConnectiveApi'
,
'SystemUserAssetsListView'
,
'SystemUserPushToAssetApi'
,
'SystemUserTestAssetConnectabilityApi'
,
'SystemUserTestAssetConnectabilityApi'
,
'SystemUserCommandFilterRuleListApi'
,
]
...
...
@@ -126,4 +127,17 @@ class SystemUserTestAssetConnectabilityApi(generics.RetrieveAPIView):
asset_id
=
self
.
kwargs
.
get
(
'aid'
)
asset
=
get_object_or_404
(
Asset
,
id
=
asset_id
)
task
=
test_system_user_connectability_a_asset
.
delay
(
system_user
,
asset
)
return
Response
({
"task"
:
task
.
id
})
\ No newline at end of file
return
Response
({
"task"
:
task
.
id
})
class
SystemUserCommandFilterRuleListApi
(
generics
.
ListAPIView
):
permission_classes
=
(
IsOrgAdminOrAppUser
,)
def
get_serializer_class
(
self
):
from
..serializers
import
CommandFilterRuleSerializer
return
CommandFilterRuleSerializer
def
get_queryset
(
self
):
pk
=
self
.
kwargs
.
get
(
'pk'
,
None
)
system_user
=
get_object_or_404
(
SystemUser
,
pk
=
pk
)
return
system_user
.
cmd_filter_rules
apps/assets/forms/__init__.py
View file @
0665644f
...
...
@@ -4,3 +4,4 @@ from .asset import *
from
.label
import
*
from
.user
import
*
from
.domain
import
*
from
.cmd_filter
import
*
apps/assets/forms/asset.py
View file @
0665644f
...
...
@@ -48,7 +48,7 @@ class AssetCreateForm(OrgModelForm):
'root or other NOPASSWD sudo privilege user existed in asset,'
'If asset is windows or other set any one, more see admin user left menu'
),
# 'platform': _("* required Must set exact system platform, Windows, Linux ...
"),
'platform'
:
_
(
"Windows 2016 RDP protocol is different, If is window 2016, set it
"
),
'domain'
:
_
(
"If your have some network not connect with each other, you can set domain"
)
}
...
...
@@ -88,7 +88,7 @@ class AssetUpdateForm(OrgModelForm):
'root or other NOPASSWD sudo privilege user existed in asset,'
'If asset is windows or other set any one, more see admin user left menu'
),
# 'platform': _("* required Must set exact system platform, Windows, Linux ...
"),
'platform'
:
_
(
"Windows 2016 RDP protocol is different, If is window 2016, set it
"
),
'domain'
:
_
(
"If your have some network not connect with each other, you can set domain"
)
}
...
...
apps/assets/forms/cmd_filter.py
0 → 100644
View file @
0665644f
# -*- coding: utf-8 -*-
#
from
django
import
forms
from
orgs.mixins
import
OrgModelForm
from
..models
import
CommandFilter
,
CommandFilterRule
__all__
=
[
'CommandFilterForm'
,
'CommandFilterRuleForm'
]
class
CommandFilterForm
(
OrgModelForm
):
class
Meta
:
model
=
CommandFilter
fields
=
[
'name'
,
'comment'
]
class
CommandFilterRuleForm
(
OrgModelForm
):
class
Meta
:
model
=
CommandFilterRule
fields
=
[
'filter'
,
'type'
,
'content'
,
'priority'
,
'action'
,
'comment'
]
widgets
=
{
'content'
:
forms
.
Textarea
(
attrs
=
{
'placeholder'
:
'eg:
\r\n
reboot
\r\n
rm -rf'
}),
}
apps/assets/forms/user.py
View file @
0665644f
...
...
@@ -3,8 +3,9 @@
from
django
import
forms
from
django.utils.translation
import
gettext_lazy
as
_
from
..models
import
AdminUser
,
SystemUser
from
common.utils
import
validate_ssh_private_key
,
ssh_pubkey_gen
,
get_logger
from
orgs.mixins
import
OrgModelForm
from
..models
import
AdminUser
,
SystemUser
logger
=
get_logger
(
__file__
)
__all__
=
[
...
...
@@ -85,7 +86,7 @@ class AdminUserForm(PasswordAndKeyAuthForm):
}
class
SystemUserForm
(
PasswordAndKeyAuthForm
):
class
SystemUserForm
(
OrgModelForm
,
PasswordAndKeyAuthForm
):
# Admin user assets define, let user select, save it in form not in view
auto_generate_key
=
forms
.
BooleanField
(
initial
=
True
,
required
=
False
)
...
...
@@ -136,11 +137,14 @@ class SystemUserForm(PasswordAndKeyAuthForm):
fields
=
[
'name'
,
'username'
,
'protocol'
,
'auto_generate_key'
,
'password'
,
'private_key_file'
,
'auto_push'
,
'sudo'
,
'comment'
,
'shell'
,
'priority'
,
'login_mode'
,
'comment'
,
'shell'
,
'priority'
,
'login_mode'
,
'cmd_filters'
,
]
widgets
=
{
'name'
:
forms
.
TextInput
(
attrs
=
{
'placeholder'
:
_
(
'Name'
)}),
'username'
:
forms
.
TextInput
(
attrs
=
{
'placeholder'
:
_
(
'Username'
)}),
'cmd_filters'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Command filter'
)
}),
}
help_texts
=
{
'name'
:
'* required'
,
...
...
apps/assets/models/__init__.py
View file @
0665644f
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
from
.user
import
AdminUser
,
SystemUser
from
.user
import
*
from
.label
import
Label
from
.cluster
import
*
from
.group
import
*
from
.domain
import
*
from
.node
import
*
from
.asset
import
*
from
.cmd_filter
import
*
from
.utils
import
*
apps/assets/models/asset.py
View file @
0665644f
...
...
@@ -15,7 +15,7 @@ from django.core.cache import cache
from
..const
import
ASSET_ADMIN_CONN_CACHE_KEY
from
.user
import
AdminUser
,
SystemUser
from
orgs.mixins
import
OrgModelMixin
,
OrgManager
from
orgs.mixins
import
OrgModelMixin
,
OrgManager
__all__
=
[
'Asset'
]
logger
=
logging
.
getLogger
(
__name__
)
...
...
apps/assets/models/cmd_filter.py
0 → 100644
View file @
0665644f
# -*- coding: utf-8 -*-
#
import
uuid
from
django.db
import
models
from
django.core.validators
import
MinValueValidator
,
MaxValueValidator
from
django.utils.translation
import
ugettext_lazy
as
_
from
orgs.mixins
import
OrgModelMixin
__all__
=
[
'CommandFilter'
,
'CommandFilterRule'
]
class
CommandFilter
(
OrgModelMixin
):
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
name
=
models
.
CharField
(
max_length
=
64
,
verbose_name
=
_
(
"Name"
))
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Is active'
))
comment
=
models
.
TextField
(
blank
=
True
,
default
=
''
,
verbose_name
=
_
(
"Comment"
))
date_created
=
models
.
DateTimeField
(
auto_now_add
=
True
)
date_updated
=
models
.
DateTimeField
(
auto_now
=
True
)
created_by
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
default
=
''
,
verbose_name
=
_
(
'Created by'
))
def
__str__
(
self
):
return
self
.
name
class
CommandFilterRule
(
OrgModelMixin
):
TYPE_REGEX
=
'regex'
TYPE_COMMAND
=
'command'
TYPE_CHOICES
=
(
(
TYPE_REGEX
,
_
(
'Regex'
)),
(
TYPE_COMMAND
,
_
(
'Command'
)),
)
ACTION_DENY
,
ACTION_ALLOW
=
range
(
2
)
ACTION_CHOICES
=
(
(
ACTION_DENY
,
_
(
'Deny'
)),
(
ACTION_ALLOW
,
_
(
'Allow'
)),
)
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
filter
=
models
.
ForeignKey
(
'CommandFilter'
,
on_delete
=
models
.
CASCADE
,
verbose_name
=
_
(
"Filter"
),
related_name
=
'rules'
)
type
=
models
.
CharField
(
max_length
=
16
,
default
=
TYPE_COMMAND
,
choices
=
TYPE_CHOICES
,
verbose_name
=
_
(
"Type"
))
priority
=
models
.
IntegerField
(
default
=
50
,
verbose_name
=
_
(
"Priority"
),
help_text
=
_
(
"1-100, the lower will be match first"
),
validators
=
[
MinValueValidator
(
1
),
MaxValueValidator
(
100
)])
content
=
models
.
TextField
(
max_length
=
1024
,
verbose_name
=
_
(
"Content"
),
help_text
=
_
(
"One line one command"
))
action
=
models
.
IntegerField
(
default
=
ACTION_DENY
,
choices
=
ACTION_CHOICES
,
verbose_name
=
_
(
"Action"
))
comment
=
models
.
CharField
(
max_length
=
64
,
blank
=
True
,
default
=
''
,
verbose_name
=
_
(
"Comment"
))
date_created
=
models
.
DateTimeField
(
auto_now_add
=
True
)
date_updated
=
models
.
DateTimeField
(
auto_now
=
True
)
created_by
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
default
=
''
,
verbose_name
=
_
(
'Created by'
))
class
Meta
:
ordering
=
(
'priority'
,
'action'
)
def
__str__
(
self
):
return
'{}
%
{}'
.
format
(
self
.
type
,
self
.
content
)
apps/assets/models/node.py
View file @
0665644f
...
...
@@ -38,12 +38,10 @@ class Node(OrgModelMixin):
return
True
self_key
=
[
int
(
k
)
for
k
in
self
.
key
.
split
(
':'
)]
other_key
=
[
int
(
k
)
for
k
in
other
.
key
.
split
(
':'
)]
if
len
(
self_key
)
<
len
(
other_key
):
return
True
elif
len
(
self_key
)
>
len
(
other_key
):
return
False
else
:
return
self_key
[
-
1
]
<
other_key
[
-
1
]
return
self_key
.
__lt__
(
other_key
)
def
__lt__
(
self
,
other
):
return
not
self
.
__gt__
(
other
)
@property
def
name
(
self
):
...
...
apps/assets/models/user.py
View file @
0665644f
...
...
@@ -3,7 +3,6 @@
#
import
logging
import
uuid
from
django.core.cache
import
cache
from
django.db
import
models
...
...
@@ -118,6 +117,7 @@ class SystemUser(AssetUser):
sudo
=
models
.
TextField
(
default
=
'/bin/whoami'
,
verbose_name
=
_
(
'Sudo'
))
shell
=
models
.
CharField
(
max_length
=
64
,
default
=
'/bin/bash'
,
verbose_name
=
_
(
'Shell'
))
login_mode
=
models
.
CharField
(
choices
=
LOGIN_MODE_CHOICES
,
default
=
AUTO_LOGIN
,
max_length
=
10
,
verbose_name
=
_
(
'Login mode'
))
cmd_filters
=
models
.
ManyToManyField
(
'CommandFilter'
,
related_name
=
'system_users'
,
verbose_name
=
_
(
"Command filter"
),
blank
=
True
)
cache_key
=
"__SYSTEM_USER_CACHED_{}"
...
...
@@ -163,6 +163,14 @@ class SystemUser(AssetUser):
def
expire_cache
(
self
):
cache
.
delete
(
self
.
cache_key
.
format
(
self
.
id
))
@property
def
cmd_filter_rules
(
self
):
from
.cmd_filter
import
CommandFilterRule
rules
=
CommandFilterRule
.
objects
.
filter
(
filter__in
=
self
.
cmd_filters
.
all
()
)
.
order_by
(
'priority'
)
.
distinct
()
return
rules
@classmethod
def
get_system_user_by_id_or_cached
(
cls
,
sid
):
cached
=
cache
.
get
(
cls
.
cache_key
.
format
(
sid
))
...
...
apps/assets/serializers/__init__.py
View file @
0665644f
...
...
@@ -7,3 +7,4 @@ from .label import *
from
.system_user
import
*
from
.node
import
*
from
.domain
import
*
from
.cmd_filter
import
*
apps/assets/serializers/cmd_filter.py
0 → 100644
View file @
0665644f
# -*- coding: utf-8 -*-
#
from
rest_framework
import
serializers
from
common.fields
import
ChoiceDisplayField
from
..models
import
CommandFilter
,
CommandFilterRule
,
SystemUser
class
CommandFilterSerializer
(
serializers
.
ModelSerializer
):
rules
=
serializers
.
PrimaryKeyRelatedField
(
queryset
=
CommandFilterRule
.
objects
.
all
(),
many
=
True
)
system_users
=
serializers
.
PrimaryKeyRelatedField
(
queryset
=
SystemUser
.
objects
.
all
(),
many
=
True
)
class
Meta
:
model
=
CommandFilter
fields
=
'__all__'
class
CommandFilterRuleSerializer
(
serializers
.
ModelSerializer
):
serializer_choice_field
=
ChoiceDisplayField
class
Meta
:
model
=
CommandFilterRule
fields
=
'__all__'
apps/assets/templates/assets/_system_user.html
View file @
0665644f
...
...
@@ -62,6 +62,10 @@
</div>
</div>
{% endblock %}
<div
id=
"command-filter-block"
>
<h3>
{% trans 'Command filter' %}
</h3>
{% bootstrap_field form.cmd_filters layout="horizontal" %}
</div>
<h3>
{% trans 'Other' %}
</h3>
{% bootstrap_field form.sudo layout="horizontal" %}
{% bootstrap_field form.shell layout="horizontal" %}
...
...
@@ -101,6 +105,7 @@ var need_change_field_login_mode = [
function
protocolChange
()
{
if
(
$
(
protocol_id
+
" option:selected"
).
text
()
===
'rdp'
)
{
$
(
'.auth-fields'
).
removeClass
(
'hidden'
);
$
(
'#command-filter-block'
).
addClass
(
'hidden'
);
$
.
each
(
need_change_field
,
function
(
index
,
value
)
{
$
(
value
).
closest
(
'.form-group'
).
addClass
(
'hidden'
)
});
...
...
apps/assets/templates/assets/admin_user_detail.html
View file @
0665644f
...
...
@@ -90,7 +90,7 @@
<td
colspan=
"2"
class=
"no-borders"
>
<select
data-placeholder=
"{% trans 'Select nodes' %}"
id=
"nodes_selected"
class=
"select2"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
>
{% for node in nodes %}
<option
value=
"{{ node.id }}"
id=
"opt_{{ node.id }}"
>
{{ node
.value
}}
</option>
<option
value=
"{{ node.id }}"
id=
"opt_{{ node.id }}"
>
{{ node }}
</option>
{% endfor %}
</select>
</td>
...
...
apps/assets/templates/assets/cmd_filter_create_update.html
0 → 100644
View file @
0665644f
{% extends '_base_create_update.html' %}
{% load static %}
{% load bootstrap3 %}
{% load i18n %}
{% block form %}
<form
id=
"groupForm"
method=
"post"
class=
"form-horizontal"
>
{% csrf_token %}
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.comment layout="horizontal" %}
<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>
{% endblock %}
apps/assets/templates/assets/cmd_filter_detail.html
0 → 100644
View file @
0665644f
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link
href=
'{% static "css/plugins/select2/select2.min.css" %}'
rel=
"stylesheet"
>
<script
src=
'{% static "js/plugins/select2/select2.full.min.js" %}'
></script>
{% endblock %}
{% 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
class=
"active"
>
<a
href=
"{% url 'assets:cmd-filter-detail' pk=object.id %}"
class=
"text-center"
>
<i
class=
"fa fa-laptop"
></i>
{% trans 'Detail' %}
</a>
</li>
<li>
<li>
<a
href=
"{% url 'assets:cmd-filter-rule-list' pk=object.id %}"
class=
"text-center"
>
<i
class=
"fa fa-laptop"
></i>
{% trans 'Rules' %}
</a>
</li>
<li
class=
"pull-right"
>
<a
class=
"btn btn-outline btn-default"
href=
"{% url 'assets:cmd-filter-update' pk=object.id %}"
><i
class=
"fa fa-edit"
></i>
{% trans 'Update' %}
</a>
</li>
<li
class=
"pull-right"
>
<a
class=
"btn btn-outline btn-danger btn-del"
>
<i
class=
"fa fa-trash-o"
></i>
{% trans 'Delete' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
<div
class=
"col-sm-8"
style=
"padding-left: 0;"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
class=
"label"
><b>
{{ object.name }}
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<ul
class=
"dropdown-menu dropdown-user"
>
</ul>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<table
class=
"table"
>
<tbody>
<tr
class=
"no-borders-tr"
>
<td>
{% trans 'Name' %}:
</td>
<td><b>
{{ object.name }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Comment' %}:
</td>
<td><b>
{{ object.comment }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Date created' %}:
</td>
<td><b>
{{ object.date_created }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Date updated' %}:
</td>
<td><b>
{{ object.date_updated }}
</b></td>
</tr>
<tr>
<td>
{% trans 'Created by' %}:
</td>
<td><b>
{{ object.created_by }}
</b></td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div
class=
"col-sm-4"
style=
"padding-left: 0; padding-right: 0"
>
<div
class=
"panel panel-primary"
>
<div
class=
"panel-heading"
>
<i
class=
"fa fa-info-circle"
></i>
{% trans 'System users' %}
</div>
<div
class=
"panel-body"
>
<table
class=
"table group_edit"
id=
"table-clusters"
>
<tbody>
<form>
<tr>
<td
colspan=
"2"
class=
"no-borders"
>
<select
data-placeholder=
"{% trans 'Binding to system user' %}"
id=
"system_users_selected"
class=
"select2"
style=
"width: 100%"
multiple=
""
tabindex=
"4"
>
{% for system_user in system_users_remain %}
<option
value=
"{{ system_user.id }}"
id=
"opt_{{ system_user.id }}"
>
{{ system_user }}
</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td
colspan=
"2"
class=
"no-borders"
>
<button
type=
"button"
class=
"btn btn-primary btn-sm"
id=
"btn-binding-system-users"
>
{% trans 'Confirm' %}
</button>
</td>
</tr>
</form>
{% for system_user in object.system_users.all %}
<tr>
<td><b
class=
"bdg-system-users"
data-gid=
{{
system_user
.
id
}}
>
{{ system_user }}
</b></td>
<td>
<button
class=
"btn btn-danger pull-right btn-xs btn-unbound-system-user"
data-gid=
{{
system_user
.
id
}}
type=
"button"
><i
class=
"fa fa-minus"
></i></button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
function
updateCMDFilterSystemUsers
(
system_users
)
{
var
the_url
=
"{% url 'api-assets:cmd-filter-detail' pk=object.id %}"
;
var
body
=
{
system_users
:
Object
.
assign
([],
system_users
)
};
var
success
=
function
(
data
)
{
location
.
reload
();
};
APIUpdateAttr
({
url
:
the_url
,
body
:
JSON
.
stringify
(
body
),
method
:
'PATCH'
,
success
:
success
});
}
$
(
document
).
ready
(
function
()
{
$
(
".select2"
).
select2
();
}).
on
(
'click'
,
'#btn-binding-system-users'
,
function
()
{
var
origin_system_users
=
$
.
map
(
$
(
".bdg-system-users"
),
function
(
s
)
{
return
$
(
s
).
data
(
'gid'
)
});
var
new_selected_system_users_id
=
$
.
map
(
$
(
"#system_users_selected"
).
select2
(
'data'
),
function
(
s
)
{
return
s
.
id
;
});
var
system_users
=
origin_system_users
.
concat
(
new_selected_system_users_id
);
updateCMDFilterSystemUsers
(
system_users
)
}).
on
(
'click'
,
'.btn-unbound-system-user'
,
function
()
{
var
unbound_system_user
=
$
(
this
).
data
(
'gid'
);
var
origin_system_users
=
$
.
map
(
$
(
".bdg-system-users"
),
function
(
s
)
{
return
$
(
s
).
data
(
'gid'
)
});
var
system_users
=
$
.
grep
(
origin_system_users
,
function
(
n
,
i
)
{
return
n
!==
unbound_system_user
});
updateCMDFilterSystemUsers
(
system_users
)
})
</script>
{% endblock %}
apps/assets/templates/assets/cmd_filter_list.html
0 → 100644
View file @
0665644f
{% extends '_base_list.html' %}
{% load i18n static %}
{% block table_search %}{% endblock %}
{% block help_message %}
<div
class=
"alert alert-info help-message"
>
{% trans 'System user bound some command filter, each command filter has some rules,'%}
{% trans 'When user login asset with this system user, then run a command,' %}
{% trans 'The command will be filter by rules, higher priority(lower number) rule run first,' %}
{% trans 'When a rule matched, if rule action is allow, then allow command execute,' %}
{% trans 'else if action is deny, then command with be deny,' %}
{% trans 'else match next rule, if none matched, allowed' %}
</div>
{% endblock %}
{% block table_container %}
<div
class=
"uc pull-left m-r-5"
>
<a
href=
"{% url 'assets:cmd-filter-create' %}"
class=
"btn btn-sm btn-primary"
>
{% trans "Create command filter" %}
</a>
</div>
<table
class=
"table table-striped table-bordered table-hover "
id=
"cmd_filter_list_table"
>
<thead>
<tr>
<th
class=
"text-center"
>
<input
type=
"checkbox"
id=
"check_all"
class=
"ipt_check_all"
>
</th>
<th
class=
"text-center"
>
{% trans 'Name' %}
</th>
<th
class=
"text-center"
>
{% trans 'Rules' %}
</th>
<th
class=
"text-center"
>
{% trans 'System users' %}
</th>
<th
class=
"text-center"
>
{% trans 'Comment' %}
</th>
<th
class=
"text-center"
>
{% trans 'Action' %}
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
<script>
function
initTable
()
{
var
options
=
{
ele
:
$
(
'#cmd_filter_list_table'
),
columnDefs
:
[
{
targets
:
1
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
detail_btn
=
'<a href="{% url '
assets
:
cmd
-
filter
-
detail
' pk=DEFAULT_PK %}">'
+
cellData
+
'</a>'
;
$
(
td
).
html
(
detail_btn
.
replace
(
'{{ DEFAULT_PK }}'
,
rowData
.
id
));
}},
{
targets
:
2
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
filters_list_btn
=
'<a href="{% url "assets:cmd-filter-rule-list" pk=DEFAULT_PK %}">'
+
cellData
.
length
+
'</a>'
;
filters_list_btn
=
filters_list_btn
.
replace
(
"{{ DEFAULT_PK }}"
,
rowData
.
id
);
$
(
td
).
html
(
filters_list_btn
);
}},
{
targets
:
3
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
system_users_list_btn
=
'<a href="{% url "assets:cmd-filter-detail" pk=DEFAULT_PK %}">'
+
cellData
.
length
+
'</a>'
;
system_users_list_btn
=
system_users_list_btn
.
replace
(
"{{ DEFAULT_PK }}"
,
rowData
.
id
);
$
(
td
).
html
(
system_users_list_btn
);
}},
{
targets
:
5
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
update_btn
=
'<a href="{% url "assets:cmd-filter-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-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'
.
replace
(
'{{ DEFAULT_PK }}'
,
cellData
);
$
(
td
).
html
(
update_btn
+
del_btn
)
}}
],
ajax_url
:
'{% url "api-assets:cmd-filter-list" %}'
,
columns
:
[
{
data
:
"id"
},
{
data
:
"name"
},
{
data
:
"rules"
},
{
data
:
"system_users"
},
{
data
:
"comment"
},
{
data
:
"id"
}
],
op_html
:
$
(
'#actions'
).
html
()
};
jumpserver
.
initDataTable
(
options
);
}
$
(
document
).
ready
(
function
(){
initTable
();
})
.
on
(
'click'
,
'.btn-delete'
,
function
()
{
var
$this
=
$
(
this
);
var
$data_table
=
$
(
'#cmd_filter_list_table'
).
DataTable
();
var
name
=
$
(
this
).
closest
(
"tr"
).
find
(
":nth-child(2)"
).
children
(
'a'
).
html
();
var
uid
=
$this
.
data
(
'uid'
);
var
the_url
=
'{% url "api-assets:cmd-filter-detail" pk=DEFAULT_PK %}'
.
replace
(
'{{ DEFAULT_PK }}'
,
uid
);
objectDelete
(
$this
,
name
,
the_url
);
setTimeout
(
function
()
{
$data_table
.
ajax
.
reload
();
},
3000
);
});
</script>
{% endblock %}
apps/assets/templates/assets/cmd_filter_rule_create_update.html
0 → 100644
View file @
0665644f
{% extends 'base.html' %}
{% load i18n %}
{% load static %}
{% load bootstrap3 %}
{% block custom_head_css_js %}
<link
href=
"{% static 'css/plugins/select2/select2.min.css' %}"
rel=
"stylesheet"
>
<script
src=
"{% static 'js/plugins/select2/select2.full.min.js' %}"
></script>
{% endblock %}
{% 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=
"ibox-title"
>
<h5>
{{ action }}
</h5>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<form
enctype=
"multipart/form-data"
method=
"post"
class=
"form-horizontal"
action=
""
>
{% csrf_token %}
{% if form.non_field_errors %}
<div
class=
"alert alert-danger"
>
{{ form.non_field_errors }}
</div>
{% endif %}
{% bootstrap_form form layout="horizontal" %}
<div
class=
"form-group"
>
<div
class=
"col-sm-4 col-sm-offset-2"
>
<button
class=
"btn btn-white"
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>
{% endblock %}
{% block custom_foot_js %}
<script>
var
content_origin_placeholder
=
''
;
var
content_origin_help_text
=
''
;
var
content_ref
=
''
;
var
content_help_ref
=
''
;
$
(
document
).
ready
(
function
(){
content_ref
=
$
(
'#id_content'
);
content_help_ref
=
content_ref
.
next
();
content_origin_placeholder
=
content_ref
.
attr
(
'placeholder'
);
content_origin_help_text
=
content_help_ref
.
html
();
}).
on
(
'change'
,
'#id_type'
,
function
()
{
if
(
$
(
'#id_type :selected'
).
val
()
===
'regex'
)
{
content_ref
.
attr
(
'placeholder'
,
'rm.*|reboot|shutdown'
);
content_help_ref
.
html
(
""
);
}
else
{
content_ref
.
attr
(
'placeholder'
,
content_origin_placeholder
);
content_help_ref
.
html
(
content_origin_help_text
);
}
})
</script>
{% endblock %}
\ No newline at end of file
apps/assets/templates/assets/cmd_filter_rule_list.html
0 → 100644
View file @
0665644f
{% extends 'base.html' %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link
href=
'{% static "css/plugins/select2/select2.min.css" %}'
rel=
"stylesheet"
>
<script
src=
'{% static "js/plugins/select2/select2.full.min.js" %}'
></script>
{% endblock %}
{% 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 'assets:cmd-filter-detail' pk=object.id %}"
class=
"text-center"
>
<i
class=
"fa fa-laptop"
></i>
{% trans 'Detail' %}
</a>
</li>
<li
class=
"active"
>
<a
href=
"{% url 'assets:cmd-filter-rule-list' pk=object.id %}"
class=
"text-center"
><i
class=
"fa fa-laptop"
></i>
{% trans 'Rules' %}
</a>
</li>
</ul>
</div>
<div
class=
"tab-content"
>
<div
class=
"col-sm-12"
style=
"padding-left: 0;"
>
<div
class=
""
id=
"content_start"
>
</div>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-title"
>
<span
style=
"float: left"
><b>
{% trans 'Command filter rule list' %}
</b></span>
<div
class=
"ibox-tools"
>
<a
class=
"collapse-link"
>
<i
class=
"fa fa-chevron-up"
></i>
</a>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<i
class=
"fa fa-wrench"
></i>
</a>
<ul
class=
"dropdown-menu dropdown-user"
>
</ul>
<a
class=
"close-link"
>
<i
class=
"fa fa-times"
></i>
</a>
</div>
</div>
<div
class=
"ibox-content"
>
<div
class=
"uc pull-left m-r-5"
>
<a
href=
"{% url 'assets:cmd-filter-rule-create' filter_pk=object.id %}"
class=
"btn btn-sm btn-primary"
>
{% trans "Create rule" %}
</a>
</div>
<table
class=
"table table-striped table-bordered table-hover "
id=
"cmd_filter_rule_list_table"
>
<thead>
<tr>
<th
class=
"text-center"
>
<input
type=
"checkbox"
id=
"check_all"
class=
"ipt_check_all"
>
</th>
<th
class=
"text-center"
>
{% trans 'Type' %}
</th>
<th
class=
"text-center"
>
{% trans 'Content' %}
</th>
<th
class=
"text-center"
>
{% trans 'Priority' %}
</th>
<th
class=
"text-center"
>
{% trans 'Strategy' %}
</th>
<th
class=
"text-center"
>
{% trans 'Comment' %}
</th>
<th
class=
"text-center"
>
{% trans 'Action' %}
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block content_bottom_left %}{% endblock %}
{% block custom_foot_js %}
<script>
function
initTable
()
{
var
options
=
{
ele
:
$
(
'#cmd_filter_rule_list_table'
),
columnDefs
:
[
{
targets
:
6
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
update_btn
=
'<a href="{% url "assets:cmd-filter-rule-update" filter_pk=object.id 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-delete" data-uid="{{ DEFAULT_PK }}">{% trans "Delete" %}</a>'
.
replace
(
'{{ DEFAULT_PK }}'
,
cellData
);
$
(
td
).
html
(
update_btn
+
del_btn
)
}}
],
ajax_url
:
'{% url "api-assets:cmd-filter-rule-list" filter_pk=object.id %}'
,
columns
:
[
{
data
:
"id"
},
{
data
:
"type.display"
},
{
data
:
'content'
},
{
data
:
'priority'
},
{
data
:
'action.display'
},
{
data
:
"comment"
},
{
data
:
"id"
}
],
op_html
:
$
(
'#actions'
).
html
()
};
jumpserver
.
initDataTable
(
options
);
}
$
(
document
).
ready
(
function
(){
initTable
();
})
.
on
(
'click'
,
'.btn-delete'
,
function
()
{
var
$this
=
$
(
this
);
var
$data_table
=
$
(
'#cmd_filter_rule_list_table'
).
DataTable
();
var
name
=
$
(
this
).
closest
(
"tr"
).
find
(
":nth-child(2)"
).
children
(
'a'
).
html
();
var
uid
=
$this
.
data
(
'uid'
);
var
the_url
=
'{% url "api-assets:cmd-filter-rule-detail" filter_pk=object.id pk=DEFAULT_PK %}'
.
replace
(
'{{ DEFAULT_PK }}'
,
uid
);
objectDelete
(
$this
,
name
,
the_url
);
setTimeout
(
function
()
{
$data_table
.
ajax
.
reload
();
},
3000
);
})
</script>
{% endblock %}
apps/assets/templates/assets/system_user_asset.html
View file @
0665644f
{% extends 'base.html' %}
{% load common_tags %}
{% load static %}
{% load i18n %}
...
...
@@ -113,7 +114,7 @@
</tr>
</form>
{% for node in system_user.nodes.all %}
{% for node in system_user.nodes.all
|sort
%}
<tr>
<td
><b
class=
"bdg_node"
data-gid=
{{
node
.
id
}}
>
{{ node }}
</b></td>
<td>
...
...
apps/assets/templates/assets/system_user_detail.html
View file @
0665644f
This diff is collapsed.
Click to expand it.
apps/assets/urls/api_urls.py
View file @
0665644f
# coding:utf-8
from
django.urls
import
path
from
..
import
api
from
rest_framework_nested
import
routers
# from rest_framework.routers import DefaultRouter
from
rest_framework_bulk.routes
import
BulkRouter
from
..
import
api
app_name
=
'assets'
router
=
BulkRouter
()
...
...
@@ -13,6 +16,11 @@ router.register(r'labels', api.LabelViewSet, 'label')
router
.
register
(
r'nodes'
,
api
.
NodeViewSet
,
'node'
)
router
.
register
(
r'domain'
,
api
.
DomainViewSet
,
'domain'
)
router
.
register
(
r'gateway'
,
api
.
GatewayViewSet
,
'gateway'
)
router
.
register
(
r'cmd-filter'
,
api
.
CommandFilterViewSet
,
'cmd-filter'
)
cmd_filter_router
=
routers
.
NestedDefaultRouter
(
router
,
r'cmd-filter'
,
lookup
=
'filter'
)
cmd_filter_router
.
register
(
r'rules'
,
api
.
CommandFilterRuleViewSet
,
'cmd-filter-rule'
)
urlpatterns
=
[
path
(
'assets-bulk/'
,
api
.
AssetListUpdateApi
.
as_view
(),
name
=
'asset-bulk-update'
),
...
...
@@ -42,6 +50,9 @@ urlpatterns = [
path
(
'system-user/<uuid:pk>/connective/'
,
api
.
SystemUserTestConnectiveApi
.
as_view
(),
name
=
'system-user-connective'
),
path
(
'system-user/<uuid:pk>/cmd-filter-rules/'
,
api
.
SystemUserCommandFilterRuleListApi
.
as_view
(),
name
=
'system-user-cmd-filter-rule-list'
),
path
(
'nodes/<uuid:pk>/children/'
,
api
.
NodeChildrenApi
.
as_view
(),
name
=
'node-children'
),
path
(
'nodes/children/'
,
api
.
NodeChildrenApi
.
as_view
(),
name
=
'node-children-2'
),
...
...
@@ -64,5 +75,5 @@ urlpatterns = [
api
.
GatewayTestConnectionApi
.
as_view
(),
name
=
'test-gateway-connective'
),
]
urlpatterns
+=
router
.
urls
urlpatterns
+=
router
.
urls
+
cmd_filter_router
.
urls
apps/assets/urls/views_urls.py
View file @
0665644f
...
...
@@ -49,4 +49,12 @@ urlpatterns = [
path
(
'domain/<uuid:pk>/gateway/create/'
,
views
.
DomainGatewayCreateView
.
as_view
(),
name
=
'domain-gateway-create'
),
path
(
'domain/gateway/<uuid:pk>/update/'
,
views
.
DomainGatewayUpdateView
.
as_view
(),
name
=
'domain-gateway-update'
),
path
(
'cmd-filter/'
,
views
.
CommandFilterListView
.
as_view
(),
name
=
'cmd-filter-list'
),
path
(
'cmd-filter/create/'
,
views
.
CommandFilterCreateView
.
as_view
(),
name
=
'cmd-filter-create'
),
path
(
'cmd-filter/<uuid:pk>/update/'
,
views
.
CommandFilterUpdateView
.
as_view
(),
name
=
'cmd-filter-update'
),
path
(
'cmd-filter/<uuid:pk>/'
,
views
.
CommandFilterDetailView
.
as_view
(),
name
=
'cmd-filter-detail'
),
path
(
'cmd-filter/<uuid:pk>/rule/'
,
views
.
CommandFilterRuleListView
.
as_view
(),
name
=
'cmd-filter-rule-list'
),
path
(
'cmd-filter/<uuid:filter_pk>/rule/create/'
,
views
.
CommandFilterRuleCreateView
.
as_view
(),
name
=
'cmd-filter-rule-create'
),
path
(
'cmd-filter/<uuid:filter_pk>/rule/<uuid:pk>/update/'
,
views
.
CommandFilterRuleUpdateView
.
as_view
(),
name
=
'cmd-filter-rule-update'
),
]
apps/assets/views/__init__.py
View file @
0665644f
...
...
@@ -4,3 +4,4 @@ from .system_user import *
from
.admin_user
import
*
from
.label
import
*
from
.domain
import
*
from
.cmd_filter
import
*
apps/assets/views/cmd_filter.py
0 → 100644
View file @
0665644f
# -*- coding: utf-8 -*-
#
from
django.views.generic
import
TemplateView
,
CreateView
,
\
UpdateView
,
DeleteView
,
DetailView
from
django.views.generic.detail
import
SingleObjectMixin
from
django.utils.translation
import
ugettext_lazy
as
_
from
django.urls
import
reverse_lazy
from
django.shortcuts
import
get_object_or_404
,
reverse
from
common.permissions
import
AdminUserRequiredMixin
from
common.const
import
create_success_msg
,
update_success_msg
from
..models
import
CommandFilter
,
CommandFilterRule
,
SystemUser
from
..forms
import
CommandFilterForm
,
CommandFilterRuleForm
__all__
=
(
"CommandFilterListView"
,
"CommandFilterCreateView"
,
"CommandFilterUpdateView"
,
"CommandFilterRuleListView"
,
"CommandFilterRuleCreateView"
,
"CommandFilterRuleUpdateView"
,
"CommandFilterDetailView"
,
)
class
CommandFilterListView
(
AdminUserRequiredMixin
,
TemplateView
):
template_name
=
'assets/cmd_filter_list.html'
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Command filter list'
),
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
CommandFilterCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
CommandFilter
template_name
=
'assets/cmd_filter_create_update.html'
form_class
=
CommandFilterForm
success_url
=
reverse_lazy
(
'assets:cmd-filter-list'
)
success_message
=
create_success_msg
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Create command filter'
),
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
CommandFilterUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
CommandFilter
template_name
=
'assets/cmd_filter_create_update.html'
form_class
=
CommandFilterForm
success_url
=
reverse_lazy
(
'assets:cmd-filter-list'
)
success_message
=
update_success_msg
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Update command filter'
),
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
CommandFilterDetailView
(
AdminUserRequiredMixin
,
DetailView
):
model
=
CommandFilter
template_name
=
'assets/cmd_filter_detail.html'
def
get_context_data
(
self
,
**
kwargs
):
system_users_remain
=
SystemUser
.
objects
\
.
exclude
(
cmd_filters
=
self
.
object
)
\
.
exclude
(
protocol
=
'rdp'
)
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Command filter detail'
),
'system_users_remain'
:
system_users_remain
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
CommandFilterRuleListView
(
AdminUserRequiredMixin
,
SingleObjectMixin
,
TemplateView
):
template_name
=
'assets/cmd_filter_rule_list.html'
model
=
CommandFilter
object
=
None
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
(
queryset
=
self
.
model
.
objects
.
all
())
return
super
()
.
get
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Command filter rule list'
),
'object'
:
self
.
get_object
()
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
CommandFilterRuleCreateView
(
AdminUserRequiredMixin
,
CreateView
):
template_name
=
'assets/cmd_filter_rule_create_update.html'
model
=
CommandFilterRule
form_class
=
CommandFilterRuleForm
success_message
=
create_success_msg
cmd_filter
=
None
def
get_success_url
(
self
):
return
reverse
(
'assets:cmd-filter-rule-list'
,
kwargs
=
{
'pk'
:
self
.
cmd_filter
.
id
})
def
get_form
(
self
,
form_class
=
None
):
form
=
super
()
.
get_form
(
form_class
=
form_class
)
form
[
'filter'
]
.
initial
=
self
.
cmd_filter
form
[
'filter'
]
.
field
.
widget
.
attrs
[
'readonly'
]
=
1
return
form
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
filter_pk
=
self
.
kwargs
.
get
(
'filter_pk'
)
self
.
cmd_filter
=
get_object_or_404
(
CommandFilter
,
pk
=
filter_pk
)
return
super
()
.
dispatch
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Create command filter rule'
),
'object'
:
self
.
cmd_filter
,
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
class
CommandFilterRuleUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
template_name
=
'assets/cmd_filter_rule_create_update.html'
model
=
CommandFilterRule
form_class
=
CommandFilterRuleForm
success_message
=
create_success_msg
cmd_filter
=
None
def
get_success_url
(
self
):
return
reverse
(
'assets:cmd-filter-rule-list'
,
kwargs
=
{
'pk'
:
self
.
cmd_filter
.
id
})
def
get_form
(
self
,
form_class
=
None
):
form
=
super
()
.
get_form
(
form_class
=
form_class
)
form
[
'filter'
]
.
initial
=
self
.
cmd_filter
form
[
'filter'
]
.
field
.
widget
.
attrs
[
'readonly'
]
=
1
return
form
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
filter_pk
=
self
.
kwargs
.
get
(
'filter_pk'
)
self
.
cmd_filter
=
get_object_or_404
(
CommandFilter
,
pk
=
filter_pk
)
return
super
()
.
dispatch
(
request
,
*
args
,
**
kwargs
)
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'Update command filter rule'
),
'object'
:
self
.
cmd_filter
,
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
\ No newline at end of file
apps/assets/views/system_user.py
View file @
0665644f
...
...
@@ -9,7 +9,7 @@ from django.views.generic.detail import DetailView
from
common.const
import
create_success_msg
,
update_success_msg
from
..forms
import
SystemUserForm
from
..models
import
SystemUser
,
Node
from
..models
import
SystemUser
,
Node
,
CommandFilter
from
common.permissions
import
AdminUserRequiredMixin
...
...
@@ -73,7 +73,7 @@ class SystemUserDetailView(AdminUserRequiredMixin, DetailView):
context
=
{
'app'
:
_
(
'Assets'
),
'action'
:
_
(
'System user detail'
),
'
nodes_remain'
:
Node
.
objects
.
exclude
(
systemuser
=
self
.
object
)
'
cmd_filters_remain'
:
CommandFilter
.
objects
.
exclude
(
system_users
=
self
.
object
)
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
...
...
@@ -91,10 +91,11 @@ class SystemUserAssetView(AdminUserRequiredMixin, DetailView):
context_object_name
=
'system_user'
def
get_context_data
(
self
,
**
kwargs
):
nodes_remain
=
sorted
(
Node
.
objects
.
exclude
(
systemuser
=
self
.
object
),
reverse
=
True
)
context
=
{
'app'
:
_
(
'assets'
),
'action'
:
_
(
'System user asset'
),
'nodes_remain'
:
Node
.
objects
.
exclude
(
systemuser
=
self
.
object
)
'nodes_remain'
:
nodes_remain
}
kwargs
.
update
(
context
)
return
super
()
.
get_context_data
(
**
kwargs
)
apps/common/fields.py
View file @
0665644f
...
...
@@ -86,3 +86,21 @@ class FormEncryptCharField(FormEncryptMixin, forms.CharField):
class
FormEncryptDictField
(
FormEncryptMixin
,
FormDictField
):
pass
class
ChoiceDisplayField
(
serializers
.
ChoiceField
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
ChoiceDisplayField
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
choice_strings_to_display
=
{
six
.
text_type
(
key
):
value
for
key
,
value
in
self
.
choices
.
items
()
}
def
to_representation
(
self
,
value
):
if
value
is
None
:
return
value
return
{
'value'
:
self
.
choice_strings_to_values
.
get
(
six
.
text_type
(
value
),
value
),
'display'
:
self
.
choice_strings_to_display
.
get
(
six
.
text_type
(
value
),
value
),
}
apps/common/templatetags/common_tags.py
View file @
0665644f
...
...
@@ -100,3 +100,9 @@ def is_bool_field(field):
@register.filter
def
to_dict
(
data
):
return
dict
(
data
)
@register.filter
def
sort
(
data
):
print
(
data
)
return
sorted
(
data
)
apps/locale/zh/LC_MESSAGES/django.mo
View file @
0665644f
No preview for this file type
apps/locale/zh/LC_MESSAGES/django.po
View file @
0665644f
This diff is collapsed.
Click to expand it.
apps/orgs/views.py
View file @
0665644f
...
...
@@ -14,7 +14,8 @@ class SwitchOrgView(DetailView):
pk
=
kwargs
.
get
(
'pk'
)
self
.
object
=
Organization
.
get_instance
(
pk
)
request
.
session
[
'oid'
]
=
self
.
object
.
id
.
__str__
()
return
redirect
(
'index'
)
referer
=
request
.
META
.
get
(
'HTTP_REFERER'
,
reverse
(
'index'
))
return
redirect
(
referer
)
class
SwitchToAOrgView
(
View
):
...
...
apps/templates/_footer.html
View file @
0665644f
{% load i18n %}
<div
class=
"footer fixed"
>
<div
class=
"pull-right"
>
Version
<strong>
1.4.
2
-{% include '_build.html' %}
</strong>
GPLv2.
Version
<strong>
1.4.
3
-{% include '_build.html' %}
</strong>
GPLv2.
<!--<img style="display: none" src="http://www.jumpserver.org/img/evaluate_avatar1.jpg">-->
</div>
<div>
...
...
apps/templates/_nav.html
View file @
0665644f
...
...
@@ -24,6 +24,7 @@
<li
id=
"admin-user"
><a
href=
"{% url 'assets:admin-user-list' %}"
>
{% trans 'Admin user' %}
</a></li>
<li
id=
"system-user"
><a
href=
"{% url 'assets:system-user-list' %}"
>
{% trans 'System user' %}
</a></li>
<li
id=
"label"
><a
href=
"{% url 'assets:label-list' %}"
>
{% trans 'Labels' %}
</a></li>
<li
id=
"cmd-filter"
><a
href=
"{% url 'assets:cmd-filter-list' %}"
>
{% trans 'Command filters' %}
</a></li>
</ul>
</li>
<li
id=
"perms"
>
...
...
@@ -47,6 +48,11 @@
<span
class=
"nav-label"
>
{% trans 'Web terminal' %}
</span>
</a>
</li>
<li>
<a
href=
"{% url 'terminal:web-sftp' %}"
target=
"_blank"
>
<span
class=
"nav-label"
>
{% trans 'File manager' %}
</span>
</a>
</li>
{% if request.user.is_superuser %}
<li
id=
"terminal"
><a
href=
"{% url 'terminal:terminal-list' %}"
>
{% trans 'Terminal' %}
</a></li>
{% endif %}
...
...
apps/terminal/urls/views_urls.py
View file @
0665644f
...
...
@@ -16,6 +16,7 @@ urlpatterns = [
path
(
'terminal/<uuid:pk>/update/'
,
views
.
TerminalUpdateView
.
as_view
(),
name
=
'terminal-update'
),
path
(
'<uuid:pk>/accept/'
,
views
.
TerminalAcceptView
.
as_view
(),
name
=
'terminal-accept'
),
path
(
'web-terminal/'
,
views
.
WebTerminalView
.
as_view
(),
name
=
'web-terminal'
),
path
(
'web-sftp/'
,
views
.
WebSFTPView
.
as_view
(),
name
=
'web-sftp'
),
# Session view
path
(
'session-online/'
,
views
.
SessionOnlineListView
.
as_view
(),
name
=
'session-online-list'
),
...
...
apps/terminal/views/terminal.py
View file @
0665644f
...
...
@@ -16,7 +16,7 @@ from common.permissions import SuperUserRequiredMixin
__all__
=
[
"TerminalListView"
,
"TerminalUpdateView"
,
"TerminalDetailView"
,
"TerminalDeleteView"
,
"TerminalConnectView"
,
"TerminalAcceptView"
,
"WebTerminalView"
,
"WebTerminalView"
,
'WebSFTPView'
,
]
...
...
@@ -124,3 +124,8 @@ class TerminalConnectView(LoginRequiredMixin, SuperUserRequiredMixin, DetailView
class
WebTerminalView
(
LoginRequiredMixin
,
View
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
return
redirect
(
'/luna/?'
+
request
.
GET
.
urlencode
())
class
WebSFTPView
(
LoginRequiredMixin
,
View
):
def
get
(
self
,
request
,
*
args
,
**
kwargs
):
return
redirect
(
'/coco/elfinder/sftp/?'
+
request
.
GET
.
urlencode
())
requirements/requirements.txt
View file @
0665644f
...
...
@@ -71,3 +71,4 @@ urllib3==1.22
vine==1.1.4
drf-yasg==1.9.1
Werkzeug==0.14.1
drf-nested-routers==0.90.2
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