Commit 8355c1d3 by Kálmán Viktor

Merge branch 'master' into fix-graphs

Conflicts:
	circle/dashboard/views.py
parents 0892583d 0c2709fa
...@@ -149,8 +149,8 @@ class VmOperationViewTestCase(unittest.TestCase): ...@@ -149,8 +149,8 @@ class VmOperationViewTestCase(unittest.TestCase):
view = vm_ops['migrate'] view = vm_ops['migrate']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go, \
patch('dashboard.views.messages') as msg, \ patch('dashboard.views.util.messages') as msg, \
patch('dashboard.views.get_object_or_404') as go4: patch('dashboard.views.vm.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.migrate = Instance._ops['migrate'](inst) inst.migrate = Instance._ops['migrate'](inst)
...@@ -160,14 +160,15 @@ class VmOperationViewTestCase(unittest.TestCase): ...@@ -160,14 +160,15 @@ class VmOperationViewTestCase(unittest.TestCase):
go4.return_value = MagicMock() go4.return_value = MagicMock()
assert view.as_view()(request, pk=1234)['location'] assert view.as_view()(request, pk=1234)['location']
assert not msg.error.called assert not msg.error.called
assert go4.called
def test_migrate_failed(self): def test_migrate_failed(self):
request = FakeRequestFactory(POST={'node': 1}, superuser=True) request = FakeRequestFactory(POST={'node': 1}, superuser=True)
view = vm_ops['migrate'] view = vm_ops['migrate']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go, \
patch('dashboard.views.messages') as msg, \ patch('dashboard.views.util.messages') as msg, \
patch('dashboard.views.get_object_or_404') as go4: patch('dashboard.views.vm.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.migrate = Instance._ops['migrate'](inst) inst.migrate = Instance._ops['migrate'](inst)
...@@ -178,13 +179,14 @@ class VmOperationViewTestCase(unittest.TestCase): ...@@ -178,13 +179,14 @@ class VmOperationViewTestCase(unittest.TestCase):
go4.return_value = MagicMock() go4.return_value = MagicMock()
assert view.as_view()(request, pk=1234)['location'] assert view.as_view()(request, pk=1234)['location']
assert msg.error.called assert msg.error.called
assert go4.called
def test_migrate_wo_permission(self): def test_migrate_wo_permission(self):
request = FakeRequestFactory(POST={'node': 1}, superuser=False) request = FakeRequestFactory(POST={'node': 1}, superuser=False)
view = vm_ops['migrate'] view = vm_ops['migrate']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go, \
patch('dashboard.views.get_object_or_404') as go4: patch('dashboard.views.vm.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.migrate = Instance._ops['migrate'](inst) inst.migrate = Instance._ops['migrate'](inst)
...@@ -194,6 +196,7 @@ class VmOperationViewTestCase(unittest.TestCase): ...@@ -194,6 +196,7 @@ class VmOperationViewTestCase(unittest.TestCase):
go4.return_value = MagicMock() go4.return_value = MagicMock()
with self.assertRaises(PermissionDenied): with self.assertRaises(PermissionDenied):
assert view.as_view()(request, pk=1234)['location'] assert view.as_view()(request, pk=1234)['location']
assert go4.called
def test_migrate_template(self): def test_migrate_template(self):
"""check if GET dialog's template can be rendered""" """check if GET dialog's template can be rendered"""
...@@ -214,15 +217,13 @@ class VmOperationViewTestCase(unittest.TestCase): ...@@ -214,15 +217,13 @@ class VmOperationViewTestCase(unittest.TestCase):
view = vm_ops['save_as_template'] view = vm_ops['save_as_template']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go, \
patch('dashboard.views.messages') as msg, \ patch('dashboard.views.util.messages') as msg:
patch('dashboard.views.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.save_as_template = Instance._ops['save_as_template'](inst) inst.save_as_template = Instance._ops['save_as_template'](inst)
inst.save_as_template.async = MagicMock() inst.save_as_template.async = MagicMock()
inst.has_level.return_value = True inst.has_level.return_value = True
go.return_value = inst go.return_value = inst
go4.return_value = MagicMock()
assert view.as_view()(request, pk=1234) assert view.as_view()(request, pk=1234)
assert not msg.error.called assert not msg.error.called
...@@ -232,15 +233,13 @@ class VmOperationViewTestCase(unittest.TestCase): ...@@ -232,15 +233,13 @@ class VmOperationViewTestCase(unittest.TestCase):
view = vm_ops['save_as_template'] view = vm_ops['save_as_template']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go, \
patch('dashboard.views.messages') as msg, \ patch('dashboard.views.util.messages') as msg:
patch('dashboard.views.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.save_as_template = Instance._ops['save_as_template'](inst) inst.save_as_template = Instance._ops['save_as_template'](inst)
inst.save_as_template.async = MagicMock() inst.save_as_template.async = MagicMock()
inst.has_level.return_value = True inst.has_level.return_value = True
go.return_value = inst go.return_value = inst
go4.return_value = MagicMock()
assert view.as_view()(request, pk=1234)['location'] assert view.as_view()(request, pk=1234)['location']
assert not msg.error.called assert not msg.error.called
...@@ -306,25 +305,24 @@ class VmMassOperationViewTestCase(unittest.TestCase): ...@@ -306,25 +305,24 @@ class VmMassOperationViewTestCase(unittest.TestCase):
view = vm_mass_ops['migrate'] view = vm_mass_ops['migrate']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go, \
patch('dashboard.views.messages') as msg, \ patch('dashboard.views.util.messages') as msg, \
patch('dashboard.views.get_object_or_404') as go4: patch('dashboard.views.vm.messages') as msg2:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.migrate = Instance._ops['migrate'](inst) inst.migrate = Instance._ops['migrate'](inst)
inst.migrate.async = MagicMock() inst.migrate.async = MagicMock()
inst.has_level.return_value = True inst.has_level.return_value = True
go.return_value = [inst] go.return_value = [inst]
go4.return_value = MagicMock()
assert view.as_view()(request, pk=1234)['location'] assert view.as_view()(request, pk=1234)['location']
assert not msg.error.called assert not msg.error.called
assert not msg2.error.called
def test_migrate_failed(self): def test_migrate_failed(self):
request = FakeRequestFactory(POST={'node': 1}, superuser=True) request = FakeRequestFactory(POST={'node': 1}, superuser=True)
view = vm_mass_ops['migrate'] view = vm_mass_ops['migrate']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go, \
patch('dashboard.views.messages') as msg, \ patch('dashboard.views.vm.messages') as msg:
patch('dashboard.views.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.migrate = Instance._ops['migrate'](inst) inst.migrate = Instance._ops['migrate'](inst)
...@@ -332,7 +330,6 @@ class VmMassOperationViewTestCase(unittest.TestCase): ...@@ -332,7 +330,6 @@ class VmMassOperationViewTestCase(unittest.TestCase):
inst.migrate.async.side_effect = Exception inst.migrate.async.side_effect = Exception
inst.has_level.return_value = True inst.has_level.return_value = True
go.return_value = [inst] go.return_value = [inst]
go4.return_value = MagicMock()
assert view.as_view()(request, pk=1234)['location'] assert view.as_view()(request, pk=1234)['location']
assert msg.error.called assert msg.error.called
...@@ -340,15 +337,13 @@ class VmMassOperationViewTestCase(unittest.TestCase): ...@@ -340,15 +337,13 @@ class VmMassOperationViewTestCase(unittest.TestCase):
request = FakeRequestFactory(POST={'node': 1}, superuser=False) request = FakeRequestFactory(POST={'node': 1}, superuser=False)
view = vm_mass_ops['migrate'] view = vm_mass_ops['migrate']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go:
patch('dashboard.views.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.migrate = Instance._ops['migrate'](inst) inst.migrate = Instance._ops['migrate'](inst)
inst.migrate.async = MagicMock() inst.migrate.async = MagicMock()
inst.has_level.return_value = True inst.has_level.return_value = True
go.return_value = [inst] go.return_value = [inst]
go4.return_value = MagicMock()
with self.assertRaises(PermissionDenied): with self.assertRaises(PermissionDenied):
assert view.as_view()(request, pk=1234)['location'] assert view.as_view()(request, pk=1234)['location']
...@@ -388,15 +383,13 @@ class RenewViewTest(unittest.TestCase): ...@@ -388,15 +383,13 @@ class RenewViewTest(unittest.TestCase):
view = vm_ops['renew'] view = vm_ops['renew']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go, \
patch('dashboard.views.messages') as msg, \ patch('dashboard.views.util.messages') as msg:
patch('dashboard.views.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.renew = Instance._ops['renew'](inst) inst.renew = Instance._ops['renew'](inst)
inst.renew.async = MagicMock() inst.renew.async = MagicMock()
inst.has_level.return_value = True inst.has_level.return_value = True
go.return_value = inst go.return_value = inst
go4.return_value = MagicMock()
assert view.as_view()(request, pk=1234) assert view.as_view()(request, pk=1234)
assert not msg.error.called assert not msg.error.called
assert inst.renew.async.called_with(user=request.user, lease=None) assert inst.renew.async.called_with(user=request.user, lease=None)
...@@ -408,15 +401,13 @@ class RenewViewTest(unittest.TestCase): ...@@ -408,15 +401,13 @@ class RenewViewTest(unittest.TestCase):
view = vm_ops['renew'] view = vm_ops['renew']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go, \
patch('dashboard.views.messages') as msg, \ patch('dashboard.views.util.messages') as msg:
patch('dashboard.views.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.renew = Instance._ops['renew'](inst) inst.renew = Instance._ops['renew'](inst)
inst.renew.async = MagicMock() inst.renew.async = MagicMock()
inst.has_level.return_value = True inst.has_level.return_value = True
go.return_value = inst go.return_value = inst
go4.return_value = MagicMock()
assert view.as_view()(request, pk=1234) assert view.as_view()(request, pk=1234)
assert not msg.error.called assert not msg.error.called
...@@ -424,15 +415,13 @@ class RenewViewTest(unittest.TestCase): ...@@ -424,15 +415,13 @@ class RenewViewTest(unittest.TestCase):
request = FakeRequestFactory(authenticated=False) request = FakeRequestFactory(authenticated=False)
view = vm_ops['renew'] view = vm_ops['renew']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go:
patch('dashboard.views.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.renew = Instance._ops['renew'](inst) inst.renew = Instance._ops['renew'](inst)
inst.renew.async = MagicMock() inst.renew.async = MagicMock()
inst.has_level.return_value = False inst.has_level.return_value = False
go.return_value = inst go.return_value = inst
go4.return_value = MagicMock()
self.assertIn('login', self.assertIn('login',
view.as_view()(request, pk=1234)['location']) view.as_view()(request, pk=1234)['location'])
...@@ -440,15 +429,13 @@ class RenewViewTest(unittest.TestCase): ...@@ -440,15 +429,13 @@ class RenewViewTest(unittest.TestCase):
request = FakeRequestFactory(has_perms_mock=True) request = FakeRequestFactory(has_perms_mock=True)
view = vm_ops['renew'] view = vm_ops['renew']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go:
patch('dashboard.views.get_object_or_404') as go4:
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.renew = Instance._ops['renew'](inst) inst.renew = Instance._ops['renew'](inst)
inst.renew.async = MagicMock() inst.renew.async = MagicMock()
inst.has_level.return_value = False inst.has_level.return_value = False
go.return_value = inst go.return_value = inst
go4.return_value = MagicMock()
with self.assertRaises(PermissionDenied): with self.assertRaises(PermissionDenied):
assert view.as_view()(request, pk=1234) assert view.as_view()(request, pk=1234)
...@@ -456,15 +443,13 @@ class RenewViewTest(unittest.TestCase): ...@@ -456,15 +443,13 @@ class RenewViewTest(unittest.TestCase):
request = FakeRequestFactory(POST={'length': 1}, has_perms_mock=True) request = FakeRequestFactory(POST={'length': 1}, has_perms_mock=True)
view = vm_ops['renew'] view = vm_ops['renew']
with patch.object(view, 'get_object') as go, \ with patch.object(view, 'get_object') as go:
patch('dashboard.views.get_object_or_404') as go4:
inst = MagicMock(spec=Instance, pk=11) inst = MagicMock(spec=Instance, pk=11)
inst._meta.object_name = "Instance" inst._meta.object_name = "Instance"
inst.renew = Instance._ops['renew'](inst) inst.renew = Instance._ops['renew'](inst)
inst.renew.async = MagicMock() inst.renew.async = MagicMock()
inst.has_level.return_value = False inst.has_level.return_value = False
go.return_value = inst go.return_value = inst
go4.return_value = MagicMock()
with self.assertRaises(PermissionDenied): with self.assertRaises(PermissionDenied):
assert view.as_view()(request, pk=1234) assert view.as_view()(request, pk=1234)
...@@ -555,7 +540,7 @@ class AclUpdateViewTest(unittest.TestCase): ...@@ -555,7 +540,7 @@ class AclUpdateViewTest(unittest.TestCase):
inst.has_level.assert_called_with('dummy', v) inst.has_level.assert_called_with('dummy', v)
def test_set_level_mod_owner(self): def test_set_level_mod_owner(self):
with patch('dashboard.views.messages') as msg: with patch('dashboard.views.util.messages') as msg:
request = FakeRequestFactory(POST={}) request = FakeRequestFactory(POST={})
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
...@@ -581,7 +566,7 @@ class AclUpdateViewTest(unittest.TestCase): ...@@ -581,7 +566,7 @@ class AclUpdateViewTest(unittest.TestCase):
(None, 'user', ('user', 'operator'), False)) (None, 'user', ('user', 'operator'), False))
for old_level, new_level, allowed_levels, fail in data: for old_level, new_level, allowed_levels, fail in data:
with patch('dashboard.views.messages') as msg: with patch('dashboard.views.util.messages') as msg:
def has_level(user, level): def has_level(user, level):
return level in allowed_levels return level in allowed_levels
...@@ -606,7 +591,7 @@ class AclUpdateViewTest(unittest.TestCase): ...@@ -606,7 +591,7 @@ class AclUpdateViewTest(unittest.TestCase):
def test_readd(self): def test_readd(self):
request = FakeRequestFactory(POST={'name': 'user0', 'level': 'user'}) request = FakeRequestFactory(POST={'name': 'user0', 'level': 'user'})
with patch('dashboard.views.messages') as msg: with patch('dashboard.views.util.messages') as msg:
with patch.object(AclUpdateView, 'get_object') as go: with patch.object(AclUpdateView, 'get_object') as go:
view = AclUpdateView.as_view() view = AclUpdateView.as_view()
inst = MagicMock(spec=Instance) inst = MagicMock(spec=Instance)
......
...@@ -20,7 +20,6 @@ from django.conf.urls import patterns, url, include ...@@ -20,7 +20,6 @@ from django.conf.urls import patterns, url, include
import autocomplete_light import autocomplete_light
from vm.models import Instance from vm.models import Instance
from .graph import VmGraphView, NodeGraphView, NodeListGraphView
from .views import ( from .views import (
AclUpdateView, FavouriteView, GroupAclUpdateView, GroupDelete, AclUpdateView, FavouriteView, GroupAclUpdateView, GroupDelete,
GroupDetailView, GroupList, IndexView, GroupDetailView, GroupList, IndexView,
...@@ -47,6 +46,7 @@ from .views import ( ...@@ -47,6 +46,7 @@ from .views import (
GroupPermissionsView, GroupPermissionsView,
LeaseAclUpdateView, LeaseAclUpdateView,
ClientCheck, TokenLogin, ClientCheck, TokenLogin,
VmGraphView, NodeGraphView, NodeListGraphView,
) )
autocomplete_light.autodiscover() autocomplete_light.autodiscover()
......
This source diff could not be displayed because it is too large. You can view the blob instead.
# flake8: noqa
# from .node import Node
# __all__ = [ ]
from group import *
from index import *
from node import *
from store import *
from template import *
from user import *
from util import *
from vm import *
from graph import *
# Copyright 2014 Budapest University of Technology and Economics (BME IK)
#
# This file is part of CIRCLE Cloud.
#
# CIRCLE is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free
# Software Foundation, either version 3 of the License, or (at your option)
# any later version.
#
# CIRCLE is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along
# with CIRCLE. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals, absolute_import
import json
import logging
from itertools import chain
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.models import User, Group
from django.contrib.messages.views import SuccessMessageMixin
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse, reverse_lazy
from django.http import HttpResponse, Http404
from django.shortcuts import redirect
from django.utils.translation import ugettext as _
from django.views.generic import UpdateView, DeleteView, TemplateView
from braces.views import SuperuserRequiredMixin, LoginRequiredMixin
from django_tables2 import SingleTableView
from ..forms import (
AddGroupMemberForm, AclUserOrGroupAddForm, GroupPermissionForm,
GroupCreateForm, GroupProfileUpdateForm,
)
from ..models import FutureMember, GroupProfile
from ..tables import GroupListTable
from .util import CheckedDetailView, AclUpdateView, search_user, saml_available
logger = logging.getLogger(__name__)
class GroupCodeMixin(object):
@classmethod
def get_available_group_codes(cls, request):
newgroups = []
if saml_available:
from djangosaml2.cache import StateCache, IdentityCache
from djangosaml2.conf import get_config
from djangosaml2.views import _get_subject_id
from saml2.client import Saml2Client
state = StateCache(request.session)
conf = get_config(None, request)
client = Saml2Client(conf, state_cache=state,
identity_cache=IdentityCache(request.session),
logger=logger)
subject_id = _get_subject_id(request.session)
identity = client.users.get_identity(subject_id,
check_not_on_or_after=False)
if identity:
attributes = identity[0]
owneratrs = getattr(
settings, 'SAML_GROUP_OWNER_ATTRIBUTES', [])
for group in chain(*[attributes[i]
for i in owneratrs if i in attributes]):
try:
GroupProfile.search(group)
except Group.DoesNotExist:
newgroups.append(group)
return newgroups
class GroupDetailView(CheckedDetailView):
template_name = "dashboard/group-detail.html"
model = Group
read_level = 'operator'
def get_has_level(self):
return self.object.profile.has_level
def get_context_data(self, **kwargs):
context = super(GroupDetailView, self).get_context_data(**kwargs)
context['group'] = self.object
context['users'] = self.object.user_set.all()
context['future_users'] = FutureMember.objects.filter(
group=self.object)
context['acl'] = AclUpdateView.get_acl_data(
self.object.profile, self.request.user,
'dashboard.views.group-acl')
context['aclform'] = AclUserOrGroupAddForm()
context['addmemberform'] = AddGroupMemberForm()
context['group_profile_form'] = GroupProfileUpdate.get_form_object(
self.request, self.object.profile)
if self.request.user.is_superuser:
context['group_perm_form'] = GroupPermissionForm(
instance=self.object)
return context
def post(self, request, *args, **kwargs):
self.object = self.get_object()
if not self.get_has_level()(request.user, 'operator'):
raise PermissionDenied()
if request.POST.get('new_name'):
return self.__set_name(request)
if request.POST.get('new_member'):
return self.__add_user(request)
if request.POST.get('new_members'):
return self.__add_list(request)
return redirect(reverse_lazy("dashboard.views.group-detail",
kwargs={'pk': self.get_object().pk}))
def __add_user(self, request):
name = request.POST['new_member']
self.__add_username(request, name)
return redirect(reverse_lazy("dashboard.views.group-detail",
kwargs={'pk': self.object.pk}))
def __add_username(self, request, name):
if not name:
return
try:
entity = search_user(name)
self.object.user_set.add(entity)
except User.DoesNotExist:
if saml_available:
FutureMember.objects.get_or_create(org_id=name,
group=self.object)
else:
messages.warning(request, _('User "%s" not found.') % name)
def __add_list(self, request):
userlist = request.POST.get('new_members').split('\r\n')
for line in userlist:
self.__add_username(request, line)
return redirect(reverse_lazy("dashboard.views.group-detail",
kwargs={'pk': self.object.pk}))
def __set_name(self, request):
new_name = request.POST.get("new_name")
Group.objects.filter(pk=self.object.pk).update(
**{'name': new_name})
success_message = _("Group successfully renamed.")
if request.is_ajax():
response = {
'message': success_message,
'new_name': new_name,
'group_pk': self.object.pk
}
return HttpResponse(
json.dumps(response),
content_type="application/json"
)
else:
messages.success(request, success_message)
return redirect(reverse_lazy("dashboard.views.group-detail",
kwargs={'pk': self.object.pk}))
class GroupPermissionsView(SuperuserRequiredMixin, UpdateView):
model = Group
form_class = GroupPermissionForm
slug_field = "pk"
slug_url_kwarg = "group_pk"
def get_success_url(self):
return "%s#group-detail-permissions" % (
self.get_object().groupprofile.get_absolute_url())
class GroupAclUpdateView(AclUpdateView):
model = Group
def get_object(self):
return super(GroupAclUpdateView, self).get_object().profile
class GroupList(LoginRequiredMixin, SingleTableView):
template_name = "dashboard/group-list.html"
model = Group
table_class = GroupListTable
table_pagination = False
def get(self, *args, **kwargs):
if self.request.is_ajax():
groups = [{
'url': reverse("dashboard.views.group-detail",
kwargs={'pk': i.pk}),
'name': i.name} for i in self.get_queryset()]
return HttpResponse(
json.dumps(list(groups)),
content_type="application/json",
)
else:
return super(GroupList, self).get(*args, **kwargs)
def get_queryset(self):
logger.debug('GroupList.get_queryset() called. User: %s',
unicode(self.request.user))
profiles = GroupProfile.get_objects_with_level(
'operator', self.request.user)
groups = Group.objects.filter(groupprofile__in=profiles)
s = self.request.GET.get("s")
if s:
groups = groups.filter(name__icontains=s)
return groups
class GroupRemoveUserView(CheckedDetailView, DeleteView):
model = Group
slug_field = 'pk'
slug_url_kwarg = 'group_pk'
read_level = 'operator'
member_key = 'member_pk'
def get_has_level(self):
return self.object.profile.has_level
def get_context_data(self, **kwargs):
context = super(GroupRemoveUserView, self).get_context_data(**kwargs)
try:
context['member'] = User.objects.get(pk=self.member_pk)
except User.DoesNotExist:
raise Http404()
return context
def get_success_url(self):
next = self.request.POST.get('next')
if next:
return next
else:
return reverse_lazy("dashboard.views.group-detail",
kwargs={'pk': self.get_object().pk})
def get(self, request, member_pk, *args, **kwargs):
self.member_pk = member_pk
return super(GroupRemoveUserView, self).get(request, *args, **kwargs)
def get_template_names(self):
if self.request.is_ajax():
return ['dashboard/confirm/ajax-remove.html']
else:
return ['dashboard/confirm/base-remove.html']
def remove_member(self, pk):
container = self.get_object()
container.user_set.remove(User.objects.get(pk=pk))
def get_success_message(self):
return _("Member successfully removed from group.")
def delete(self, request, *args, **kwargs):
object = self.get_object()
if not object.profile.has_level(request.user, 'operator'):
raise PermissionDenied()
self.remove_member(kwargs[self.member_key])
success_url = self.get_success_url()
success_message = self.get_success_message()
if request.is_ajax():
return HttpResponse(
json.dumps({'message': success_message}),
content_type="application/json",
)
else:
messages.success(request, success_message)
return redirect(success_url)
class GroupRemoveFutureUserView(GroupRemoveUserView):
member_key = 'member_org_id'
def get(self, request, member_org_id, *args, **kwargs):
self.member_org_id = member_org_id
return super(GroupRemoveUserView, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(GroupRemoveUserView, self).get_context_data(**kwargs)
try:
context['member'] = FutureMember.objects.get(
org_id=self.member_org_id, group=self.get_object())
except FutureMember.DoesNotExist:
raise Http404()
return context
def remove_member(self, org_id):
FutureMember.objects.filter(org_id=org_id,
group=self.get_object()).delete()
def get_success_message(self):
return _("Future user successfully removed from group.")