Convert workflows document type selection, smart link document type selection, role members list, user group and group users views to CBV assign remove. Remove now obsolete assign remove function based view

This commit is contained in:
Roberto Rosario
2015-04-07 15:48:27 -04:00
parent 0476e66903
commit 69a7efd6f0
11 changed files with 257 additions and 289 deletions

View File

@@ -333,7 +333,7 @@ def multi_object_action_view(request):
class AssignRemoveView(TemplateView): class AssignRemoveView(TemplateView):
left_list_title = None left_list_title = None
right_list_title=None right_list_title = None
decode_content_type = False decode_content_type = False
extra_context = None extra_context = None
grouped = False grouped = False
@@ -374,7 +374,7 @@ class AssignRemoveView(TemplateView):
for selection in self.unselected_list.cleaned_data['selection']: for selection in self.unselected_list.cleaned_data['selection']:
if self.grouped: if self.grouped:
flat_list = [] flat_list = []
for group in left_list(): for group in self.left_list():
flat_list.extend(group[1]) flat_list.extend(group[1])
else: else:
flat_list = self.left_list() flat_list = self.left_list()
@@ -451,97 +451,6 @@ class AssignRemoveView(TemplateView):
return data return data
def assign_remove(request, left_list, right_list, add_method, remove_method, left_list_title=None, right_list_title=None, decode_content_type=False, extra_context=None, grouped=False):
left_list_name = 'left_list'
right_list_name = 'right_list'
if request.method == 'POST':
if '%s-submit' % left_list_name in request.POST.keys():
unselected_list = ChoiceForm(request.POST,
prefix=left_list_name,
choices=left_list())
if unselected_list.is_valid():
for selection in unselected_list.cleaned_data['selection']:
if grouped:
flat_list = []
for group in left_list():
flat_list.extend(group[1])
else:
flat_list = left_list()
label = dict(flat_list)[selection]
if decode_content_type:
selection_obj = get_obj_from_content_type_string(selection)
else:
selection_obj = selection
try:
add_method(selection_obj)
except:
if settings.DEBUG:
raise
else:
messages.error(request, _('Unable to remove %(selection)s.') % {
'selection': label, 'right_list_title': right_list_title})
elif '%s-submit' % right_list_name in request.POST.keys():
selected_list = ChoiceForm(request.POST,
prefix=right_list_name,
choices=right_list())
if selected_list.is_valid():
for selection in selected_list.cleaned_data['selection']:
if grouped:
flat_list = []
for group in right_list():
flat_list.extend(group[1])
else:
flat_list = right_list()
label = dict(flat_list)[selection]
if decode_content_type:
selection = get_obj_from_content_type_string(selection)
try:
remove_method(selection)
except:
if settings.DEBUG:
raise
else:
messages.error(request, _('Unable to add %(selection)s.') % {
'selection': label, 'right_list_title': right_list_title})
unselected_list = ChoiceForm(prefix=left_list_name, choices=left_list())
selected_list = ChoiceForm(prefix=right_list_name, choices=right_list())
context = {
'subtemplates_list': [
{
'name': 'appearance/generic_form_subtemplate.html',
'column_class': 'col-xs-12 col-sm-6 col-md-6 col-lg-6',
'context': {
'form': unselected_list,
'title': left_list_title or ' ',
'submit_label': _('Add'),
'submit_icon': 'fa fa-plus'
}
},
{
'name': 'appearance/generic_form_subtemplate.html',
'column_class': 'col-xs-12 col-sm-6 col-md-6 col-lg-6',
'context': {
'form': selected_list,
'title': right_list_title or ' ',
'submit_label': _('Remove'),
'submit_icon': 'fa fa-minus'
}
},
],
}
if extra_context:
context.update(extra_context)
return render_to_response('appearance/generic_form.html', context,
context_instance=RequestContext(request))
def current_user_edit(request): def current_user_edit(request):
""" """
Allow an user to edit his own details Allow an user to edit his own details

View File

@@ -3,7 +3,8 @@ from __future__ import unicode_literals
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from .views import ( from .views import (
SetupWorkflowCreateView, SetupWorkflowDeleteView, SetupWorkflowEditView, SetupWorkflowCreateView, SetupWorkflowDeleteView,
SetupWorkflowDocumentTypesView, SetupWorkflowEditView,
SetupWorkflowListView, SetupWorkflowStateCreateView, SetupWorkflowListView, SetupWorkflowStateCreateView,
SetupWorkflowStateDeleteView, SetupWorkflowStateEditView, SetupWorkflowStateDeleteView, SetupWorkflowStateEditView,
SetupWorkflowStateListView, SetupWorkflowTransitionListView, SetupWorkflowStateListView, SetupWorkflowTransitionListView,
@@ -13,26 +14,20 @@ from .views import (
) )
urlpatterns = patterns('', urlpatterns = patterns('',
url(r'^document/(?P<pk>\d+)/workflows/$', DocumentWorkflowInstanceListView.as_view(), name='document_workflow_instance_list'),
url(r'^document/workflows/(?P<pk>\d+)/$', WorkflowInstanceDetailView.as_view(), name='workflow_instance_detail'),
url(r'^document/workflows/(?P<pk>\d+)/transition/$', WorkflowInstanceTransitionView.as_view(), name='workflow_instance_transition'),
url(r'^setup/all/$', SetupWorkflowListView.as_view(), name='setup_workflow_list'), url(r'^setup/all/$', SetupWorkflowListView.as_view(), name='setup_workflow_list'),
url(r'^setup/create/$', SetupWorkflowCreateView.as_view(), name='setup_workflow_create'), url(r'^setup/create/$', SetupWorkflowCreateView.as_view(), name='setup_workflow_create'),
url(r'^setup/(?P<pk>\d+)/edit/$', SetupWorkflowEditView.as_view(), name='setup_workflow_edit'), url(r'^setup/(?P<pk>\d+)/edit/$', SetupWorkflowEditView.as_view(), name='setup_workflow_edit'),
url(r'^setup/(?P<pk>\d+)/delete/$', SetupWorkflowDeleteView.as_view(), name='setup_workflow_delete'), url(r'^setup/(?P<pk>\d+)/delete/$', SetupWorkflowDeleteView.as_view(), name='setup_workflow_delete'),
url(r'^setup/(?P<pk>\d+)/document_types/$', SetupWorkflowDocumentTypesView.as_view(), name='setup_workflow_document_types'),
url(r'^setup/(?P<pk>\d+)/states/$', SetupWorkflowStateListView.as_view(), name='setup_workflow_states'), url(r'^setup/(?P<pk>\d+)/states/$', SetupWorkflowStateListView.as_view(), name='setup_workflow_states'),
url(r'^setup/(?P<pk>\d+)/states/create/$', SetupWorkflowStateCreateView.as_view(), name='setup_workflow_state_create'), url(r'^setup/(?P<pk>\d+)/states/create/$', SetupWorkflowStateCreateView.as_view(), name='setup_workflow_state_create'),
url(r'^setup/workflow/state/(?P<pk>\d+)/delete/$', SetupWorkflowStateDeleteView.as_view(), name='setup_workflow_state_delete'),
url(r'^setup/workflow/state/(?P<pk>\d+)/edit/$', SetupWorkflowStateEditView.as_view(), name='setup_workflow_state_edit'),
url(r'^setup/(?P<pk>\d+)/transitions/$', SetupWorkflowTransitionListView.as_view(), name='setup_workflow_transitions'), url(r'^setup/(?P<pk>\d+)/transitions/$', SetupWorkflowTransitionListView.as_view(), name='setup_workflow_transitions'),
url(r'^setup/(?P<pk>\d+)/transitions/create/$', SetupWorkflowTransitionCreateView.as_view(), name='setup_workflow_transition_create'), url(r'^setup/(?P<pk>\d+)/transitions/create/$', SetupWorkflowTransitionCreateView.as_view(), name='setup_workflow_transition_create'),
url(r'^setup/workflow/state/(?P<pk>\d+)/delete/$', SetupWorkflowStateDeleteView.as_view(), name='setup_workflow_state_delete'),
url(r'^setup/workflow/state/(?P<pk>\d+)/edit/$', SetupWorkflowStateEditView.as_view(), name='setup_workflow_state_edit'),
url(r'^setup/workflow/transitions/(?P<pk>\d+)/delete/$', SetupWorkflowTransitionDeleteView.as_view(), name='setup_workflow_transition_delete'), url(r'^setup/workflow/transitions/(?P<pk>\d+)/delete/$', SetupWorkflowTransitionDeleteView.as_view(), name='setup_workflow_transition_delete'),
url(r'^setup/workflow/transitions/(?P<pk>\d+)/edit/$', SetupWorkflowTransitionEditView.as_view(), name='setup_workflow_transition_edit'), url(r'^setup/workflow/transitions/(?P<pk>\d+)/edit/$', SetupWorkflowTransitionEditView.as_view(), name='setup_workflow_transition_edit'),
url(r'^document/(?P<pk>\d+)/workflows/$', DocumentWorkflowInstanceListView.as_view(), name='document_workflow_instance_list'),
url(r'^document/workflows/(?P<pk>\d+)/$', WorkflowInstanceDetailView.as_view(), name='workflow_instance_detail'),
url(r'^document/workflows/(?P<pk>\d+)/transition/$', WorkflowInstanceTransitionView.as_view(), name='workflow_instance_transition'),
)
urlpatterns += patterns('document_states.views',
url(r'^setup/(?P<pk>\d+)/document_types/$', 'setup_workflow_document_types', name='setup_workflow_document_types'),
) )

View File

@@ -12,8 +12,8 @@ from django.views.generic import FormView
from acls.models import AccessEntry from acls.models import AccessEntry
from common.utils import generate_choices_w_labels from common.utils import generate_choices_w_labels
from common.views import ( from common.views import (
SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView, AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
SingleObjectListView, assign_remove SingleObjectEditView, SingleObjectListView
) )
from documents.models import Document from documents.models import Document
from permissions.models import Permission from permissions.models import Permission
@@ -188,7 +188,40 @@ class SetupWorkflowDeleteView(SingleObjectDeleteView):
success_url = reverse_lazy('document_states:setup_workflow_list') success_url = reverse_lazy('document_states:setup_workflow_list')
# States class SetupWorkflowDocumentTypesView(AssignRemoveView):
decode_content_type = True
def add(self, item):
self.workflow.document_types.add(item)
def dispatch(self, request, *args, **kwargs):
self.workflow = get_object_or_404(Workflow, pk=self.kwargs['pk'])
try:
Permission.objects.check_permissions(self.request.user, [PERMISSION_WORKFLOW_EDIT])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_WORKFLOW_EDIT, self.request.user,self.workflow)
return super(SetupWorkflowDocumentTypesView, self).dispatch(request, *args, **kwargs)
def left_list(self):
return generate_choices_w_labels(self.workflow.get_document_types_not_in_workflow(), display_object_type=False)
def right_list(self):
return generate_choices_w_labels(self.workflow.document_types.all(), display_object_type=False)
def remove(self, item):
self.workflow.document_types.remove(item)
def get_context_data(self, **kwargs):
data = super(SetupWorkflowDocumentTypesView, self).get_context_data(**kwargs)
data.update({
'main_title': _('Document types assigned the workflow: %s') % self.workflow,
'object': self.workflow,
})
return data
class SetupWorkflowStateListView(SingleObjectListView): class SetupWorkflowStateListView(SingleObjectListView):
def dispatch(self, request, *args, **kwargs): def dispatch(self, request, *args, **kwargs):
@@ -422,25 +455,3 @@ class SetupWorkflowTransitionEditView(SingleObjectEditView):
def get_success_url(self): def get_success_url(self):
return reverse('document_states:setup_workflow_transitions', args=[self.get_object().workflow.pk]) return reverse('document_states:setup_workflow_transitions', args=[self.get_object().workflow.pk])
def setup_workflow_document_types(request, pk):
workflow = get_object_or_404(Workflow, pk=pk)
try:
Permission.objects.check_permissions(request.user, [PERMISSION_WORKFLOW_EDIT])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_WORKFLOW_EDIT, request.user, workflow)
return assign_remove(
request,
left_list=lambda: generate_choices_w_labels(workflow.get_document_types_not_in_workflow(), display_object_type=False),
right_list=lambda: generate_choices_w_labels(workflow.document_types.all(), display_object_type=False),
add_method=lambda x: workflow.document_types.add(x),
remove_method=lambda x: workflow.document_types.remove(x),
decode_content_type=True,
extra_context={
'main_title': _('Document types assigned the workflow: %s') % workflow,
'object': workflow,
}
)

View File

@@ -2,6 +2,8 @@ from __future__ import unicode_literals
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from .views import SetupSmartLinkDocumentTypesView
urlpatterns = patterns('linking.views', urlpatterns = patterns('linking.views',
url(r'^document/(?P<document_id>\d+)/$', 'smart_link_instances_for_document', (), 'smart_link_instances_for_document'), url(r'^document/(?P<document_id>\d+)/$', 'smart_link_instances_for_document', (), 'smart_link_instances_for_document'),
url(r'^document/(?P<document_id>\d+)/smart_link/(?P<smart_link_pk>\d+)/$', 'smart_link_instance_view', (), 'smart_link_instance_view'), url(r'^document/(?P<document_id>\d+)/smart_link/(?P<smart_link_pk>\d+)/$', 'smart_link_instance_view', (), 'smart_link_instance_view'),
@@ -10,7 +12,7 @@ urlpatterns = patterns('linking.views',
url(r'^setup/create/$', 'smart_link_create', (), 'smart_link_create'), url(r'^setup/create/$', 'smart_link_create', (), 'smart_link_create'),
url(r'^setup/(?P<smart_link_pk>\d+)/delete/$', 'smart_link_delete', (), 'smart_link_delete'), url(r'^setup/(?P<smart_link_pk>\d+)/delete/$', 'smart_link_delete', (), 'smart_link_delete'),
url(r'^setup/(?P<smart_link_pk>\d+)/edit/$', 'smart_link_edit', (), 'smart_link_edit'), url(r'^setup/(?P<smart_link_pk>\d+)/edit/$', 'smart_link_edit', (), 'smart_link_edit'),
url(r'^setup/(?P<smart_link_pk>\d+)/document_types/$', 'smart_link_document_types', (), 'smart_link_document_types'), url(r'^setup/(?P<smart_link_pk>\d+)/document_types/$', SetupSmartLinkDocumentTypesView.as_view(), name='smart_link_document_types'),
url(r'^setup/(?P<smart_link_pk>\d+)/condition/list/$', 'smart_link_condition_list', (), 'smart_link_condition_list'), url(r'^setup/(?P<smart_link_pk>\d+)/condition/list/$', 'smart_link_condition_list', (), 'smart_link_condition_list'),
url(r'^setup/(?P<smart_link_pk>\d+)/condition/create/$', 'smart_link_condition_create', (), 'smart_link_condition_create'), url(r'^setup/(?P<smart_link_pk>\d+)/condition/create/$', 'smart_link_condition_create', (), 'smart_link_condition_create'),

View File

@@ -15,7 +15,7 @@ from acls.models import AccessEntry
from acls.utils import apply_default_acls from acls.utils import apply_default_acls
from acls.views import acl_list_for from acls.views import acl_list_for
from common.utils import encapsulate, generate_choices_w_labels from common.utils import encapsulate, generate_choices_w_labels
from common.views import assign_remove from common.views import AssignRemoveView
from common.widgets import two_state_template from common.widgets import two_state_template
from documents.models import Document, DocumentType from documents.models import Document, DocumentType
from documents.views import document_list from documents.views import document_list
@@ -31,6 +31,41 @@ from .permissions import (
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class SetupSmartLinkDocumentTypesView(AssignRemoveView):
decode_content_type = True
def add(self, item):
self.smart_link.document_types.add(item)
def dispatch(self, request, *args, **kwargs):
self.smart_link = get_object_or_404(SmartLink, pk=self.kwargs['smart_link_pk'])
try:
Permission.objects.check_permissions(self.request.user, [PERMISSION_SMART_LINK_EDIT])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_SMART_LINK_EDIT, self.request.user, self.smart_link)
return super(SetupSmartLinkDocumentTypesView, self).dispatch(request, *args, **kwargs)
def left_list(self):
return generate_choices_w_labels(DocumentType.objects.exclude(pk__in=self.smart_link.document_types.all()), display_object_type=False)
def right_list(self):
return generate_choices_w_labels(self.smart_link.document_types.all(), display_object_type=False)
def remove(self, item):
self.smart_link.document_types.remove(item)
def get_context_data(self, **kwargs):
data = super(SetupSmartLinkDocumentTypesView, self).get_context_data(**kwargs)
data.update({
'main_title': _('Document type for which to enable smart link: %s') % self.smart_link,
'object': self.smart_link,
})
return data
def smart_link_instance_view(request, document_id, smart_link_pk): def smart_link_instance_view(request, document_id, smart_link_pk):
document = get_object_or_404(Document, pk=document_id) document = get_object_or_404(Document, pk=document_id)
smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) smart_link = get_object_or_404(SmartLink, pk=smart_link_pk)
@@ -196,28 +231,6 @@ def smart_link_delete(request, smart_link_pk):
}, context_instance=RequestContext(request)) }, context_instance=RequestContext(request))
def smart_link_document_types(request, smart_link_pk):
smart_link = get_object_or_404(SmartLink, pk=smart_link_pk)
try:
Permission.objects.check_permissions(request.user, [PERMISSION_SMART_LINK_EDIT])
except PermissionDenied:
AccessEntry.objects.check_access(PERMISSION_SMART_LINK_EDIT, request.user, smart_link)
return assign_remove(
request,
left_list=lambda: generate_choices_w_labels(DocumentType.objects.exclude(pk__in=smart_link.document_types.all()), display_object_type=False),
right_list=lambda: generate_choices_w_labels(smart_link.document_types.all(), display_object_type=False),
add_method=lambda x: smart_link.document_types.add(x),
remove_method=lambda x: smart_link.document_types.remove(x),
decode_content_type=True,
extra_context={
'main_title': _('Document type for which to enable smart link: %s') % smart_link,
'object': smart_link,
}
)
def smart_link_condition_list(request, smart_link_pk): def smart_link_condition_list(request, smart_link_pk):
smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) smart_link = get_object_or_404(SmartLink, pk=smart_link_pk)

View File

@@ -0,0 +1,7 @@
from __future__ import unicode_literals
from acls.classes import EncapsulatedObject
class Member(EncapsulatedObject):
source_object_name = 'member_object'

View File

@@ -3,7 +3,9 @@ from __future__ import unicode_literals
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from .api_views import APIRoleListView, APIRoleView from .api_views import APIRoleListView, APIRoleView
from .views import RoleCreateView, RoleDeleteView, RoleEditView from .views import (
RoleCreateView, RoleDeleteView, RoleEditView, SetupRoleMembersView
)
urlpatterns = patterns('permissions.views', urlpatterns = patterns('permissions.views',
url(r'^role/list/$', 'role_list', (), 'role_list'), url(r'^role/list/$', 'role_list', (), 'role_list'),
@@ -11,7 +13,7 @@ urlpatterns = patterns('permissions.views',
url(r'^role/(?P<role_id>\d+)/permissions/$', 'role_permissions', (), 'role_permissions'), url(r'^role/(?P<role_id>\d+)/permissions/$', 'role_permissions', (), 'role_permissions'),
url(r'^role/(?P<pk>\d+)/edit/$', RoleEditView.as_view(), name='role_edit'), url(r'^role/(?P<pk>\d+)/edit/$', RoleEditView.as_view(), name='role_edit'),
url(r'^role/(?P<pk>\d+)/delete/$', RoleDeleteView.as_view(), name='role_delete'), url(r'^role/(?P<pk>\d+)/delete/$', RoleDeleteView.as_view(), name='role_delete'),
url(r'^role/(?P<role_id>\d+)/members/$', 'role_members', (), 'role_members'), url(r'^role/(?P<role_id>\d+)/members/$', SetupRoleMembersView.as_view(), name='role_members'),
url(r'^permissions/multiple/grant/$', 'permission_grant', (), 'permission_multiple_grant'), url(r'^permissions/multiple/grant/$', 'permission_grant', (), 'permission_multiple_grant'),
url(r'^permissions/multiple/revoke/$', 'permission_revoke', (), 'permission_multiple_revoke'), url(r'^permissions/multiple/revoke/$', 'permission_revoke', (), 'permission_multiple_revoke'),

View File

@@ -0,0 +1,64 @@
from __future__ import unicode_literals
from django.contrib.auth.models import Group, User
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import ugettext_lazy as _
from common.models import AnonymousUserSingleton
from common.utils import get_object_name
from .classes import Member
def _as_choice_list(items):
return sorted([(Member.encapsulate(item).gid, get_object_name(item, display_object_type=False)) for item in items], key=lambda x: x[1])
def get_role_members(role, separate=False):
user_ct = ContentType.objects.get(model='user')
group_ct = ContentType.objects.get(model='group')
anonymous = ContentType.objects.get(model='anonymoususersingleton')
users = role.members(filter_dict={'member_type': user_ct})
groups = role.members(filter_dict={'member_type': group_ct})
anonymous = role.members(filter_dict={'member_type': anonymous})
if separate:
return users, groups, anonymous
else:
members = []
if users:
members.append((_('Users'), _as_choice_list(list(users))))
if groups:
members.append((_('Groups'), _as_choice_list(list(groups))))
if anonymous:
members.append((_('Special'), _as_choice_list(list(anonymous))))
return members
def get_non_role_members(role):
# non members = all users - members - staff - super users
member_users, member_groups, member_anonymous = get_role_members(role, separate=True)
staff_users = User.objects.filter(is_staff=True)
super_users = User.objects.filter(is_superuser=True)
users = set(User.objects.all()) - set(member_users) - set(staff_users) - set(super_users)
groups = set(Group.objects.all()) - set(member_groups)
anonymous = set([AnonymousUserSingleton.objects.get()]) - set(member_anonymous)
non_members = []
if users:
non_members.append((_('Users'), _as_choice_list(list(users))))
if groups:
non_members.append((_('Groups'), _as_choice_list(list(groups))))
if anonymous:
non_members.append((_('Special'), _as_choice_list(list(anonymous))))
return non_members

View File

@@ -5,7 +5,6 @@ from json import loads
import operator import operator
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.models import Group, User
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.urlresolvers import reverse_lazy from django.core.urlresolvers import reverse_lazy
@@ -15,15 +14,14 @@ from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext from django.template import RequestContext
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from acls.classes import EncapsulatedObject
from common.models import AnonymousUserSingleton
from common.views import ( from common.views import (
SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView, AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView,
assign_remove SingleObjectEditView
) )
from common.utils import encapsulate, get_object_name from common.utils import encapsulate
from common.widgets import two_state_template from common.widgets import two_state_template
from .classes import Member
from .forms import RoleForm, RoleForm_view from .forms import RoleForm, RoleForm_view
from .models import Permission, Role from .models import Permission, Role
from .permissions import ( from .permissions import (
@@ -31,6 +29,7 @@ from .permissions import (
PERMISSION_ROLE_VIEW, PERMISSION_ROLE_CREATE, PERMISSION_ROLE_DELETE, PERMISSION_ROLE_VIEW, PERMISSION_ROLE_CREATE, PERMISSION_ROLE_DELETE,
PERMISSION_ROLE_EDIT PERMISSION_ROLE_EDIT
) )
from .utils import get_non_role_members, get_role_members
class RoleCreateView(SingleObjectCreateView): class RoleCreateView(SingleObjectCreateView):
@@ -51,6 +50,40 @@ class RoleEditView(SingleObjectEditView):
view_permission = PERMISSION_ROLE_EDIT view_permission = PERMISSION_ROLE_EDIT
class SetupRoleMembersView(AssignRemoveView):
grouped = True
def add(self, item):
member = Member.get(item).source_object
self.role.add_member(member)
def dispatch(self, request, *args, **kwargs):
Permission.objects.check_permissions(request.user, [PERMISSION_ROLE_EDIT])
self.role = get_object_or_404(Role, pk=self.kwargs['role_id'])
self.left_list_title = _('Non members of role: %s') % self.role
self.right_list_title = _('Members of role: %s') % self.role
return super(SetupRoleMembersView, self).dispatch(request, *args, **kwargs)
def left_list(self):
return get_non_role_members(self.role)
def right_list(self):
return get_role_members(self.role)
def remove(self, item):
member = Member.get(item).source_object
self.role.remove_member(member)
def get_context_data(self, **kwargs):
data = super(SetupRoleMembersView, self).get_context_data(**kwargs)
data.update({
'object': self.role,
})
return data
def role_list(request): def role_list(request):
Permission.objects.check_permissions(request.user, [PERMISSION_ROLE_VIEW]) Permission.objects.check_permissions(request.user, [PERMISSION_ROLE_VIEW])
@@ -221,90 +254,3 @@ def permission_revoke(request):
return render_to_response('appearance/generic_confirm.html', context, return render_to_response('appearance/generic_confirm.html', context,
context_instance=RequestContext(request)) context_instance=RequestContext(request))
class Member(EncapsulatedObject):
source_object_name = 'member_object'
def _as_choice_list(items):
return sorted([(Member.encapsulate(item).gid, get_object_name(item, display_object_type=False)) for item in items], key=lambda x: x[1])
def get_role_members(role, separate=False):
user_ct = ContentType.objects.get(model='user')
group_ct = ContentType.objects.get(model='group')
anonymous = ContentType.objects.get(model='anonymoususersingleton')
users = role.members(filter_dict={'member_type': user_ct})
groups = role.members(filter_dict={'member_type': group_ct})
anonymous = role.members(filter_dict={'member_type': anonymous})
if separate:
return users, groups, anonymous
else:
members = []
if users:
members.append((_('Users'), _as_choice_list(list(users))))
if groups:
members.append((_('Groups'), _as_choice_list(list(groups))))
if anonymous:
members.append((_('Special'), _as_choice_list(list(anonymous))))
return members
def get_non_role_members(role):
# non members = all users - members - staff - super users
member_users, member_groups, member_anonymous = get_role_members(role, separate=True)
staff_users = User.objects.filter(is_staff=True)
super_users = User.objects.filter(is_superuser=True)
users = set(User.objects.all()) - set(member_users) - set(staff_users) - set(super_users)
groups = set(Group.objects.all()) - set(member_groups)
anonymous = set([AnonymousUserSingleton.objects.get()]) - set(member_anonymous)
non_members = []
if users:
non_members.append((_('Users'), _as_choice_list(list(users))))
if groups:
non_members.append((_('Groups'), _as_choice_list(list(groups))))
if anonymous:
non_members.append((_('Special'), _as_choice_list(list(anonymous))))
return non_members
def add_role_member(role, selection):
member = Member.get(selection).source_object
role.add_member(member)
def remove_role_member(role, selection):
member = Member.get(selection).source_object
role.remove_member(member)
def role_members(request, role_id):
Permission.objects.check_permissions(request.user, [PERMISSION_ROLE_EDIT])
role = get_object_or_404(Role, pk=role_id)
return assign_remove(
request,
left_list=lambda: get_non_role_members(role),
right_list=lambda: get_role_members(role),
add_method=lambda x: add_role_member(role, x),
remove_method=lambda x: remove_role_member(role, x),
left_list_title=_('Non members of role: %s') % role,
right_list_title=_('Members of role: %s') % role,
extra_context={
'object': role,
},
grouped=True,
)

View File

@@ -6,6 +6,7 @@ from .api_views import (
APICurrentUserView, APIGroupListView, APIGroupView, APIUserListView, APICurrentUserView, APIGroupListView, APIGroupView, APIUserListView,
APIUserView APIUserView
) )
from .views import GroupMembersView, UserGroupsView
urlpatterns = patterns('user_management.views', urlpatterns = patterns('user_management.views',
url(r'^user/list/$', 'user_list', (), 'user_list'), url(r'^user/list/$', 'user_list', (), 'user_list'),
@@ -15,14 +16,14 @@ urlpatterns = patterns('user_management.views',
url(r'^user/multiple/delete/$', 'user_multiple_delete', (), 'user_multiple_delete'), url(r'^user/multiple/delete/$', 'user_multiple_delete', (), 'user_multiple_delete'),
url(r'^user/(?P<user_id>\d+)/set_password/$', 'user_set_password', (), 'user_set_password'), url(r'^user/(?P<user_id>\d+)/set_password/$', 'user_set_password', (), 'user_set_password'),
url(r'^user/multiple/set_password/$', 'user_multiple_set_password', (), 'user_multiple_set_password'), url(r'^user/multiple/set_password/$', 'user_multiple_set_password', (), 'user_multiple_set_password'),
url(r'^user/(?P<user_id>\d+)/groups/$', 'user_groups', (), 'user_groups'), url(r'^user/(?P<user_id>\d+)/groups/$', UserGroupsView.as_view(), name='user_groups'),
url(r'^group/list/$', 'group_list', (), 'group_list'), url(r'^group/list/$', 'group_list', (), 'group_list'),
url(r'^group/add/$', 'group_add', (), 'group_add'), url(r'^group/add/$', 'group_add', (), 'group_add'),
url(r'^group/(?P<group_id>\d+)/edit/$', 'group_edit', (), 'group_edit'), url(r'^group/(?P<group_id>\d+)/edit/$', 'group_edit', (), 'group_edit'),
url(r'^group/(?P<group_id>\d+)/delete/$', 'group_delete', (), 'group_delete'), url(r'^group/(?P<group_id>\d+)/delete/$', 'group_delete', (), 'group_delete'),
url(r'^group/multiple/delete/$', 'group_multiple_delete', (), 'group_multiple_delete'), url(r'^group/multiple/delete/$', 'group_multiple_delete', (), 'group_multiple_delete'),
url(r'^group/(?P<group_id>\d+)/members/$', 'group_members', (), 'group_members'), url(r'^group/(?P<group_id>\d+)/members/$', GroupMembersView.as_view(), name='group_members'),
) )
api_urls = patterns('', api_urls = patterns('',

View File

@@ -11,7 +11,7 @@ from django.template import RequestContext
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from common.utils import encapsulate, generate_choices_w_labels from common.utils import encapsulate, generate_choices_w_labels
from common.views import assign_remove from common.views import AssignRemoveView
from common.widgets import two_state_template from common.widgets import two_state_template
from permissions.models import Permission from permissions.models import Permission
@@ -219,23 +219,36 @@ def get_user_non_groups(user):
return Group.objects.exclude(user=user) return Group.objects.exclude(user=user)
def user_groups(request, user_id): class UserGroupsView(AssignRemoveView):
Permission.objects.check_permissions(request.user, [PERMISSION_USER_EDIT]) decode_content_type = True
user = get_object_or_404(User, pk=user_id)
return assign_remove( def add(self, item):
request, item.user_set.add(self.user)
left_list=lambda: generate_choices_w_labels(get_user_non_groups(user), display_object_type=False),
right_list=lambda: generate_choices_w_labels(get_user_groups(user), display_object_type=False), def dispatch(self, request, *args, **kwargs):
add_method=lambda x: x.user_set.add(user), Permission.objects.check_permissions(request.user, [PERMISSION_USER_EDIT])
remove_method=lambda x: x.user_set.remove(user), self.user = get_object_or_404(User, pk=self.kwargs['user_id'])
left_list_title=_('Non groups of user: %s') % user, self.left_list_title=_('Non groups of user: %s') % self.user
right_list_title=_('Groups of user: %s') % user, self.right_list_title=_('Groups of user: %s') % self.user
decode_content_type=True,
extra_context={ return super(UserGroupsView, self).dispatch(request, *args, **kwargs)
'object': user,
} def left_list(self):
) return generate_choices_w_labels(get_user_non_groups(self.user), display_object_type=False)
def right_list(self):
return generate_choices_w_labels(get_user_groups(self.user), display_object_type=False)
def remove(self, item):
item.user_set.remove(self.user)
def get_context_data(self, **kwargs):
data = super(UserGroupsView, self).get_context_data(**kwargs)
data.update({
'object': self.user,
})
return data
# Group views # Group views
@@ -345,28 +358,33 @@ def group_multiple_delete(request):
) )
def get_group_members(group): class GroupMembersView(AssignRemoveView):
return group.user_set.all() decode_content_type = True
def add(self, item):
self.group.user_set.add(item)
def get_non_group_members(group): def dispatch(self, request, *args, **kwargs):
return User.objects.exclude(groups=group).exclude(is_staff=True).exclude(is_superuser=True)
def group_members(request, group_id):
Permission.objects.check_permissions(request.user, [PERMISSION_GROUP_EDIT]) Permission.objects.check_permissions(request.user, [PERMISSION_GROUP_EDIT])
group = get_object_or_404(Group, pk=group_id) self.group = get_object_or_404(Group, pk=self.kwargs['group_id'])
self.left_list_title = _('Non members of group: %s') % self.group
self.right_list_title = _('Members of group: %s') % self.group
return assign_remove( return super(GroupMembersView, self).dispatch(request, *args, **kwargs)
request,
left_list=lambda: generate_choices_w_labels(get_non_group_members(group), display_object_type=False), def left_list(self):
right_list=lambda: generate_choices_w_labels(get_group_members(group), display_object_type=False), return generate_choices_w_labels(User.objects.exclude(groups=self.group).exclude(is_staff=True).exclude(is_superuser=True), display_object_type=False)
add_method=lambda x: group.user_set.add(x),
remove_method=lambda x: group.user_set.remove(x), def right_list(self):
left_list_title=_('Non members of group: %s') % group, return generate_choices_w_labels(self.group.user_set.all(), display_object_type=False)
right_list_title=_('Members of group: %s') % group,
decode_content_type=True, def remove(self, item):
extra_context={ self.group.user_set.remove(item)
'object': group,
} def get_context_data(self, **kwargs):
) data = super(GroupMembersView, self).get_context_data(**kwargs)
data.update({
'object': self.group,
})
return data