[Update] 修改授权

pull/1185/head
ibuler 2018-04-08 00:16:37 +08:00
parent cb8e59edf2
commit d0ede246e7
11 changed files with 494 additions and 318 deletions

View File

@ -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:

View File

@ -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)

View File

@ -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类型。

View File

@ -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"),
}

View File

@ -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)

View File

@ -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 %}

View File

@ -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 %}

View File

@ -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

View File

@ -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'),

View File

@ -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>

View File

@ -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):