permission user search

pull/530/head
ibuler 2016-09-14 01:08:26 +08:00
parent 4c4f598552
commit 5bca783e12
11 changed files with 288 additions and 38 deletions

View File

@ -33,10 +33,6 @@
<i class="fa fa-wrench"></i> <i class="fa fa-wrench"></i>
</a> </a>
<ul class="dropdown-menu dropdown-user"> <ul class="dropdown-menu dropdown-user">
<li><a href="#"></a>
</li>
<li><a href="#"></a>
</li>
</ul> </ul>
<a class="close-link"> <a class="close-link">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
@ -78,10 +74,6 @@
<i class="fa fa-wrench"></i> <i class="fa fa-wrench"></i>
</a> </a>
<ul class="dropdown-menu dropdown-user"> <ul class="dropdown-menu dropdown-user">
<li><a href="#"></a>
</li>
<li><a href="#"></a>
</li>
</ul> </ul>
<a class="close-link"> <a class="close-link">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>

View File

@ -39,10 +39,6 @@
<i class="fa fa-wrench"></i> <i class="fa fa-wrench"></i>
</a> </a>
<ul class="dropdown-menu dropdown-user"> <ul class="dropdown-menu dropdown-user">
<li><a href="#"></a>
</li>
<li><a href="#"></a>
</li>
</ul> </ul>
<a class="close-link"> <a class="close-link">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>

View File

@ -40,10 +40,6 @@
<i class="fa fa-wrench"></i> <i class="fa fa-wrench"></i>
</a> </a>
<ul class="dropdown-menu dropdown-user"> <ul class="dropdown-menu dropdown-user">
<li><a href="#"></a>
</li>
<li><a href="#"></a>
</li>
</ul> </ul>
<a class="close-link"> <a class="close-link">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>

View File

@ -42,10 +42,6 @@
<i class="fa fa-wrench"></i> <i class="fa fa-wrench"></i>
</a> </a>
<ul class="dropdown-menu dropdown-user"> <ul class="dropdown-menu dropdown-user">
<li><a href="#"></a>
</li>
<li><a href="#"></a>
</li>
</ul> </ul>
<a class="close-link"> <a class="close-link">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>

View File

@ -2,6 +2,8 @@
# #
from __future__ import unicode_literals from __future__ import unicode_literals
from itertools import chain
import string
from django.shortcuts import reverse as dj_reverse from django.shortcuts import reverse as dj_reverse
from django.conf import settings from django.conf import settings
@ -40,3 +42,44 @@ def date_expired_default():
years = 70 years = 70
return timezone.now() + timezone.timedelta(days=365 * years) return timezone.now() + timezone.timedelta(days=365 * years)
def combine_seq(s1, s2, callback=None):
for s in (s1, s2):
if not hasattr(s, '__iter__'):
return []
seq = chain(s1, s2)
if callback:
seq = map(callback, seq)
return seq
def search_object_attr(obj, value='', attr_list=None, ignore_case=False):
try:
object_attr = obj.__dict__
except AttributeError:
return False
if not isinstance(value, str):
return False
if value == '':
return True
if attr_list is not None:
for attr in attr_list:
object_attr.pop(attr)
print(value)
print(object_attr)
if ignore_case:
if value.lower() in map(string.lower, filter(lambda x: isinstance(x, (str, unicode)), object_attr.values())):
return True
else:
if value in object_attr.values():
return True
return False

View File

@ -1,4 +1,5 @@
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
import functools
from django.db import models from django.db import models
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
@ -6,7 +7,7 @@ from django.utils import timezone
from users.models import User, UserGroup from users.models import User, UserGroup
from assets.models import Asset, AssetGroup, SystemUser from assets.models import Asset, AssetGroup, SystemUser
from common.utils import date_expired_default from common.utils import date_expired_default, combine_seq
class AssetPermission(models.Model): class AssetPermission(models.Model):
@ -16,8 +17,8 @@ class AssetPermission(models.Model):
) )
name = models.CharField(max_length=128, verbose_name=_('Name')) name = models.CharField(max_length=128, verbose_name=_('Name'))
users = models.ManyToManyField(User, related_name='asset_permissions') users = models.ManyToManyField(User, related_name='asset_permissions', blank=True)
user_groups = models.ManyToManyField(UserGroup, related_name='asset_permissions') user_groups = models.ManyToManyField(UserGroup, related_name='asset_permissions', blank=True)
assets = models.ManyToManyField(Asset, related_name='granted_by_permissions', blank=True) assets = models.ManyToManyField(Asset, related_name='granted_by_permissions', blank=True)
asset_groups = models.ManyToManyField(AssetGroup, related_name='granted_by_permissions', blank=True) asset_groups = models.ManyToManyField(AssetGroup, related_name='granted_by_permissions', blank=True)
system_users = models.ManyToManyField(SystemUser, related_name='granted_by_permissions') system_users = models.ManyToManyField(SystemUser, related_name='granted_by_permissions')
@ -37,6 +38,33 @@ class AssetPermission(models.Model):
return True return True
return True return True
@staticmethod
def set_inherit(obj):
setattr(obj, 'inherited', True)
return obj
def get_granted_users(self):
return list(set(self.users.all() or []) | set(self.get_granted_user_groups_member()))
def get_granted_user_groups_member(self):
combine_users = functools.partial(combine_seq, callback=AssetPermission.set_inherit)
try:
return functools.reduce(combine_users, [user_group.users.all()
for user_group in self.user_groups.iterator()])
except TypeError:
return []
def get_granted_assets(self):
return list(self.assets.all() or []) | set(self.get_granted_asset_groups_member())
def get_granted_asset_groups_member(self):
combine_assets = functools.partial(combine_seq, callback=AssetPermission.set_inherit)
try:
return functools.reduce(combine_assets, [asset_group.users.all()
for asset_group in self.asset_groups.iterator()])
except TypeError:
return []
class Meta: class Meta:
db_table = 'asset_permission' db_table = 'asset_permission'

View File

@ -0,0 +1,186 @@
{% extends 'base.html' %}
{% load common_tags %}
{% load users_tags %}
{% load static %}
{% load i18n %}
{% block custom_head_css_js %}
<link href="{% static "css/plugins/select2/select2.min.css" %}" rel="stylesheet">
<script src="{% static "js/plugins/select2/select2.full.min.js" %}"></script>
{% endblock %}
{% block content %}
<div class="wrapper wrapper-content animated fadeInRight">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="panel-options">
<ul class="nav nav-tabs">
<li>
<a href="{% url 'perms:asset-permission-detail' pk=asset_permission.id %}" class="text-center">
<i class="fa fa-laptop"></i> {% trans 'Detail' %} </a>
</li>
<li>
<a href="{% url 'perms:asset-permission-user-list' pk=asset_permission.id %}" class="text-center">
<i class="fa fa-bar-chart-o"></i> {% trans 'Users and user groups' %}
</a>
</li>
<li class="active">
<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>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-sm-7" style="padding-left: 0;">
<div class="ibox float-e-margins">
<div class="ibox-title">
<span style="float: left">{% trans 'Asset list of ' %} <b>{{ asset_permission.name }}</b></span>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
<i class="fa fa-wrench"></i>
</a>
<ul class="dropdown-menu dropdown-user">
</ul>
<a class="close-link">
<i class="fa fa-times"></i>
</a>
</div>
</div>
<div class="ibox-content">
<table class="table table-hover">
<thead>
<tr>
<th>{% trans 'Hostname' %}</th>
<th>{% trans 'IP' %}</th>
<th>{% trans 'Port' %}</th>
<th>{% trans 'Is valid' %}</th>
<th></th>
</tr>
</thead>
<tbody>
{% for user in page_obj %}
<tr>
<td>{{ user.name }}</td>
<td>{{ user.username }}</td>
<td>{{ user.email }}</td>
<td>
{% if user.is_expired and user.is_active %}
<i class="fa fa-times text-danger"></i>
{% else %}
<i class="fa fa-check text-navy"></i>
{% endif %}
</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>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="row">
{% include '_pagination.html' %}
</div>
</div>
</div>
</div>
<div class="col-sm-5" style="padding-left: 0;padding-right: 0">
<div class="panel panel-primary">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Add user to asset permission' %}
</div>
<div class="panel-body">
<table class="table">
<tbody>
<form>
<tr class="no-borders-tr">
<td colspan="2">
<select data-placeholder="{% trans 'Select user' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for user in users_remain %}
<option value="{{ user.id }}">{{ user.name }}: {{ user.username }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr class="no-borders-tr">
<td colspan="2">
<button type="button" class="btn btn-primary btn-sm">{% trans 'Add' %}</button>
</td>
</tr>
</form>
</tbody>
</table>
</div>
</div>
<div class="panel panel-info">
<div class="panel-heading">
<i class="fa fa-info-circle"></i> {% trans 'Add user group to asset permission' %}
</div>
<div class="panel-body">
<table class="table group_edit">
<tbody>
<form>
<tr>
<td colspan="2" class="no-borders">
<select data-placeholder="{% trans 'Select user groups' %}" class="select2" style="width: 100%" multiple="" tabindex="4">
{% for user_group in user_groups_remain %}
<option value="{{ user_group.id }}" id="opt_{{ user_group.id }}">{{ user_group.name }}</option>
{% endfor %}
</select>
</td>
</tr>
<tr>
<td colspan="2" class="no-borders">
<button type="button" class="btn btn-info btn-small" id="btn_add_user_group">{% trans 'Join' %}</button>
</td>
</tr>
</form>
{% for user_group in user_groups %}
<tr>
<td ><b class="bdg_user_group" data-gid={{ user_group.id }}>{{ user_group.name }}</b></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>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block custom_foot_js %}
<script>
{# function switch_user_status(obj) {#}
{# var status = $(obj).prop('checked');#}
{##}
{# $.ajax({#}
{# url: "{% url 'users:user-active-api' pk=user.id %}",#}
{# type: "PUT",#}
{# data: {#}
{# 'is_active': status#}
{# },#}
{# success: function (data, status) {#}
{# console.log(data)#}
{# },#}
{# error: function () {#}
{# console.log('error')#}
{# }#}
{# })#}
{# }#}
$(document).ready(function () {
$('.select2').select2();
});
</script>
{% endblock %}

View File

@ -43,10 +43,6 @@
<i class="fa fa-wrench"></i> <i class="fa fa-wrench"></i>
</a> </a>
<ul class="dropdown-menu dropdown-user"> <ul class="dropdown-menu dropdown-user">
<li><a href="#"></a>
</li>
<li><a href="#"></a>
</li>
</ul> </ul>
<a class="close-link"> <a class="close-link">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>

View File

@ -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="">
<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">
@ -43,10 +53,6 @@
<i class="fa fa-wrench"></i> <i class="fa fa-wrench"></i>
</a> </a>
<ul class="dropdown-menu dropdown-user"> <ul class="dropdown-menu dropdown-user">
<li><a href="#"></a>
</li>
<li><a href="#"></a>
</li>
</ul> </ul>
<a class="close-link"> <a class="close-link">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
@ -60,7 +66,8 @@
<th>{% trans 'Name' %}</th> <th>{% trans 'Name' %}</th>
<th>{% trans 'Username' %}</th> <th>{% trans 'Username' %}</th>
<th>{% trans 'Email' %}</th> <th>{% trans 'Email' %}</th>
<th>{% trans 'Active' %}</th> <th>{% trans 'Is valid' %}</th>
<th></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -77,6 +84,9 @@
{% endif %} {% endif %}
</td> </td>
<td>
<button class="btn btn-danger btn-xs btn_delete_user_group {% if user.inherited %} disabled {% endif %}" type="button" style="float: right;"><i class="fa fa-minus"></i></button>
</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>

View File

@ -1,6 +1,7 @@
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
from __future__ import unicode_literals, absolute_import from __future__ import unicode_literals, absolute_import
import functools
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.conf import settings from django.conf import settings
@ -11,6 +12,7 @@ from django.urls import reverse_lazy
from django.contrib.messages.views import SuccessMessageMixin 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 .hands import AdminUserRequiredMixin, User, UserGroup, SystemUser from .hands import AdminUserRequiredMixin, User, UserGroup, SystemUser
from .models import AssetPermission from .models import AssetPermission
from .forms import AssetPermissionForm from .forms import AssetPermissionForm
@ -124,10 +126,19 @@ 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', '')
return super(AssetPermissionUserListView, self).get(request, *args, **kwargs) return super(AssetPermissionUserListView, self).get(request, *args, **kwargs)
def get_queryset(self): def get_queryset(self):
return self.object.users.all() print(self.keyword)
queryset = self.object.get_granted_users()
if self.keyword:
search_func = functools.partial(search_object_attr, value=self.keyword,
attr_list=['name', 'username', 'email'],
ignore_case=True)
queryset = filter(search_func, queryset[:])
return queryset
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {

View File

@ -34,10 +34,6 @@
<i class="fa fa-wrench"></i> <i class="fa fa-wrench"></i>
</a> </a>
<ul class="dropdown-menu dropdown-user"> <ul class="dropdown-menu dropdown-user">
<li><a href="#"></a>
</li>
<li><a href="#"></a>
</li>
</ul> </ul>
<a class="close-link"> <a class="close-link">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>