mirror of https://github.com/jumpserver/jumpserver
permission user search
parent
4c4f598552
commit
5bca783e12
|
@ -33,10 +33,6 @@
|
|||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
|
@ -78,10 +74,6 @@
|
|||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
|
|
|
@ -39,10 +39,6 @@
|
|||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
|
|
|
@ -40,10 +40,6 @@
|
|||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
|
|
|
@ -42,10 +42,6 @@
|
|||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from itertools import chain
|
||||
import string
|
||||
|
||||
from django.shortcuts import reverse as dj_reverse
|
||||
from django.conf import settings
|
||||
|
@ -40,3 +42,44 @@ def date_expired_default():
|
|||
years = 70
|
||||
|
||||
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
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from __future__ import unicode_literals, absolute_import
|
||||
import functools
|
||||
|
||||
from django.db import models
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
@ -6,7 +7,7 @@ from django.utils import timezone
|
|||
|
||||
from users.models import User, UserGroup
|
||||
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):
|
||||
|
@ -16,8 +17,8 @@ class AssetPermission(models.Model):
|
|||
)
|
||||
|
||||
name = models.CharField(max_length=128, verbose_name=_('Name'))
|
||||
users = models.ManyToManyField(User, related_name='asset_permissions')
|
||||
user_groups = models.ManyToManyField(UserGroup, related_name='asset_permissions')
|
||||
users = models.ManyToManyField(User, related_name='asset_permissions', blank=True)
|
||||
user_groups = models.ManyToManyField(UserGroup, related_name='asset_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)
|
||||
system_users = models.ManyToManyField(SystemUser, related_name='granted_by_permissions')
|
||||
|
@ -37,6 +38,33 @@ class AssetPermission(models.Model):
|
|||
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:
|
||||
db_table = 'asset_permission'
|
||||
|
||||
|
|
|
@ -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 %}
|
|
@ -43,10 +43,6 @@
|
|||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
|
|
|
@ -28,6 +28,16 @@
|
|||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<div class="tab-content">
|
||||
|
@ -43,10 +53,6 @@
|
|||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
|
@ -60,7 +66,8 @@
|
|||
<th>{% trans 'Name' %}</th>
|
||||
<th>{% trans 'Username' %}</th>
|
||||
<th>{% trans 'Email' %}</th>
|
||||
<th>{% trans 'Active' %}</th>
|
||||
<th>{% trans 'Is valid' %}</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
@ -77,6 +84,9 @@
|
|||
{% endif %}
|
||||
</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>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# ~*~ coding: utf-8 ~*~
|
||||
|
||||
from __future__ import unicode_literals, absolute_import
|
||||
import functools
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.conf import settings
|
||||
|
@ -11,6 +12,7 @@ from django.urls import reverse_lazy
|
|||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.views.generic.detail import DetailView, SingleObjectMixin
|
||||
|
||||
from common.utils import search_object_attr
|
||||
from .hands import AdminUserRequiredMixin, User, UserGroup, SystemUser
|
||||
from .models import AssetPermission
|
||||
from .forms import AssetPermissionForm
|
||||
|
@ -124,10 +126,19 @@ class AssetPermissionUserListView(AdminUserRequiredMixin, SingleObjectMixin, Lis
|
|||
|
||||
def get(self, request, *args, **kwargs):
|
||||
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)
|
||||
|
||||
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):
|
||||
context = {
|
||||
|
|
|
@ -34,10 +34,6 @@
|
|||
<i class="fa fa-wrench"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-user">
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
<li><a href="#"></a>
|
||||
</li>
|
||||
</ul>
|
||||
<a class="close-link">
|
||||
<i class="fa fa-times"></i>
|
||||
|
|
Loading…
Reference in New Issue