@@ -83,7 +73,7 @@
-
+
|
{% endfor %}
@@ -108,7 +98,7 @@
|
@@ -143,16 +133,16 @@
-
+
|
{% for user_group in user_groups %}
- {{ user_group.name }} |
+ {{ user_group.name }} |
-
+
|
{% endfor %}
@@ -169,30 +159,118 @@
{% endblock %}
{% block custom_foot_js %}
-
+ .on('select2:unselect', function(evt) {
+ var data = evt.params.data;
+ delete jumpserver.users_selected[data.id]
+ });
+ $('.select2.user-group').select2()
+ .on('select2:select', function(evt) {
+ var data = evt.params.data;
+ jumpserver.groups_selected[data.id] = data.text;
+ })
+ .on('select2:unselect', function(evt) {
+ var data = evt.params.data;
+ delete jumpserver.groups_selected[data.id]
+ })
+}).on('click', '.btn-add-user', function () {
+ if (Object.keys(jumpserver.users_selected).length === 0) {
+ return false;
+ }
+ var users_id = [];
+ $.map(jumpserver.users_selected, function(value, index) {
+ users_id.push(index);
+ });
+ console.log(users_id);
+ addUsers(users_id);
+}).on('click', '.btn-remove-user', function () {
+ var user_id = $(this).data("gid");
+ if (user_id === "") {
+ return
+ }
+ var users = [user_id];
+ removeUser(users)
+}).on('click', '#btn-add-group', function () {
+ if (Object.keys(jumpserver.groups_selected).length === 0) {
+ return false;
+ }
+
+ var groups = $('.bdg_group').map(function() {
+ return $(this).data('gid');
+ }).get();
+
+ $.map(jumpserver.groups_selected, function(group_name, index) {
+ groups.push(index);
+ $('#opt_' + index).remove();
+ $('.group_edit tbody').append(
+ '
' +
+ '' + group_name + ' | ' +
+ ' | ' +
+ '
'
+ )
+ });
+
+ updateGroup(groups);
+}).on('click', '.btn-remove-group', function () {
+ var $this = $(this);
+ var $tr = $this.closest('tr');
+ var groups = $('.bdg_group').map(function() {
+ if ($(this).data('gid') !== $this.data('gid')){
+ return $(this).data('gid');
+ }
+ }).get();
+ updateGroup(groups);
+ $tr.remove()
+})
+
{% endblock %}
diff --git a/apps/perms/urls/api_urls.py b/apps/perms/urls/api_urls.py
index 2c5df54d4..f59bb178e 100644
--- a/apps/perms/urls/api_urls.py
+++ b/apps/perms/urls/api_urls.py
@@ -19,41 +19,22 @@ urlpatterns = [
url(r'^v1/user/my/asset-group/(?P
[0-9a-zA-Z\-]{36})/assets/$', api.MyAssetGroupOfAssetsApi.as_view(), name='my-asset-group-of-assets'),
# 查询某个用户授权的资产和资产组
- url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/assets/$',
- api.UserGrantedAssetsApi.as_view(),
- name='user-assets'),
- url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/asset-groups/$',
- api.UserGrantedAssetGroupsApi.as_view(),
- name='user-asset-groups'),
- url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/asset-groups-assets/$',
- api.UserGrantedAssetGroupsWithAssetsApi.as_view(),
- name='user-asset-groups'),
+ url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/assets/$', api.UserGrantedAssetsApi.as_view(), name='user-assets'),
+ url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/asset-groups/$', api.UserGrantedAssetGroupsApi.as_view(), name='user-asset-groups'),
+ url(r'^v1/user/(?P[0-9a-zA-Z\-]{36})/asset-groups-assets/$', api.UserGrantedAssetGroupsWithAssetsApi.as_view(), name='user-asset-groups'),
# 查询某个用户组授权的资产和资产组
- url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/assets/$',
- api.UserGroupGrantedAssetsApi.as_view(),
- name='user-group-assets'),
- url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/asset-groups/$',
- api.UserGroupGrantedAssetGroupsApi.as_view(),
- name='user-group-asset-groups'),
+ url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/assets/$', api.UserGroupGrantedAssetsApi.as_view(), name='user-group-assets'),
+ url(r'^v1/user-group/(?P[0-9a-zA-Z\-]{36})/asset-groups/$', api.UserGroupGrantedAssetGroupsApi.as_view(), name='user-group-asset-groups'),
- # 回收用户或用户组授权
- url(r'^v1/asset-permissions/user/revoke/$',
- api.RevokeUserAssetPermission.as_view(),
- name='revoke-user-asset-permission'),
- url(r'^v1/asset-permissions/user-group/revoke/$',
- api.RevokeUserGroupAssetPermission.as_view(),
- name='revoke-user-group-asset-permission'),
+ # 用户和资产授权变更
+ url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/user/remove/$', api.AssetPermissionRemoveUserApi.as_view(), name='asset-permission-remove-user'),
+ url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/user/add/$', api.AssetPermissionAddUserApi.as_view(), name='asset-permission-add-user'),
+ url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/asset/remove/$', api.AssetPermissionRemoveAssetApi.as_view(), name='asset-permission-remove-asset'),
+ url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/asset/add/$', api.AssetPermissionAddAssetApi.as_view(), name='asset-permission-add-asset'),
# 验证用户是否有某个资产和系统用户的权限
- url(r'v1/asset-permission/user/validate/$',
- api.ValidateUserAssetPermissionView.as_view(),
- name='validate-user-asset-permission'),
-
- # 删除asset permission中的某个系统用户
- url(r'^v1/asset-permissions/(?P[0-9a-zA-Z\-]{36})/system-user/remove/$',
- api.RemoveSystemUserAssetPermission.as_view(),
- name='remove-system-user-asset-permission'),
+ url(r'v1/asset-permission/user/validate/$', api.ValidateUserAssetPermissionView.as_view(), name='validate-user-asset-permission'),
]
urlpatterns += router.urls
diff --git a/apps/perms/utils.py b/apps/perms/utils.py
index edbbe6dc9..8f494f2f8 100644
--- a/apps/perms/utils.py
+++ b/apps/perms/utils.py
@@ -179,31 +179,3 @@ def push_system_user(assets, system_user):
system_user = system_user._to_secret_json()
task = push_users.delay(assets, system_user)
return task.id
-
-
-def associate_system_users_and_assets(system_users, assets, asset_groups, force=False):
- """关联系统用户和资产, 目的是保存它们的关系, 然后新加入的资产或系统
- 用户时,推送系统用户到资产
-
- Todo: 这里需要最终Api定下来更改一下, 现在策略是以系统用户为核心推送, 一个系统用户
- 推送一次
- """
- assets_all = set(assets)
-
- for asset_group in asset_groups:
- assets_all |= set(asset_group.assets.all())
-
- for system_user in system_users:
- assets_need_push = []
- if system_user.auto_push:
- if force:
- assets_need_push = assets_all
- else:
- assets_need_push.extend(
- [asset for asset in assets_all
- if asset not in system_user.assets.all()
- ]
- )
- system_user.assets.add(*(tuple(assets_all)))
- push_system_user(assets_need_push, system_user)
-
diff --git a/apps/perms/views.py b/apps/perms/views.py
index 3063488d2..9875b1366 100644
--- a/apps/perms/views.py
+++ b/apps/perms/views.py
@@ -2,24 +2,19 @@
from __future__ import unicode_literals, absolute_import
-import functools
-
from django.utils.translation import ugettext as _
-from django.db import transaction
from django.conf import settings
-from django.db.models import Q
from django.views.generic import ListView, CreateView, UpdateView
from django.views.generic.edit import DeleteView, FormView
from django.urls import reverse_lazy
from django.contrib.messages.views import SuccessMessageMixin
from django.views.generic.detail import DetailView, SingleObjectMixin
+from django.contrib import messages
-from common.utils import search_object_attr
from .hands import AdminUserRequiredMixin, User, UserGroup, SystemUser, \
Asset, AssetGroup
from .models import AssetPermission
from .forms import AssetPermissionForm
-# from .utils import associate_system_users_and_assets
class AssetPermissionListView(AdminUserRequiredMixin, ListView):
@@ -32,52 +27,34 @@ class AssetPermissionListView(AdminUserRequiredMixin, ListView):
context = {
'app': _('Perms'),
'action': _('Asset permission list'),
- 'keyword': self.keyword,
}
kwargs.update(context)
- return super(AssetPermissionListView, self).get_context_data(**kwargs)
-
- def get_queryset(self):
- self.queryset = super(AssetPermissionListView, self).get_queryset()
- self.keyword = keyword = self.request.GET.get('keyword', '')
- self.sort = sort = self.request.GET.get('sort', '-date_created')
-
- if keyword:
- self.queryset = self.queryset\
- .filter(Q(users__name__contains=keyword) |
- Q(users__username__contains=keyword) |
- Q(user_groups__name__contains=keyword) |
- Q(assets__ip__contains=keyword) |
- Q(assets__hostname__contains=keyword) |
- Q(system_users__username__icontains=keyword) |
- Q(system_users__name__icontains=keyword) |
- Q(asset_groups__name__icontains=keyword) |
- Q(comment__icontains=keyword) |
- Q(name__icontains=keyword)).distinct()
- if sort:
- self.queryset = self.queryset.order_by(sort)
- return self.queryset
+ return super().get_context_data(**kwargs)
-class AssetPermissionCreateView(AdminUserRequiredMixin,
- SuccessMessageMixin,
- CreateView):
- model = AssetPermission
- form_class = AssetPermissionForm
- template_name = 'perms/asset_permission_create_update.html'
- success_url = reverse_lazy('perms:asset-permission-list')
+class MessageMixin:
+ def form_valid(self, form):
+ response = super().form_valid(form)
+ errors = self.object.check_system_user_in_assets()
+ if errors:
+ message = self.get_warning_messages(errors)
+ messages.warning(self.request, message)
+ else:
+ message = self.get_success_message(form.cleaned_data)
+ messages.success(self.request, message)
- @transaction.atomic
- def post(self, request, *args, **kwargs):
- return super(AssetPermissionCreateView, self).post(request, *args, **kwargs)
+ success_message = self.get_success_message(form.cleaned_data)
+ if success_message:
+ messages.success(self.request, success_message)
+ return response
- def get_context_data(self, **kwargs):
- context = {
- 'app': _('Perms'),
- 'action': _('Create asset permission'),
- }
- kwargs.update(context)
- return super(AssetPermissionCreateView, self).get_context_data(**kwargs)
+ @staticmethod
+ def get_warning_messages(errors):
+ message = "System user should in behind clusters, so that " \
+ "system user auto push to cluster assets
"
+ for system_user, clusters in errors:
+ message += "{}: {} ".format(system_user.name, ", ".join(list(clusters)))
+ return message
def get_success_message(self, cleaned_data):
url = reverse_lazy('perms:asset-permission-detail',
@@ -87,24 +64,29 @@ class AssetPermissionCreateView(AdminUserRequiredMixin,
'successfully.'.format(url=url, name=self.object.name))
return success_message
- # Todo: When create push system user
- # def form_valid(self, form):
- # assets = form.cleaned_data['assets']
- # asset_groups = form.cleaned_data['asset_groups']
- # system_users = form.cleaned_data['system_users']
- # response = super(AssetPermissionCreateView, self).form_valid(form)
- # self.object.created_by = self.request.user.name
- # self.object.save()
- # return response
-
-class AssetPermissionUpdateView(AdminUserRequiredMixin, UpdateView):
+class AssetPermissionCreateView(AdminUserRequiredMixin,
+ MessageMixin,
+ CreateView):
+ model = AssetPermission
+ form_class = AssetPermissionForm
+ template_name = 'perms/asset_permission_create_update.html'
+ success_url = reverse_lazy('perms:asset-permission-list')
+ warning = None
+
+ def get_context_data(self, **kwargs):
+ context = {
+ 'app': _('Perms'),
+ 'action': _('Create asset permission'),
+ }
+ kwargs.update(context)
+ return super().get_context_data(**kwargs)
+
+
+class AssetPermissionUpdateView(AdminUserRequiredMixin, MessageMixin, UpdateView):
model = AssetPermission
form_class = AssetPermissionForm
template_name = 'perms/asset_permission_create_update.html'
- success_message = _(
- 'Update asset permission {name} successfully.'
- )
success_url = reverse_lazy("perms:asset-permission-list")
def get_context_data(self, **kwargs):
@@ -113,14 +95,7 @@ class AssetPermissionUpdateView(AdminUserRequiredMixin, UpdateView):
'action': _('Update asset permission')
}
kwargs.update(context)
- return super(AssetPermissionUpdateView, self).get_context_data(**kwargs)
-
- def get_success_message(self):
- url = reverse_lazy('perms:asset-permission-detail',
- kwargs={'pk': self.object.pk})
- return self.success_message.format(
- url=url, name=self.object.name
- )
+ return super().get_context_data(**kwargs)
class AssetPermissionDetailView(AdminUserRequiredMixin, DetailView):
@@ -138,7 +113,7 @@ class AssetPermissionDetailView(AdminUserRequiredMixin, DetailView):
'system_users': self.object.system_users.all(),
}
kwargs.update(context)
- return super(AssetPermissionDetailView, self).get_context_data(**kwargs)
+ return super().get_context_data(**kwargs)
class AssetPermissionDeleteView(AdminUserRequiredMixin, DeleteView):
@@ -153,40 +128,28 @@ class AssetPermissionUserView(AdminUserRequiredMixin,
template_name = 'perms/asset_permission_user.html'
context_object_name = 'asset_permission'
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
+ object = None
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=AssetPermission.objects.all())
- self.keyword = self.request.GET.get('keyword', '')
- return super(AssetPermissionUserView, self).get(request, *args, **kwargs)
+ return super().get(request, *args, **kwargs)
def get_queryset(self):
queryset = self.object.get_granted_users()
- if self.keyword:
- search_func = functools.partial(
- search_object_attr,
- value=self.keyword,
- attr_list=['username', 'name', 'email'],
- ignore_case=True)
- queryset = filter(search_func, queryset)
return queryset
def get_context_data(self, **kwargs):
users_granted = self.get_queryset()
- user_groups_granted = self.object.user_groups.all()
+ groups_granted = self.object.user_groups.all()
context = {
'app': _('Perms'),
'action': _('Asset permission user list'),
- 'users_remain': [
- user for user in User.objects.all()
- if user not in users_granted],
+ 'users_remain': User.objects.exclude(id__in=[user.id for user in users_granted]),
'user_groups': self.object.user_groups.all(),
- 'user_groups_remain': [
- user_group for user_group in UserGroup.objects.all()
- if user_group not in user_groups_granted],
- 'keyword': self.keyword,
+ 'user_groups_remain': UserGroup.objects.exclude(id__in=[group.id for group in groups_granted])
}
kwargs.update(context)
- return super(AssetPermissionUserView, self).get_context_data(**kwargs)
+ return super().get_context_data(**kwargs)
class AssetPermissionAssetView(AdminUserRequiredMixin,
@@ -195,37 +158,25 @@ class AssetPermissionAssetView(AdminUserRequiredMixin,
template_name = 'perms/asset_permission_asset.html'
context_object_name = 'asset_permission'
paginate_by = settings.CONFIG.DISPLAY_PER_PAGE
+ object = None
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=AssetPermission.objects.all())
- self.keyword = self.request.GET.get('keyword', '')
- return super(AssetPermissionAssetView, self)\
- .get(request, *args, **kwargs)
+ return super().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()
+ groups_granted = self.object.asset_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],
+ 'assets_remain': Asset.objects.exclude(id__in=[asset.id for asset 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,
+ 'asset_groups_remain': AssetGroup.objects.exclude(id__in=[group.id for group in groups_granted])
}
kwargs.update(context)
- return super(AssetPermissionAssetView, self).get_context_data(**kwargs)
+ return super().get_context_data(**kwargs)