Commit a4dc27f0 authored by ibuler's avatar ibuler

Finish permissin detail asset list and user list

parent 5bca783e
# Common app
Common app provide common view, function or others.
Common app shouldn't rely on other apps, because It may lead to cycle
import.
If your want to implement some function or class, you should think
whether other app use or not. If yes, You should make in common.
If the ability more relate to your app tightness, It's mean your app
provide this ability, not common, You should write it on your app utils.
## Celery usage ## Celery usage
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# #
from __future__ import unicode_literals from __future__ import unicode_literals
from six import string_types
from itertools import chain from itertools import chain
import string import string
...@@ -52,30 +53,43 @@ def combine_seq(s1, s2, callback=None): ...@@ -52,30 +53,43 @@ def combine_seq(s1, s2, callback=None):
seq = chain(s1, s2) seq = chain(s1, s2)
if callback: if callback:
seq = map(callback, seq) seq = map(callback, seq)
return seq return seq
def search_object_attr(obj, value='', attr_list=None, ignore_case=False): def search_object_attr(obj, value='', attr_list=None, ignore_case=False):
try: """It's provide a method to search a object attribute equal some value
object_attr = obj.__dict__
except AttributeError:
return False
if not isinstance(value, str): If object some attribute equal :param: value, return True else return False
return False
class A():
name = 'admin'
age = 7
:param obj: A object
:param value: A string match object attribute
:param attr_list: Only match attribute in attr_list
:param ignore_case: Ignore case
:return: Boolean
"""
if value == '': if value == '':
return True return True
try:
object_attr = obj.__dict__
except AttributeError:
return False
if attr_list is not None: if attr_list is not None:
new_object_attr = {}
for attr in attr_list: for attr in attr_list:
object_attr.pop(attr) new_object_attr[attr] = object_attr.pop(attr)
object_attr = new_object_attr
print(value)
print(object_attr)
if ignore_case: if ignore_case:
if value.lower() in map(string.lower, filter(lambda x: isinstance(x, (str, unicode)), object_attr.values())): if not isinstance(value, string_types):
return False
if value.lower() in map(string.lower, map(str, object_attr.values())):
return True return True
else: else:
if value in object_attr.values(): if value in object_attr.values():
......
...@@ -55,7 +55,7 @@ class AssetPermission(models.Model): ...@@ -55,7 +55,7 @@ class AssetPermission(models.Model):
return [] return []
def get_granted_assets(self): def get_granted_assets(self):
return list(self.assets.all() or []) | set(self.get_granted_asset_groups_member()) return list(set(self.assets.all() or []) | set(self.get_granted_asset_groups_member()))
def get_granted_asset_groups_member(self): def get_granted_asset_groups_member(self):
combine_assets = functools.partial(combine_seq, callback=AssetPermission.set_inherit) combine_assets = functools.partial(combine_seq, callback=AssetPermission.set_inherit)
......
...@@ -28,6 +28,16 @@ ...@@ -28,6 +28,16 @@
<a href="{% url 'perms:asset-permission-asset-list' pk=asset_permission.id %}" class="text-center"> <a href="{% url 'perms:asset-permission-asset-list' pk=asset_permission.id %}" class="text-center">
<i class="fa fa-bar-chart-o"></i> {% trans 'Assets and asset gruops' %}</a> <i class="fa fa-bar-chart-o"></i> {% trans 'Assets and asset gruops' %}</a>
</li> </li>
<form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group">
<input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}">
<div class="input-group-btn">
<button id="search_btn" type="submit" class="btn btn-sm btn-primary">
搜索
</button>
</div>
</div>
</form>
</ul> </ul>
</div> </div>
<div class="tab-content"> <div class="tab-content">
...@@ -61,13 +71,13 @@ ...@@ -61,13 +71,13 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for user in page_obj %} {% for asset in page_obj %}
<tr> <tr>
<td>{{ user.name }}</td> <td>{{ asset.hostname }}</td>
<td>{{ user.username }}</td> <td>{{ asset.ip }}</td>
<td>{{ user.email }}</td> <td>{{ user.port }}</td>
<td> <td>
{% if user.is_expired and user.is_active %} {% if asset.is_active %}
<i class="fa fa-times text-danger"></i> <i class="fa fa-times text-danger"></i>
{% else %} {% else %}
<i class="fa fa-check text-navy"></i> <i class="fa fa-check text-navy"></i>
...@@ -90,7 +100,7 @@ ...@@ -90,7 +100,7 @@
<div class="col-sm-5" style="padding-left: 0;padding-right: 0"> <div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary"> <div class="panel panel-primary">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Add user to asset permission' %} <i class="fa fa-info-circle"></i> {% trans 'Add asset to this permission' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table"> <table class="table">
...@@ -98,9 +108,9 @@ ...@@ -98,9 +108,9 @@
<form> <form>
<tr class="no-borders-tr"> <tr class="no-borders-tr">
<td colspan="2"> <td colspan="2">
<select data-placeholder="{% trans 'Select user' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select asset ' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for user in users_remain %} {% for asset in asset_remain %}
<option value="{{ user.id }}">{{ user.name }}: {{ user.username }}</option> <option value="{{ asset.id }}">{{ asset.hostname }}: {{ asset.ip }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
...@@ -118,7 +128,7 @@ ...@@ -118,7 +128,7 @@
<div class="panel panel-info"> <div class="panel panel-info">
<div class="panel-heading"> <div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Add user group to asset permission' %} <i class="fa fa-info-circle"></i> {% trans 'Add asset group to this permission' %}
</div> </div>
<div class="panel-body"> <div class="panel-body">
<table class="table group_edit"> <table class="table group_edit">
...@@ -126,9 +136,9 @@ ...@@ -126,9 +136,9 @@
<form> <form>
<tr> <tr>
<td colspan="2" class="no-borders"> <td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Select user groups' %}" class="select2" style="width: 100%" multiple="" tabindex="4"> <select data-placeholder="{% trans 'Select asset groups' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for user_group in user_groups_remain %} {% for asset_group in asset_groups_remain %}
<option value="{{ user_group.id }}" id="opt_{{ user_group.id }}">{{ user_group.name }}</option> <option value="{{ asset_group.id }}">{{ asset_group.name }}</option>
{% endfor %} {% endfor %}
</select> </select>
</td> </td>
...@@ -140,9 +150,9 @@ ...@@ -140,9 +150,9 @@
</tr> </tr>
</form> </form>
{% for user_group in user_groups %} {% for asset_group in asset_groups %}
<tr> <tr>
<td ><b class="bdg_user_group" data-gid={{ user_group.id }}>{{ user_group.name }}</b></td> <td ><b class="bdg_user_group" data-gid={{ asset_group.id }}>{{ asset_group.name }}</b></td>
<td> <td>
<button class="btn btn-danger btn-xs btn_delete_user_group" type="button" style="float: right;"><i class="fa fa-minus"></i></button> <button class="btn btn-danger btn-xs btn_delete_user_group" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
</td> </td>
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
</li> </li>
<form id="search_form" method="get" action="" class="pull-right mail-search"> <form id="search_form" method="get" action="" class="pull-right mail-search">
<div class="input-group"> <div class="input-group">
<input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value=""> <input type="text" class="form-control input-sm" name="keyword" placeholder="Search" value="{{ keyword }}">
<div class="input-group-btn"> <div class="input-group-btn">
<button id="search_btn" type="submit" class="btn btn-sm btn-primary"> <button id="search_btn" type="submit" class="btn btn-sm btn-primary">
搜索 搜索
......
...@@ -13,7 +13,7 @@ from django.contrib.messages.views import SuccessMessageMixin ...@@ -13,7 +13,7 @@ from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin from django.views.generic.detail import DetailView, SingleObjectMixin
from common.utils import search_object_attr from common.utils import search_object_attr
from .hands import AdminUserRequiredMixin, User, UserGroup, SystemUser from .hands import AdminUserRequiredMixin, User, UserGroup, SystemUser, Asset, AssetGroup
from .models import AssetPermission from .models import AssetPermission
from .forms import AssetPermissionForm from .forms import AssetPermissionForm
...@@ -28,7 +28,7 @@ class AssetPermissionListView(AdminUserRequiredMixin, ListView): ...@@ -28,7 +28,7 @@ class AssetPermissionListView(AdminUserRequiredMixin, ListView):
context = { context = {
'app': _('Perms'), 'app': _('Perms'),
'action': _('Asset permission list'), 'action': _('Asset permission list'),
'keyword': self.request.GET.get('keyword', '') 'keyword': self.keyword,
} }
kwargs.update(context) kwargs.update(context)
return super(AssetPermissionListView, self).get_context_data(**kwargs) return super(AssetPermissionListView, self).get_context_data(**kwargs)
...@@ -40,16 +40,16 @@ class AssetPermissionListView(AdminUserRequiredMixin, ListView): ...@@ -40,16 +40,16 @@ class AssetPermissionListView(AdminUserRequiredMixin, ListView):
self.sort = sort = self.request.GET.get('sort', '-date_created') self.sort = sort = self.request.GET.get('sort', '-date_created')
if keyword: if keyword:
self.queryset = self.queryset.filter(Q(users__name__icontains=keyword) | self.queryset = self.queryset.filter(Q(users__name__contains=keyword) |
Q(users__username__icontains=keyword) | Q(users__username__contains=keyword) |
Q(user_groups__name__icontains=keyword) | Q(user_groups__name__contains=keyword) |
Q(assets__ip__icontains=keyword) | Q(assets__ip__contains=keyword) |
Q(assets__hostname__icontains=keyword) | Q(assets__hostname__contains=keyword) |
Q(system_users__username_icontains=keyword) | Q(system_users__username__icontains=keyword) |
Q(system_users__name_icontains=keyword) | Q(system_users__name__icontains=keyword) |
Q(asset_groups__name__icontains=keyword) | Q(asset_groups__name__icontains=keyword) |
Q(comment__icontains=keyword)) Q(comment__icontains=keyword) |
Q(name__icontains=keyword)).distinct()
if sort: if sort:
self.queryset = self.queryset.order_by(sort) self.queryset = self.queryset.order_by(sort)
return self.queryset return self.queryset
...@@ -126,32 +126,64 @@ class AssetPermissionUserListView(AdminUserRequiredMixin, SingleObjectMixin, Lis ...@@ -126,32 +126,64 @@ class AssetPermissionUserListView(AdminUserRequiredMixin, SingleObjectMixin, Lis
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=AssetPermission.objects.all()) self.object = self.get_object(queryset=AssetPermission.objects.all())
self.keyword = keyword = self.request.GET.get('keyword', '') self.keyword = self.request.GET.get('keyword', '')
return super(AssetPermissionUserListView, self).get(request, *args, **kwargs) return super(AssetPermissionUserListView, self).get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
print(self.keyword)
queryset = self.object.get_granted_users() queryset = self.object.get_granted_users()
if self.keyword: if self.keyword:
search_func = functools.partial(search_object_attr, value=self.keyword, search_func = functools.partial(search_object_attr, value=self.keyword,
attr_list=['name', 'username', 'email'], attr_list=['username', 'name', 'email'],
ignore_case=True) ignore_case=True)
queryset = filter(search_func, queryset[:]) queryset = filter(search_func, queryset)
return queryset return queryset
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
users_granted = self.get_queryset()
user_groups_granted = self.object.user_groups.all()
context = { context = {
'app': _('Perms'), 'app': _('Perms'),
'action': _('Asset permission user list'), 'action': _('Asset permission user list'),
'users_remain': [user for user in User.objects.all() if user not in self.get_queryset()], 'users_remain': [user for user in User.objects.all() if user not in users_granted],
'user_groups': self.object.user_groups.all(), 'user_groups': self.object.user_groups.all(),
'user_groups_remain': [user_group for user_group in UserGroup.objects.all() 'user_groups_remain': [user_group for user_group in UserGroup.objects.all()
if user_group not in self.object.user_groups.all()] if user_group not in user_groups_granted],
'keyword': self.keyword,
} }
kwargs.update(context) kwargs.update(context)
return super(AssetPermissionUserListView, self).get_context_data(**kwargs) return super(AssetPermissionUserListView, self).get_context_data(**kwargs)
class AssetPermissionAssetListView(AdminUserRequiredMixin, ListView): class AssetPermissionAssetListView(AdminUserRequiredMixin, SingleObjectMixin, ListView):
pass template_name = 'perms/asset_permission_asset_list.html'
context_object_name = 'asset_permission'
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=AssetPermission.objects.all())
self.keyword = self.request.GET.get('keyword', '')
return super(AssetPermissionAssetListView, self).get(request, *args, **kwargs)
def get_queryset(self):
queryset = self.object.get_granted_assets()
if self.keyword:
search_func = functools.partial(search_object_attr, value=self.keyword,
attr_list=['hostname', 'ip'],
ignore_case=True)
queryset = filter(search_func, queryset)
return queryset
def get_context_data(self, **kwargs):
assets_granted = self.get_queryset()
asset_groups_granted = self.object.user_groups.all()
context = {
'app': _('Perms'),
'action': _('Asset permission asset list'),
'assets_remain': (asset for asset in Asset.objects.all() if asset not in assets_granted),
'asset_groups': self.object.asset_groups.all(),
'asset_groups_remain': [asset_group for asset_group in AssetGroup.objects.all()
if asset_group not in asset_groups_granted],
'keyword': self.keyword,
}
kwargs.update(context)
return super(AssetPermissionAssetListView, self).get_context_data(**kwargs)
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