mirror of https://github.com/jumpserver/jumpserver
[Update] 修改授权
parent
cb8e59edf2
commit
d0ede246e7
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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类型。
|
||||
|
||||
|
|
|
@ -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 NodePermission
|
||||
from .models import AssetPermission
|
||||
|
||||
|
||||
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_groups': 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"),
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,17 +49,19 @@
|
|||
{{ 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>
|
||||
</div>
|
||||
{% bootstrap_field form.comment layout="horizontal" %}
|
||||
|
||||
<div class="form-group">
|
||||
|
@ -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 %}
|
|
@ -1,238 +1,154 @@
|
|||
{% 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;
|
||||
<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;
|
||||
}
|
||||
div#rMenu li{
|
||||
margin: 1px 0;
|
||||
cursor: pointer;
|
||||
{#list-style: none outside none;#}
|
||||
}
|
||||
.dropdown a:hover {
|
||||
background-color: #f1f1f1
|
||||
}
|
||||
</style>
|
||||
</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">
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</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>
|
||||
</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%">
|
||||
<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 class="text-center">{% trans 'User group' %}</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>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% 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>
|
||||
<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="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>
|
||||
</form>
|
||||
{% endblock %}
|
||||
{% block table_container %}
|
||||
<table class="footable table table-stripped table-bordered toggle-arrow-tiny" data-page="false">
|
||||
<thead>
|
||||
<tr>
|
||||
<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 '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>
|
||||
{% 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'
|
||||
});
|
||||
$('#date .input-daterange').datepicker({
|
||||
format: "yyyy-mm-dd",
|
||||
todayBtn: "linked",
|
||||
keyboardNavigation: false,
|
||||
forceParse: false,
|
||||
calendarWeeks: true,
|
||||
autoclose: true
|
||||
});
|
||||
zNodes = data;
|
||||
$.fn.zTree.init($("#assetTree"), setting, zNodes);
|
||||
zTree = $.fn.zTree.getZTreeObj("assetTree");
|
||||
rMenu = $("#rMenu");
|
||||
selectQueryNode();
|
||||
});
|
||||
}
|
||||
|
||||
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 %}
|
||||
|
||||
|
||||
|
|
|
@ -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 NodePermission
|
||||
from common.utils import set_or_append_attr_bulk, get_logger
|
||||
from .models import AssetPermission
|
||||
|
||||
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
|
||||
|
|
|
@ -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 = NodePermission
|
||||
model = AssetPermission
|
||||
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 = NodePermission
|
||||
model = AssetPermission
|
||||
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'),
|
||||
|
|
|
@ -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 toggle-arrow-tiny" data-page="false">
|
||||
<table class="footable table table-stripped table-bordered toggle-arrow-tiny" data-page="false" >
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-toggle="true">ID</th>
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue