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
d0ede246
Commit
d0ede246
authored
Apr 07, 2018
by
ibuler
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Update] 修改授权
parent
cb8e59ed
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
475 additions
and
298 deletions
+475
-298
asset.py
apps/assets/models/asset.py
+4
-0
signals_handler.py
apps/assets/signals_handler.py
+1
-1
utils.py
apps/common/utils.py
+8
-0
forms.py
apps/perms/forms.py
+18
-13
models.py
apps/perms/models.py
+58
-8
asset_permission_create_update.html
...perms/templates/perms/asset_permission_create_update.html
+19
-21
asset_permission_list.html
apps/perms/templates/perms/asset_permission_list.html
+121
-205
utils.py
apps/perms/utils.py
+170
-3
views.py
apps/perms/views.py
+50
-20
command_list.html
apps/terminal/templates/terminal/command_list.html
+2
-2
forms.py
apps/users/forms.py
+24
-25
No files found.
apps/assets/models/asset.py
View file @
d0ede246
...
...
@@ -101,6 +101,10 @@ class Asset(models.Model):
else
:
return
False
def
get_nodes
(
self
):
from
.node
import
Node
return
self
.
nodes
.
all
()
or
[
Node
.
root
()]
@property
def
hardware_info
(
self
):
if
self
.
cpu_count
:
...
...
apps/assets/signals_handler.py
View file @
d0ede246
...
...
@@ -31,7 +31,7 @@ def set_asset_root_node(asset):
@receiver
(
post_save
,
sender
=
Asset
,
dispatch_uid
=
"my_unique_identifier"
)
def
on_asset_created_or_update
(
sender
,
instance
=
None
,
created
=
False
,
**
kwargs
):
set_asset_root_node
(
instance
)
#
set_asset_root_node(instance)
if
created
:
logger
.
info
(
"Asset `{}` create signal received"
.
format
(
instance
))
update_asset_hardware_info_on_created
(
instance
)
...
...
apps/common/utils.py
View file @
d0ede246
...
...
@@ -232,6 +232,14 @@ def setattr_bulk(seq, key, value):
return
map
(
set_attr
,
seq
)
def
set_or_append_attr_bulk
(
seq
,
key
,
value
):
for
obj
in
seq
:
ori
=
getattr
(
obj
,
key
,
None
)
if
ori
:
value
+=
" "
+
ori
setattr
(
obj
,
key
,
value
)
def
content_md5
(
data
):
"""计算data的MD5值,经过Base64编码并返回str类型。
...
...
apps/perms/forms.py
View file @
d0ede246
...
...
@@ -4,27 +4,32 @@ from __future__ import absolute_import, unicode_literals
from
django
import
forms
from
django.utils.translation
import
ugettext_lazy
as
_
from
.models
import
Node
Permission
from
.models
import
Asset
Permission
class
AssetPermissionForm
(
forms
.
ModelForm
):
class
Meta
:
model
=
NodePermission
fields
=
[
'node'
,
'user_group'
,
'system_user'
,
'is_active'
,
'date_expired'
,
'comment'
,
]
model
=
AssetPermission
exclude
=
(
'id'
,
'date_created'
,
'created_by'
)
widgets
=
{
'
node'
:
forms
.
Select
(
attrs
=
{
'
style'
:
'display:none'
}
'
users'
:
forms
.
SelectMultiple
(
attrs
=
{
'
class'
:
'select2'
,
'data-placeholder'
:
_
(
"User"
)
}
),
'user_group
'
:
forms
.
Select
(
'user_group
s'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
"User group"
)}
),
'system_user'
:
forms
.
Select
(
'assets'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
"Asset"
)}
),
'nodes'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
"Node"
)}
),
'system_users'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'System user'
)}
),
}
def
clean_system_user
(
self
):
return
self
.
cleaned_data
[
'system_user'
]
labels
=
{
'nodes'
:
_
(
"Node"
),
}
apps/perms/models.py
View file @
d0ede246
...
...
@@ -7,28 +7,42 @@ from django.utils import timezone
from
common.utils
import
date_expired_default
class
ValidManager
(
models
.
Manager
):
def
get_queryset
(
self
):
return
super
()
.
get_queryset
()
.
filter
(
is_active
=
True
)
\
.
filter
(
date_start__lt
=
timezone
.
now
())
\
.
filter
(
date_expired__gt
=
timezone
.
now
())
class
AssetPermission
(
models
.
Model
):
from
users.models
import
User
,
UserGroup
from
assets.models
import
Asset
,
AssetGroup
,
SystemUser
,
Cluster
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
name
=
models
.
CharField
(
max_length
=
128
,
unique
=
True
,
verbose_name
=
_
(
'Name'
))
users
=
models
.
ManyToManyField
(
User
,
related_name
=
'asset_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"User"
))
user_groups
=
models
.
ManyToManyField
(
UserGroup
,
related_name
=
'asset_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"User group"
))
assets
=
models
.
ManyToManyField
(
Asset
,
related_name
=
'granted_by_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"Asset"
))
asset_groups
=
models
.
ManyToManyField
(
AssetGroup
,
related_name
=
'granted_by_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"Asset group
"
))
system_users
=
models
.
ManyToManyField
(
SystemUser
,
related_name
=
'granted_by_permissions'
,
verbose_name
=
_
(
"System user"
))
users
=
models
.
ManyToManyField
(
'users.User'
,
related_name
=
'asset_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"User"
))
user_groups
=
models
.
ManyToManyField
(
'users.UserGroup'
,
related_name
=
'asset_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"User group"
))
assets
=
models
.
ManyToManyField
(
'assets.Asset'
,
related_name
=
'granted_by_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"Asset"
))
nodes
=
models
.
ManyToManyField
(
'assets.Node'
,
related_name
=
'granted_by_permissions'
,
blank
=
True
,
verbose_name
=
_
(
"Nodes
"
))
system_users
=
models
.
ManyToManyField
(
'assets.SystemUser'
,
related_name
=
'granted_by_permissions'
,
verbose_name
=
_
(
"System user"
))
is_active
=
models
.
BooleanField
(
default
=
True
,
verbose_name
=
_
(
'Active'
))
date_start
=
models
.
DateTimeField
(
default
=
timezone
.
now
,
verbose_name
=
_
(
"Date start"
))
date_expired
=
models
.
DateTimeField
(
default
=
date_expired_default
,
verbose_name
=
_
(
'Date expired'
))
created_by
=
models
.
CharField
(
max_length
=
128
,
blank
=
True
,
verbose_name
=
_
(
'Created by'
))
date_created
=
models
.
DateTimeField
(
auto_now_add
=
True
,
verbose_name
=
_
(
'Date created'
))
comment
=
models
.
TextField
(
verbose_name
=
_
(
'Comment'
),
blank
=
True
)
objects
=
models
.
Manager
()
valid
=
ValidManager
()
inherit_from
=
None
def
__str__
(
self
):
return
self
.
name
@property
def
id_str
(
self
):
return
str
(
self
.
id
)
@property
def
is_valid
(
self
):
if
self
.
date_expired
>
timezone
.
now
()
and
self
.
is_active
:
if
self
.
date_expired
>
timezone
.
now
()
>
self
.
date_start
and
self
.
is_active
:
return
True
return
False
...
...
@@ -68,6 +82,42 @@ class AssetPermission(models.Model):
errors
[
system_user
]
=
cluster_remain
return
errors
@property
def
users_detail
(
self
):
return
" "
.
join
([
u
.
name
for
u
in
self
.
users
.
all
()])
@property
def
user_groups_detail
(
self
):
return
" "
.
join
([
g
.
name
for
g
in
self
.
user_groups
.
all
()])
@property
def
assets_detail
(
self
):
return
" "
.
join
([
a
.
hostname
for
a
in
self
.
assets
.
all
()])
@property
def
nodes_detail
(
self
):
return
" "
.
join
([
g
.
value
for
g
in
self
.
nodes
.
all
()])
@property
def
system_users_detail
(
self
):
return
" "
.
join
([
s
.
name
for
s
in
self
.
system_users
.
all
()])
@property
def
detail
(
self
):
data
=
""
if
self
.
users
.
all
():
comment
=
_
(
"User"
)
users
=
"<b>{}: </b>"
.
format
(
comment
)
for
u
in
self
.
users
.
all
():
users
+=
u
.
name
+
" "
data
+=
users
+
"<br/>"
if
self
.
assets
.
all
():
assets
=
_
(
"<b>Assets: </b>"
)
for
a
in
self
.
assets
.
all
():
assets
+=
a
.
hostname
+
" "
data
+=
assets
+
"<br/>"
return
data
class
NodePermission
(
models
.
Model
):
id
=
models
.
UUIDField
(
default
=
uuid
.
uuid4
,
primary_key
=
True
)
...
...
apps/perms/templates/perms/asset_permission_create_update.html
View file @
d0ede246
...
...
@@ -28,23 +28,19 @@
</div>
</div>
<div
class=
"ibox-content"
>
{% if form.non_field_errors %}
<div
class=
"alert alert-danger"
>
{{ form.non_field_errors }}
</div>
{% endif %}
<form
method=
"post"
class=
"form-horizontal"
action=
""
>
{% csrf_token %}
<h3>
{% trans 'Basic' %}
</h3>
<div
class=
"form-group"
>
<label
class=
"col-md-2 control-label"
for=
"id_name"
>
{% trans 'Node' %}
</label>
<div
class=
"col-md-9"
>
<input
type=
"text"
class=
"form-control"
readonly
value=
"{{ form.node.initial }}"
>
</div>
</div>
{{ form.node }}
{% bootstrap_field form.user_group layout="horizontal" %}
{% bootstrap_field form.system_user layout="horizontal" %}
{% bootstrap_field form.name layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'User' %}
</h3>
{% bootstrap_field form.users layout="horizontal" %}
{% bootstrap_field form.user_groups layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Asset' %}
</h3>
{% bootstrap_field form.assets layout="horizontal" %}
{% bootstrap_field form.nodes layout="horizontal" %}
{% bootstrap_field form.system_users layout="horizontal" %}
<div
class=
"hr-line-dashed"
></div>
<h3>
{% trans 'Other' %}
</h3>
<div
class=
"form-group"
>
...
...
@@ -53,15 +49,17 @@
{{ form.is_active }}
</div>
</div>
<div
class=
"form-group {% if form.date_expired.errors %} has-error {% endif %}"
id=
"date_5"
>
<div
class=
"form-group {% if form.date_expired.errors or form.date_start.errors %} has-error {% endif %}"
id=
"date_5"
>
<label
for=
"{{ form.date_expired.id_for_label }}"
class=
"col-sm-2 control-label"
>
{{ form.date_expired.label }}
</label>
<div
class=
"col-sm-9"
>
<div
class=
"input-
group date
"
>
<div
class=
"input-
daterange input-group"
id=
"datepicker
"
>
<span
class=
"input-group-addon"
><i
class=
"fa fa-calendar"
></i></span>
<input
id=
"{{ form.date_expired.id_for_label }}"
name=
"{{ form.date_expired.html_name }}"
type=
"text"
class=
"form-control"
value=
"{{ form.date_expired.value|date:'Y-m-d'|default:form.date_expired.value }}"
>
<input
type=
"text"
class=
"input-sm form-control"
name=
"date_start"
value=
"{{ form.date_start.value|date:'Y-m-d' }}"
>
<span
class=
"input-group-addon"
>
to
</span>
<input
type=
"text"
class=
"input-sm form-control"
name=
"date_expired"
value=
"{{ form.date_expired.value|date:'Y-m-d' }}"
>
</div>
<span
class=
"help-block "
>
{{ form.date_expired.errors }}
</span>
<span
class=
"help-block "
>
{{ form.date_start.errors }}
</span>
</div>
</div>
{% bootstrap_field form.comment layout="horizontal" %}
...
...
@@ -84,15 +82,14 @@
<script>
$
(
document
).
ready
(
function
()
{
$
(
'.select2'
).
select2
();
$
(
'.input-group.date'
).
datepicker
({
$
(
'#datepicker'
).
datepicker
({
format
:
"yyyy-mm-dd"
,
todayBtn
:
"linked"
,
keyboardNavigation
:
false
,
forceParse
:
false
,
calendarWeeks
:
true
,
autoclose
:
true
})
})
;
})
</script>
{% endblock %}
\ No newline at end of file
apps/perms/templates/perms/asset_permission_list.html
View file @
d0ede246
{% extends 'base.html' %}
{% load static %}
{% extends '_base_list.html' %}
{% load i18n %}
{% load static %}
{% load common_tags %}
{% block custom_head_css_js %}
<link
href=
"{% static 'css/plugins/jstree/style.min.css' %}"
rel=
"stylesheet"
>
<link
href=
"{% static 'css/plugins/ztree/awesomeStyle/awesome.css' %}"
rel=
"stylesheet"
>
<script
type=
"text/javascript"
src=
"{% static 'js/plugins/ztree/jquery.ztree.all.min.js' %}"
></script>
<style
type=
"text/css"
>
div
#rMenu
{
position
:
absolute
;
visibility
:
hidden
;
text-align
:
left
;
top
:
100%
;
left
:
0
;
z-index
:
1000
;
float
:
left
;
padding
:
5px
0
;
margin
:
2px
0
0
;
list-style
:
none
;
background-clip
:
padding-box
;
}
div
#rMenu
li
{
margin
:
1px
0
;
cursor
:
pointer
;
{#
list-style
:
none
outside
none
;
#
}
}
.dropdown
a
:hover
{
background-color
:
#f1f1f1
<link
href=
"{% static "
css
/
plugins
/
footable
/
footable
.
core
.
css
"
%}"
rel=
"stylesheet"
>
<link
href=
"{% static 'css/plugins/datepicker/datepicker3.css' %}"
rel=
"stylesheet"
>
<link
href=
"{% static 'css/plugins/select2/select2.min.css' %}"
rel=
"stylesheet"
>
<script
src=
"{% static 'js/plugins/select2/select2.full.min.js' %}"
></script>
<style>
#search_btn
{
margin-bottom
:
0
;
}
</style>
{% endblock %}
{% block content_left_head %}
{% endblock %}
{% block content %}
<div
class=
"wrapper wrapper-content"
>
<div
class=
"row"
>
<div
class=
"col-lg-3"
id=
"split-left"
>
<div
class=
"ibox float-e-margins"
>
<div
class=
"ibox-content mailbox-content"
style=
"padding-top: 0"
>
<div
class=
"file-manager "
>
<div
id=
"assetTree"
class=
"ztree"
>
{% block table_search %}
<div
class=
"uc pull-left m-r-5"
>
<a
href=
"{% url 'perms:asset-permission-create' %}"
class=
"btn btn-sm btn-primary "
>
{% trans "Create permission" %}
</a>
</div>
<div
class=
"clearfix"
></div>
<form
id=
"search_form"
method=
"get"
action=
""
class=
"pull-right form-inline"
style=
"padding-bottom: 8px"
>
<div
class=
"input-group"
>
<select
class=
"select2 form-control"
name=
"user"
>
<option
value=
""
>
{% trans 'User' %}
</option>
{% for u in user_list %}
<option
value=
"{{ u }}"
{%
if
u =
=
user
%}
selected
{%
endif
%}
>
{{ u }}
</option>
{% endfor %}
</select>
</div>
<div
class=
"input-group"
>
<select
class=
"select2 form-control"
name=
"user_group"
>
<option
value=
""
>
{% trans 'User group' %}
</option>
{% for g in user_group_list %}
<option
value=
"{{ g }}"
{%
if
g =
=
user_group
%}
selected
{%
endif
%}
>
{{ g }}
</option>
{% endfor %}
</select>
</div>
<div
class=
"input-group"
>
<select
class=
"select2 form-control"
name=
"asset"
>
<option
value=
""
>
{% trans 'Asset' %}
</option>
{% for a in asset_list %}
<option
value=
"{{ a }}"
{%
if
a =
=
asset
%}
selected
{%
endif
%}
>
{{ a }}
</option>
{% endfor %}
</select>
</div>
<div
class=
"input-group"
>
<select
class=
"select2 form-control"
name=
"node"
>
<option
value=
""
>
{% trans 'Node' %}
</option>
{% for n in node_list %}
<option
value=
"{{ n }}"
{%
if
n =
=
node
%}
selected
{%
endif
%}
>
{{ n }}
</option>
{% endfor %}
</select>
</div>
<div
class=
"col-lg-9 animated fadeInRight"
id=
"split-right"
>
<div
class=
"tree-toggle"
>
<div
class=
"btn btn-sm btn-primary tree-toggle-btn"
onclick=
"toggle()"
>
<i
class=
"fa fa-angle-left fa-x"
id=
"toggle-icon"
></i>
<div
class=
"input-group"
>
<select
class=
"select2 form-control"
name=
"system_user"
>
<option
value=
""
>
{% trans 'System user' %}
</option>
{% for s in system_user_list %}
<option
value=
"{{ s }}"
{%
if
s =
=
system_user
%}
selected
{%
endif
%}
>
{{ s }}
</option>
{% endfor %}
</select>
</div>
<div
class=
"input-group"
>
<input
type=
"text"
class=
"form-control input-sm"
name=
"q"
placeholder=
"{% trans 'Search' %}"
value=
"{{ q }}"
>
</div>
<div
class=
"input-group"
>
<div
class=
"input-group-btn"
>
<button
id=
'search_btn'
type=
"submit"
class=
"btn btn-sm btn-primary"
>
{% trans 'Search' %}
</button>
</div>
<div
class=
"mail-box-header"
>
<div
class=
"uc pull-left m-r-5"
>
<a
class=
"btn btn-sm btn-primary btn-create-permission"
>
{% trans "Create permission" %}
</a>
</div>
<table
class=
"table table-striped table-bordered table-hover"
id=
"permission_list_table"
style=
"width: 100%"
>
</form>
{% endblock %}
{% block table_container %}
<table
class=
"footable table table-stripped table-bordered toggle-arrow-tiny"
data-page=
"false"
>
<thead>
<tr>
<th
class=
"text-center"
>
<input
type=
"checkbox"
id=
"check_all"
class=
"ipt_check_all"
>
</th>
<th
class=
"text-center"
>
{% trans 'Node' %}
</th>
<th
data-sorted=
"true"
data-toggle=
"true"
>
ID
</th>
<th>
{% trans 'Name' %}
</th>
<th
class=
"text-center"
>
{% trans 'User' %}
</th>
<th
class=
"text-center"
>
{% trans 'User group' %}
</th>
<th
class=
"text-center"
>
{% trans 'Asset' %}
</th>
<th
class=
"text-center"
>
{% trans 'Node'%}
</th>
<th
class=
"text-center"
>
{% trans 'System user' %}
</th>
<th
class=
"text-center"
>
{% trans 'Is active' %}
</th>
<th
class=
"text-center"
>
{% trans 'Date expired' %}
</th>
<th
class=
"text-center"
>
{% trans 'Action' %}
</th>
<th
class=
"text-center"
>
{% trans 'Active' %}
</th>
<th
class=
"text-center"
>
{% trans 'Action' %}
</th>
<th
data-hide=
"all"
>
{% trans 'User' %}
</th>
<th
data-hide=
"all"
>
{% trans 'User group' %}
</th>
<th
data-hide=
"all"
>
{% trans 'Asset' %}
</th>
<th
data-hide=
"all"
>
{% trans 'Node' %}
</th>
<th
data-hide=
"all"
>
{% trans 'System user' %}
</th>
</tr>
</thead>
<tbody>
{% for object in object_list %}
<tr>
<td>
{{ forloop.counter }}
</td>
<td><a
href=
"#"
>
{{ object.name }}
</a></td>
<td
class=
"text-center"
>
{{ object.users.count }}
</td>
<td
class=
"text-center"
>
{{ object.user_groups.count }}
</td>
<td
class=
"text-center"
>
{{ object.assets.count }}
</td>
<td
class=
"text-center"
>
{{ object.nodes.count }}
</td>
<td
class=
"text-center"
>
{{ object.system_users.count }}
</td>
<td
class=
"text-center"
>
{% if object.is_valid %}
<i
class=
"fa fa-check text-navy"
></i>
{% else %}
<i
class=
"fa fa-times text-danger"
></i>
{% endif %}
</td>
<td
class=
"text-center"
>
<a
href=
"{% url 'perms:asset-permission-update' pk=object.id %}"
class=
"btn btn-xs btn-info"
>
{% trans "Update" %}
</a>
<a
href=
""
class=
"btn btn-xs btn-danger m-l-xs"
>
{% trans "Delete" %}
</a>
</td>
<td>
{{ object.users_detail }}
</td>
<td>
{{ object.user_groups_detail }}
</td>
<td>
{{ object.assets_detail }}
</td>
<td>
{{ object.nodes_detail }}
</td>
<td>
{{ object.system_users_detail }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script
src=
"{% static "
js
/
plugins
/
footable
/
footable
.
all
.
min
.
js
"
%}"
></script>
<script
src=
"{% static 'js/plugins/datepicker/bootstrap-datepicker.js' %}"
></script>
<script>
var
zTree
,
rMenu
,
table
,
show
=
0
;
function
initTable
()
{
var
options
=
{
ele
:
$
(
'#permission_list_table'
),
columnDefs
:
[
{
targets
:
1
,
createdCell
:
function
(
td
,
cellData
)
{
var
html
=
'<a href="{% url '
assets
:
asset
-
list
' %}?node=99899">'
+
cellData
.
name
+
'</a>'
;
$
(
td
).
html
(
html
.
replace
(
"99899"
,
cellData
.
pk
));
}},
{
targets
:
2
,
createdCell
:
function
(
td
,
cellData
)
{
var
html
=
'<a href="{% url "users:user-group-detail" pk=DEFAULT_PK %}">'
+
cellData
.
name
+
'</a>'
;
$
(
td
).
html
(
html
.
replace
(
"{{ DEFAULT_PK }}"
,
cellData
.
pk
))
}},
{
targets
:
3
,
createdCell
:
function
(
td
,
cellData
)
{
var
html
=
'<a href="{% url '
assets
:
system
-
user
-
detail
' pk=DEFAULT_PK %}">'
+
cellData
.
name
+
'</a>'
;
$
(
td
).
html
(
html
.
replace
(
"{{ DEFAULT_PK }}"
,
cellData
.
pk
));
}},
{
targets
:
4
,
createdCell
:
function
(
td
,
cellData
)
{
if
(
!
cellData
)
{
$
(
td
).
html
(
'<i class="fa fa-times text-danger"></i>'
)
}
else
{
$
(
td
).
html
(
'<i class="fa fa-check text-navy"></i>'
)
}
}},
{
targets
:
5
,
createdCell
:
function
(
td
,
cellData
)
{
var
date_expired
=
cellData
.
split
(
" "
);
if
(
date_expired
&&
date_expired
.
length
===
3
)
{
$
(
td
).
html
(
date_expired
[
0
]);
}
else
{
$
(
td
).
html
(
cellData
);
}
}},
{
targets
:
6
,
createdCell
:
function
(
td
,
cellData
,
rowData
)
{
var
name
=
rowData
.
user_group
.
name
+
"=>"
+
rowData
.
system_user
.
name
+
"=>"
+
rowData
.
node
.
name
;
var
update_btn
=
'<a href="{% url "perms:asset-permission-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-del" data-uid="{{ DEFAULT_PK }}" data-name="99991938">{% trans "Delete" %}</a>'
.
replace
(
'{{ DEFAULT_PK }}'
,
cellData
)
.
replace
(
'99991938'
,
name
);
$
(
td
).
html
(
update_btn
+
del_btn
);
}}
],
ajax_url
:
'{% url "api-perms:asset-permission-list" %}'
,
columns
:
[
{
data
:
"id"
},
{
data
:
"node"
},
{
data
:
"user_group"
},
{
data
:
"system_user"
},
{
data
:
"is_active"
},
{
data
:
"date_expired"
},
{
data
:
"id"
}
],
op_html
:
$
(
'#actions'
).
html
()
};
table
=
jumpserver
.
initDataTable
(
options
);
return
table
}
function
onSelected
(
event
,
treeNode
)
{
var
url
=
table
.
ajax
.
url
();
url
=
setUrlParam
(
url
,
"node_id"
,
treeNode
.
id
);
setCookie
(
'node_selected'
,
treeNode
.
id
);
table
.
ajax
.
url
(
url
);
table
.
ajax
.
reload
();
}
function
selectQueryNode
()
{
var
query_node_id
=
$
.
getUrlParam
(
"node"
);
var
cookie_node_id
=
getCookie
(
'node_selected'
);
var
node
;
var
node_id
;
if
(
query_node_id
!==
null
)
{
node_id
=
query_node_id
}
else
if
(
cookie_node_id
!==
null
)
{
node_id
=
cookie_node_id
;
}
node
=
zTree
.
getNodesByParam
(
"id"
,
node_id
,
null
);
if
(
node
){
zTree
.
selectNode
(
node
[
0
]);
}
}
function
initTree
()
{
var
setting
=
{
view
:
{
dblClickExpand
:
false
,
showLine
:
true
},
data
:
{
simpleData
:
{
enable
:
true
}
},
callback
:
{
onSelected
:
onSelected
}
};
var
zNodes
=
[];
$
.
get
(
"{% url 'api-assets:node-list' %}"
,
function
(
data
,
status
){
$
.
each
(
data
,
function
(
index
,
value
)
{
value
[
"pId"
]
=
value
[
"parent"
];
{
#
if
(
value
[
"key"
]
===
"0"
)
{
#
}
value
[
"open"
]
=
true
;
{
#
}
#
}
value
[
"name"
]
=
value
[
"value"
]
$
(
document
).
ready
(
function
()
{
$
(
'.footable'
).
footable
();
$
(
'.select2'
).
select2
({
dropdownAutoWidth
:
true
,
width
:
'auto'
});
zNodes
=
data
;
$
.
fn
.
zTree
.
init
(
$
(
"#assetTree"
),
setting
,
zNodes
);
zTree
=
$
.
fn
.
zTree
.
getZTreeObj
(
"assetTree"
);
rMenu
=
$
(
"#rMenu"
);
selectQueryNode
();
$
(
'#date .input-daterange'
).
datepicker
({
format
:
"yyyy-mm-dd"
,
todayBtn
:
"linked"
,
keyboardNavigation
:
false
,
forceParse
:
false
,
calendarWeeks
:
true
,
autoclose
:
true
});
}
function
toggle
()
{
if
(
show
===
0
)
{
$
(
"#split-left"
).
hide
(
500
,
function
()
{
$
(
"#split-right"
).
attr
(
"class"
,
"col-lg-12"
);
$
(
"#toggle-icon"
).
attr
(
"class"
,
"fa fa-angle-right fa-x"
);
show
=
1
;
});
}
else
{
$
(
"#split-right"
).
attr
(
"class"
,
"col-lg-9"
);
$
(
"#toggle-icon"
).
attr
(
"class"
,
"fa fa-angle-left fa-x"
);
$
(
"#split-left"
).
show
(
500
);
show
=
0
;
}
}
$
(
document
).
ready
(
function
(){
initTable
();
initTree
();
})
.
on
(
'click'
,
'.btn-del'
,
function
()
{
var
$this
=
$
(
this
);
var
uid
=
$this
.
data
(
'uid'
);
var
name
=
$this
.
data
(
'name'
);
var
the_url
=
'{% url "api-perms:asset-permission-detail" pk=DEFAULT_PK %}'
.
replace
(
'{{ DEFAULT_PK }}'
,
uid
);
objectDelete
(
$this
,
name
,
the_url
);
})
.
on
(
'click'
,
'.btn-create-permission'
,
function
()
{
var
url
=
"{% url 'perms:asset-permission-create' %}"
;
var
nodes
=
zTree
.
getSelectedNodes
();
var
current_node
;
if
(
nodes
&&
nodes
.
length
===
1
){
current_node
=
nodes
[
0
];
url
+=
"?node_id="
+
current_node
.
id
;
}
window
.
open
(
url
,
'_self'
);
})
</script>
{% endblock %}
apps/perms/utils.py
View file @
d0ede246
...
...
@@ -2,16 +2,183 @@
from
__future__
import
absolute_import
,
unicode_literals
import
collections
from
collections
import
defaultdict
from
django.utils
import
timezone
from
django.utils.translation
import
ugettext
as
_
import
copy
from
common.utils
import
setattr_bulk
,
get_logger
from
.models
import
Node
Permission
from
common.utils
import
set
_or_append_
attr_bulk
,
get_logger
from
.models
import
Asset
Permission
logger
=
get_logger
(
__file__
)
class
AssetPermissionUtils
:
@staticmethod
def
get_user_permissions
(
user
):
return
AssetPermission
.
valid
.
all
()
.
filter
(
users
=
user
)
@staticmethod
def
get_user_group_permissions
(
user_group
):
return
AssetPermission
.
valid
.
all
()
.
filter
(
user_groups
=
user_group
)
@staticmethod
def
get_asset_permissions
(
asset
):
return
AssetPermission
.
valid
.
all
()
.
filter
(
assets
=
asset
)
@staticmethod
def
get_node_permissions
(
node
):
return
AssetPermission
.
valid
.
all
()
.
filter
(
nodes
=
node
)
@staticmethod
def
get_system_user_permissions
(
system_user
):
return
AssetPermission
.
objects
.
all
()
.
filter
(
system_users
=
system_user
)
@classmethod
def
get_user_group_nodes
(
cls
,
group
):
nodes
=
defaultdict
(
set
)
permissions
=
cls
.
get_user_group_permissions
(
group
)
for
perm
in
permissions
:
_nodes
=
perm
.
nodes
.
all
()
_system_users
=
perm
.
system_users
.
all
()
set_or_append_attr_bulk
(
_nodes
,
'permission'
,
perm
.
id
)
for
node
in
_nodes
:
nodes
[
node
]
.
update
(
set
(
_system_users
))
return
nodes
@classmethod
def
get_user_group_assets_direct
(
cls
,
group
):
assets
=
defaultdict
(
set
)
permissions
=
cls
.
get_user_group_permissions
(
group
)
for
perm
in
permissions
:
_assets
=
perm
.
assets
.
all
()
_system_users
=
perm
.
system_users
.
all
()
set_or_append_attr_bulk
(
_assets
,
'permission'
,
perm
.
id
)
for
asset
in
_assets
:
assets
[
asset
]
.
update
(
set
(
_system_users
))
return
assets
@classmethod
def
get_user_group_nodes_assets
(
cls
,
group
):
assets
=
defaultdict
(
set
)
nodes
=
cls
.
get_user_group_nodes
(
group
)
for
node
,
_system_users
in
nodes
.
items
():
_assets
=
node
.
get_all_assets
()
set_or_append_attr_bulk
(
_assets
,
'inherit_node'
,
node
.
id
)
set_or_append_attr_bulk
(
_assets
,
'permission'
,
getattr
(
node
,
'permission'
,
None
))
for
asset
in
_assets
:
assets
[
asset
]
.
update
(
set
(
_system_users
))
return
assets
@classmethod
def
get_user_group_assets
(
cls
,
group
):
assets
=
defaultdict
(
set
)
_assets
=
cls
.
get_user_group_assets_direct
(
group
)
_nodes_assets
=
cls
.
get_user_group_nodes_assets
(
group
)
for
asset
,
_system_users
in
_assets
.
items
():
assets
[
asset
]
.
update
(
set
(
_system_users
))
for
asset
,
_system_users
in
_nodes_assets
.
items
():
assets
[
asset
]
.
update
(
set
(
_system_users
))
return
assets
@classmethod
def
get_user_assets_direct
(
cls
,
user
):
assets
=
defaultdict
(
set
)
permissions
=
list
(
cls
.
get_user_permissions
(
user
))
for
perm
in
permissions
:
_assets
=
perm
.
assets
.
all
()
_system_users
=
perm
.
system_users
.
all
()
set_or_append_attr_bulk
(
_assets
,
'permission'
,
perm
.
id
)
for
asset
in
_assets
:
assets
[
asset
]
.
update
(
set
(
_system_users
))
return
assets
@classmethod
def
get_user_nodes_direct
(
cls
,
user
):
nodes
=
defaultdict
(
set
)
permissions
=
cls
.
get_user_permissions
(
user
)
for
perm
in
permissions
:
_nodes
=
perm
.
nodes
.
all
()
_system_users
=
perm
.
system_users
.
all
()
set_or_append_attr_bulk
(
_nodes
,
'permission'
,
perm
.
id
)
for
node
in
_nodes
:
nodes
[
node
]
.
update
(
set
(
_system_users
))
return
nodes
@classmethod
def
get_user_nodes_assets_direct
(
cls
,
user
):
assets
=
defaultdict
(
set
)
nodes
=
cls
.
get_user_nodes_direct
(
user
)
for
node
,
_system_users
in
nodes
.
items
():
_assets
=
node
.
get_all_assets
()
set_or_append_attr_bulk
(
_assets
,
'inherit_node'
,
node
.
id
)
set_or_append_attr_bulk
(
_assets
,
'permission'
,
getattr
(
node
,
'permission'
,
None
))
for
asset
in
_assets
:
assets
[
asset
]
.
update
(
set
(
_system_users
))
return
assets
@classmethod
def
get_user_assets_inherit_group
(
cls
,
user
):
assets
=
defaultdict
(
set
)
for
group
in
user
.
groups
.
all
():
_assets
=
cls
.
get_user_group_assets
(
group
)
set_or_append_attr_bulk
(
_assets
,
'inherit_group'
,
group
.
id
)
for
asset
,
_system_users
in
_assets
.
items
():
assets
[
asset
]
.
update
(
_system_users
)
return
assets
@classmethod
def
get_user_assets
(
cls
,
user
):
assets
=
defaultdict
(
set
)
_assets_direct
=
cls
.
get_user_assets_direct
(
user
)
_nodes_assets_direct
=
cls
.
get_user_nodes_assets_direct
(
user
)
_assets_inherit_group
=
cls
.
get_user_assets_inherit_group
(
user
)
for
asset
,
_system_users
in
_assets_direct
.
items
():
assets
[
asset
]
.
update
(
_system_users
)
for
asset
,
_system_users
in
_nodes_assets_direct
.
items
():
assets
[
asset
]
.
update
(
_system_users
)
for
asset
,
_system_users
in
_assets_inherit_group
.
items
():
assets
[
asset
]
.
update
(
_system_users
)
return
assets
@classmethod
def
get_user_node_with_assets
(
cls
,
user
):
"""
:param user:
:return: {node: {asset: set(su1, su2)}}
"""
nodes
=
defaultdict
(
dict
)
_assets
=
cls
.
get_user_assets
(
user
)
for
asset
,
_system_users
in
_assets
.
items
():
_nodes
=
asset
.
get_nodes
()
for
node
in
_nodes
:
if
asset
in
nodes
[
node
]:
nodes
[
node
][
asset
]
.
update
(
_system_users
)
else
:
nodes
[
node
][
asset
]
=
_system_users
return
nodes
@classmethod
def
get_system_user_assets
(
cls
,
system_user
):
assets
=
set
()
permissions
=
cls
.
get_system_user_permissions
(
system_user
)
for
perm
in
permissions
:
assets
.
update
(
set
(
perm
.
assets
.
all
()))
nodes
=
perm
.
nodes
.
all
()
for
node
in
nodes
:
assets
.
update
(
set
(
node
.
get_all_assets
()))
return
assets
@classmethod
def
get_node_system_users
(
cls
,
node
):
system_users
=
set
()
permissions
=
cls
.
get_node_permissions
(
node
)
for
perm
in
permissions
:
system_users
.
update
(
perm
.
system_users
.
all
())
return
system_users
class
NodePermissionUtil
:
@staticmethod
...
...
apps/perms/views.py
View file @
d0ede246
...
...
@@ -6,21 +6,65 @@ from django.utils.translation import ugettext as _
from
django.views.generic
import
ListView
,
CreateView
,
UpdateView
from
django.views.generic.edit
import
DeleteView
from
django.urls
import
reverse_lazy
from
django.conf
import
settings
from
django.db.models
import
Q
from
common.utils
import
get_object_or_none
from
.hands
import
AdminUserRequiredMixin
,
Node
from
.hands
import
AdminUserRequiredMixin
,
Node
,
User
,
UserGroup
,
Asset
,
SystemUser
from
.models
import
AssetPermission
,
NodePermission
from
.forms
import
AssetPermissionForm
class
AssetPermissionListView
(
AdminUserRequiredMixin
,
ListView
):
model
=
NodePermission
context_object_name
=
'asset_permission_list'
model
=
AssetPermission
template_name
=
'perms/asset_permission_list.html'
paginate_by
=
settings
.
DISPLAY_PER_PAGE
user
=
user_group
=
asset
=
node
=
system_user
=
q
=
""
def
get_queryset
(
self
):
self
.
q
=
self
.
request
.
GET
.
get
(
'q'
,
''
)
self
.
user
=
self
.
request
.
GET
.
get
(
"user"
,
''
)
self
.
user_group
=
self
.
request
.
GET
.
get
(
"user_group"
,
''
)
self
.
asset
=
self
.
request
.
GET
.
get
(
'asset'
,
''
)
self
.
node
=
self
.
request
.
GET
.
get
(
'node'
,
''
)
self
.
system_user
=
self
.
request
.
GET
.
get
(
'system_user'
,
''
)
filter_kwargs
=
dict
()
if
self
.
user
:
filter_kwargs
[
'users__name'
]
=
self
.
user
if
self
.
user_group
:
filter_kwargs
[
'user_groups__name'
]
=
self
.
user_group
if
self
.
asset
:
filter_kwargs
[
'assets__hostname'
]
=
self
.
asset
if
self
.
node
:
filter_kwargs
[
'nodes__value'
]
=
self
.
node
if
self
.
system_user
:
filter_kwargs
[
'system_users__name'
]
=
self
.
system_user
queryset
=
self
.
model
.
objects
.
filter
(
**
filter_kwargs
)
if
self
.
q
:
queryset
=
queryset
.
filter
(
Q
(
name__contains
=
self
.
q
)
|
Q
(
users__name
=
self
.
q
)
|
Q
(
user_groups__name
=
self
.
q
)
|
Q
(
assets__hostname
=
self
.
q
)
|
Q
(
nodes__value
=
self
.
q
)
|
Q
(
system_users__name
=
self
.
q
)
)
queryset
=
queryset
.
order_by
(
'-date_start'
)
return
queryset
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Perms'
),
'user_list'
:
User
.
objects
.
all
()
.
values_list
(
'name'
,
flat
=
True
),
'user_group_list'
:
UserGroup
.
objects
.
all
()
.
values_list
(
'name'
,
flat
=
True
),
'asset_list'
:
Asset
.
objects
.
all
()
.
values_list
(
'hostname'
,
flat
=
True
),
'node_list'
:
Node
.
objects
.
all
()
.
values_list
(
'value'
,
flat
=
True
),
'system_user_list'
:
SystemUser
.
objects
.
all
()
.
values_list
(
'name'
,
flat
=
True
),
'user'
:
self
.
user
,
'user_group'
:
self
.
user_group
,
'asset'
:
self
.
asset
,
'node'
:
self
.
node
,
'system_user'
:
self
.
system_user
,
'q'
:
self
.
q
,
'action'
:
_
(
'Asset permission list'
),
}
kwargs
.
update
(
context
)
...
...
@@ -28,20 +72,11 @@ class AssetPermissionListView(AdminUserRequiredMixin, ListView):
class
AssetPermissionCreateView
(
AdminUserRequiredMixin
,
CreateView
):
model
=
Node
Permission
model
=
Asset
Permission
form_class
=
AssetPermissionForm
template_name
=
'perms/asset_permission_create_update.html'
success_url
=
reverse_lazy
(
'perms:asset-permission-list'
)
def
get_form
(
self
,
form_class
=
None
):
form
=
super
()
.
get_form
(
form_class
=
form_class
)
node_id
=
self
.
request
.
GET
.
get
(
"node_id"
)
node
=
get_object_or_none
(
Node
,
id
=
node_id
)
if
not
node
:
node
=
Node
.
root
()
form
[
'node'
]
.
initial
=
node
return
form
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Perms'
),
...
...
@@ -52,16 +87,11 @@ class AssetPermissionCreateView(AdminUserRequiredMixin, CreateView):
class
AssetPermissionUpdateView
(
AdminUserRequiredMixin
,
UpdateView
):
model
=
Node
Permission
model
=
Asset
Permission
form_class
=
AssetPermissionForm
template_name
=
'perms/asset_permission_create_update.html'
success_url
=
reverse_lazy
(
"perms:asset-permission-list"
)
def
get_form
(
self
,
form_class
=
None
):
form
=
super
()
.
get_form
(
form_class
=
form_class
)
form
[
'node'
]
.
initial
=
form
.
instance
.
node
return
form
def
get_context_data
(
self
,
**
kwargs
):
context
=
{
'app'
:
_
(
'Perms'
),
...
...
apps/terminal/templates/terminal/command_list.html
View file @
d0ede246
...
...
@@ -18,7 +18,7 @@
{% endblock %}
{% block table_search %}
<form
id=
"search_form"
method=
"get"
action=
""
class=
"pull-right form-inline"
>
<form
id=
"search_form"
method=
"get"
action=
""
class=
"pull-right form-inline"
style=
"padding-bottom: 8px"
>
<div
class=
"form-group"
id=
"date"
>
<div
class=
"input-daterange input-group"
id=
"datepicker"
>
<span
class=
"input-group-addon"
><i
class=
"fa fa-calendar"
></i></span>
...
...
@@ -64,7 +64,7 @@
</form>
{% endblock %}
{% block table_container %}
<table
class=
"footable table table-stripped t
oggle-arrow-tiny"
data-page=
"false"
>
<table
class=
"footable table table-stripped t
able-bordered toggle-arrow-tiny"
data-page=
"false"
>
<thead>
<tr>
<th
data-toggle=
"true"
>
ID
</th>
...
...
apps/users/forms.py
View file @
d0ede246
...
...
@@ -6,7 +6,6 @@ from django.utils.translation import gettext_lazy as _
from
captcha.fields
import
CaptchaField
from
common.utils
import
validate_ssh_public_key
from
perms.models
import
AssetPermission
from
.models
import
User
,
UserGroup
...
...
@@ -253,30 +252,30 @@ class UserGroupForm(forms.ModelForm):
}
class
UserGroupPrivateAssetPermissionForm
(
forms
.
ModelForm
):
def
save
(
self
,
commit
=
True
):
self
.
instance
=
super
(
UserGroupPrivateAssetPermissionForm
,
self
)
\
.
save
(
commit
=
commit
)
self
.
instance
.
user_groups
=
[
self
.
user_group
]
self
.
instance
.
save
()
return
self
.
instance
class
Meta
:
model
=
AssetPermission
fields
=
[
'assets'
,
'asset_groups'
,
'system_users'
,
'name'
,
]
widgets
=
{
'assets'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select assets'
)}),
'asset_groups'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select asset groups'
)}),
'system_users'
:
forms
.
SelectMultiple
(
attrs
=
{
'class'
:
'select2'
,
'data-placeholder'
:
_
(
'Select system users'
)}),
}
#
class UserGroupPrivateAssetPermissionForm(forms.ModelForm):
#
def save(self, commit=True):
#
self.instance = super(UserGroupPrivateAssetPermissionForm, self)\
#
.save(commit=commit)
#
self.instance.user_groups = [self.user_group]
#
self.instance.save()
#
return self.instance
#
#
class Meta:
#
model = AssetPermission
#
fields = [
#
'assets', 'asset_groups', 'system_users', 'name',
#
]
#
widgets = {
#
'assets': forms.SelectMultiple(
#
attrs={'class': 'select2',
#
'data-placeholder': _('Select assets')}),
#
'asset_groups': forms.SelectMultiple(
#
attrs={'class': 'select2',
#
'data-placeholder': _('Select asset groups')}),
#
'system_users': forms.SelectMultiple(
#
attrs={'class': 'select2',
#
'data-placeholder': _('Select system users')}),
#
}
class
FileForm
(
forms
.
Form
):
...
...
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