Commit d0ede246 authored by ibuler's avatar ibuler

[Update] 修改授权

parent cb8e59ed
......@@ -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 %}
\ No newline at end of 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
......
......@@ -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):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment