diff --git a/mayan/apps/common/views.py b/mayan/apps/common/views.py index 280926d4eb..180b650e40 100644 --- a/mayan/apps/common/views.py +++ b/mayan/apps/common/views.py @@ -333,7 +333,7 @@ def multi_object_action_view(request): class AssignRemoveView(TemplateView): left_list_title = None - right_list_title=None + right_list_title = None decode_content_type = False extra_context = None grouped = False @@ -374,7 +374,7 @@ class AssignRemoveView(TemplateView): for selection in self.unselected_list.cleaned_data['selection']: if self.grouped: flat_list = [] - for group in left_list(): + for group in self.left_list(): flat_list.extend(group[1]) else: flat_list = self.left_list() @@ -451,97 +451,6 @@ class AssignRemoveView(TemplateView): 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): """ Allow an user to edit his own details diff --git a/mayan/apps/document_states/urls.py b/mayan/apps/document_states/urls.py index 7aae2fd723..9112d767c6 100644 --- a/mayan/apps/document_states/urls.py +++ b/mayan/apps/document_states/urls.py @@ -3,7 +3,8 @@ from __future__ import unicode_literals from django.conf.urls import patterns, url from .views import ( - SetupWorkflowCreateView, SetupWorkflowDeleteView, SetupWorkflowEditView, + SetupWorkflowCreateView, SetupWorkflowDeleteView, + SetupWorkflowDocumentTypesView, SetupWorkflowEditView, SetupWorkflowListView, SetupWorkflowStateCreateView, SetupWorkflowStateDeleteView, SetupWorkflowStateEditView, SetupWorkflowStateListView, SetupWorkflowTransitionListView, @@ -13,26 +14,20 @@ from .views import ( ) urlpatterns = patterns('', + url(r'^document/(?P\d+)/workflows/$', DocumentWorkflowInstanceListView.as_view(), name='document_workflow_instance_list'), + url(r'^document/workflows/(?P\d+)/$', WorkflowInstanceDetailView.as_view(), name='workflow_instance_detail'), + url(r'^document/workflows/(?P\d+)/transition/$', WorkflowInstanceTransitionView.as_view(), name='workflow_instance_transition'), 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/(?P\d+)/edit/$', SetupWorkflowEditView.as_view(), name='setup_workflow_edit'), url(r'^setup/(?P\d+)/delete/$', SetupWorkflowDeleteView.as_view(), name='setup_workflow_delete'), - + url(r'^setup/(?P\d+)/document_types/$', SetupWorkflowDocumentTypesView.as_view(), name='setup_workflow_document_types'), url(r'^setup/(?P\d+)/states/$', SetupWorkflowStateListView.as_view(), name='setup_workflow_states'), url(r'^setup/(?P\d+)/states/create/$', SetupWorkflowStateCreateView.as_view(), name='setup_workflow_state_create'), - url(r'^setup/workflow/state/(?P\d+)/delete/$', SetupWorkflowStateDeleteView.as_view(), name='setup_workflow_state_delete'), - url(r'^setup/workflow/state/(?P\d+)/edit/$', SetupWorkflowStateEditView.as_view(), name='setup_workflow_state_edit'), - url(r'^setup/(?P\d+)/transitions/$', SetupWorkflowTransitionListView.as_view(), name='setup_workflow_transitions'), url(r'^setup/(?P\d+)/transitions/create/$', SetupWorkflowTransitionCreateView.as_view(), name='setup_workflow_transition_create'), + url(r'^setup/workflow/state/(?P\d+)/delete/$', SetupWorkflowStateDeleteView.as_view(), name='setup_workflow_state_delete'), + url(r'^setup/workflow/state/(?P\d+)/edit/$', SetupWorkflowStateEditView.as_view(), name='setup_workflow_state_edit'), url(r'^setup/workflow/transitions/(?P\d+)/delete/$', SetupWorkflowTransitionDeleteView.as_view(), name='setup_workflow_transition_delete'), url(r'^setup/workflow/transitions/(?P\d+)/edit/$', SetupWorkflowTransitionEditView.as_view(), name='setup_workflow_transition_edit'), - - url(r'^document/(?P\d+)/workflows/$', DocumentWorkflowInstanceListView.as_view(), name='document_workflow_instance_list'), - url(r'^document/workflows/(?P\d+)/$', WorkflowInstanceDetailView.as_view(), name='workflow_instance_detail'), - url(r'^document/workflows/(?P\d+)/transition/$', WorkflowInstanceTransitionView.as_view(), name='workflow_instance_transition'), -) - -urlpatterns += patterns('document_states.views', - url(r'^setup/(?P\d+)/document_types/$', 'setup_workflow_document_types', name='setup_workflow_document_types'), ) diff --git a/mayan/apps/document_states/views.py b/mayan/apps/document_states/views.py index c1b99b72de..db6ac5d47d 100644 --- a/mayan/apps/document_states/views.py +++ b/mayan/apps/document_states/views.py @@ -12,8 +12,8 @@ from django.views.generic import FormView from acls.models import AccessEntry from common.utils import generate_choices_w_labels from common.views import ( - SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView, - SingleObjectListView, assign_remove + AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView, + SingleObjectEditView, SingleObjectListView ) from documents.models import Document from permissions.models import Permission @@ -188,7 +188,40 @@ class SetupWorkflowDeleteView(SingleObjectDeleteView): 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): def dispatch(self, request, *args, **kwargs): @@ -422,25 +455,3 @@ class SetupWorkflowTransitionEditView(SingleObjectEditView): def get_success_url(self): 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, - } - ) diff --git a/mayan/apps/linking/urls.py b/mayan/apps/linking/urls.py index 5fcf0efb56..938ff75e89 100644 --- a/mayan/apps/linking/urls.py +++ b/mayan/apps/linking/urls.py @@ -2,6 +2,8 @@ from __future__ import unicode_literals from django.conf.urls import patterns, url +from .views import SetupSmartLinkDocumentTypesView + urlpatterns = patterns('linking.views', url(r'^document/(?P\d+)/$', 'smart_link_instances_for_document', (), 'smart_link_instances_for_document'), url(r'^document/(?P\d+)/smart_link/(?P\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/(?P\d+)/delete/$', 'smart_link_delete', (), 'smart_link_delete'), url(r'^setup/(?P\d+)/edit/$', 'smart_link_edit', (), 'smart_link_edit'), - url(r'^setup/(?P\d+)/document_types/$', 'smart_link_document_types', (), 'smart_link_document_types'), + url(r'^setup/(?P\d+)/document_types/$', SetupSmartLinkDocumentTypesView.as_view(), name='smart_link_document_types'), url(r'^setup/(?P\d+)/condition/list/$', 'smart_link_condition_list', (), 'smart_link_condition_list'), url(r'^setup/(?P\d+)/condition/create/$', 'smart_link_condition_create', (), 'smart_link_condition_create'), diff --git a/mayan/apps/linking/views.py b/mayan/apps/linking/views.py index 1f42dc0d47..da003a60ea 100644 --- a/mayan/apps/linking/views.py +++ b/mayan/apps/linking/views.py @@ -15,7 +15,7 @@ from acls.models import AccessEntry from acls.utils import apply_default_acls from acls.views import acl_list_for 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 documents.models import Document, DocumentType from documents.views import document_list @@ -31,6 +31,41 @@ from .permissions import ( 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): document = get_object_or_404(Document, pk=document_id) 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)) -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): smart_link = get_object_or_404(SmartLink, pk=smart_link_pk) diff --git a/mayan/apps/permissions/classes.py b/mayan/apps/permissions/classes.py new file mode 100644 index 0000000000..a21e20d2dc --- /dev/null +++ b/mayan/apps/permissions/classes.py @@ -0,0 +1,7 @@ +from __future__ import unicode_literals + +from acls.classes import EncapsulatedObject + + +class Member(EncapsulatedObject): + source_object_name = 'member_object' diff --git a/mayan/apps/permissions/urls.py b/mayan/apps/permissions/urls.py index 82378035bb..cd3d7354d0 100644 --- a/mayan/apps/permissions/urls.py +++ b/mayan/apps/permissions/urls.py @@ -3,7 +3,9 @@ from __future__ import unicode_literals from django.conf.urls import patterns, url from .api_views import APIRoleListView, APIRoleView -from .views import RoleCreateView, RoleDeleteView, RoleEditView +from .views import ( + RoleCreateView, RoleDeleteView, RoleEditView, SetupRoleMembersView +) urlpatterns = patterns('permissions.views', url(r'^role/list/$', 'role_list', (), 'role_list'), @@ -11,7 +13,7 @@ urlpatterns = patterns('permissions.views', url(r'^role/(?P\d+)/permissions/$', 'role_permissions', (), 'role_permissions'), url(r'^role/(?P\d+)/edit/$', RoleEditView.as_view(), name='role_edit'), url(r'^role/(?P\d+)/delete/$', RoleDeleteView.as_view(), name='role_delete'), - url(r'^role/(?P\d+)/members/$', 'role_members', (), 'role_members'), + url(r'^role/(?P\d+)/members/$', SetupRoleMembersView.as_view(), name='role_members'), url(r'^permissions/multiple/grant/$', 'permission_grant', (), 'permission_multiple_grant'), url(r'^permissions/multiple/revoke/$', 'permission_revoke', (), 'permission_multiple_revoke'), diff --git a/mayan/apps/permissions/utils.py b/mayan/apps/permissions/utils.py new file mode 100644 index 0000000000..914aa6012c --- /dev/null +++ b/mayan/apps/permissions/utils.py @@ -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 diff --git a/mayan/apps/permissions/views.py b/mayan/apps/permissions/views.py index 7842e6fdc9..2c55f7754c 100644 --- a/mayan/apps/permissions/views.py +++ b/mayan/apps/permissions/views.py @@ -5,7 +5,6 @@ from json import loads import operator from django.contrib import messages -from django.contrib.auth.models import Group, User from django.contrib.contenttypes.models import ContentType from django.core.urlresolvers import reverse 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.utils.translation import ugettext_lazy as _ -from acls.classes import EncapsulatedObject -from common.models import AnonymousUserSingleton from common.views import ( - SingleObjectCreateView, SingleObjectDeleteView, SingleObjectEditView, - assign_remove + AssignRemoveView, SingleObjectCreateView, SingleObjectDeleteView, + SingleObjectEditView ) -from common.utils import encapsulate, get_object_name +from common.utils import encapsulate from common.widgets import two_state_template +from .classes import Member from .forms import RoleForm, RoleForm_view from .models import Permission, Role from .permissions import ( @@ -31,6 +29,7 @@ from .permissions import ( PERMISSION_ROLE_VIEW, PERMISSION_ROLE_CREATE, PERMISSION_ROLE_DELETE, PERMISSION_ROLE_EDIT ) +from .utils import get_non_role_members, get_role_members class RoleCreateView(SingleObjectCreateView): @@ -51,6 +50,40 @@ class RoleEditView(SingleObjectEditView): 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): 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, 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, - ) diff --git a/mayan/apps/user_management/urls.py b/mayan/apps/user_management/urls.py index 946e9fe6dd..91303cc8cb 100644 --- a/mayan/apps/user_management/urls.py +++ b/mayan/apps/user_management/urls.py @@ -6,6 +6,7 @@ from .api_views import ( APICurrentUserView, APIGroupListView, APIGroupView, APIUserListView, APIUserView ) +from .views import GroupMembersView, UserGroupsView urlpatterns = patterns('user_management.views', 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/(?P\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/(?P\d+)/groups/$', 'user_groups', (), 'user_groups'), + url(r'^user/(?P\d+)/groups/$', UserGroupsView.as_view(), name='user_groups'), url(r'^group/list/$', 'group_list', (), 'group_list'), url(r'^group/add/$', 'group_add', (), 'group_add'), url(r'^group/(?P\d+)/edit/$', 'group_edit', (), 'group_edit'), url(r'^group/(?P\d+)/delete/$', 'group_delete', (), 'group_delete'), url(r'^group/multiple/delete/$', 'group_multiple_delete', (), 'group_multiple_delete'), - url(r'^group/(?P\d+)/members/$', 'group_members', (), 'group_members'), + url(r'^group/(?P\d+)/members/$', GroupMembersView.as_view(), name='group_members'), ) api_urls = patterns('', diff --git a/mayan/apps/user_management/views.py b/mayan/apps/user_management/views.py index 3048fd16e2..e52f28128f 100644 --- a/mayan/apps/user_management/views.py +++ b/mayan/apps/user_management/views.py @@ -11,7 +11,7 @@ from django.template import RequestContext from django.utils.translation import ugettext_lazy as _ 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 permissions.models import Permission @@ -219,23 +219,36 @@ def get_user_non_groups(user): return Group.objects.exclude(user=user) -def user_groups(request, user_id): - Permission.objects.check_permissions(request.user, [PERMISSION_USER_EDIT]) - user = get_object_or_404(User, pk=user_id) +class UserGroupsView(AssignRemoveView): + decode_content_type = True - return assign_remove( - request, - 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), - add_method=lambda x: x.user_set.add(user), - remove_method=lambda x: x.user_set.remove(user), - left_list_title=_('Non groups of user: %s') % user, - right_list_title=_('Groups of user: %s') % user, - decode_content_type=True, - extra_context={ - 'object': user, - } - ) + def add(self, item): + item.user_set.add(self.user) + + def dispatch(self, request, *args, **kwargs): + Permission.objects.check_permissions(request.user, [PERMISSION_USER_EDIT]) + self.user = get_object_or_404(User, pk=self.kwargs['user_id']) + self.left_list_title=_('Non groups of user: %s') % self.user + self.right_list_title=_('Groups of user: %s') % self.user + + return super(UserGroupsView, self).dispatch(request, *args, **kwargs) + + 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 @@ -345,28 +358,33 @@ def group_multiple_delete(request): ) -def get_group_members(group): - return group.user_set.all() +class GroupMembersView(AssignRemoveView): + decode_content_type = True + def add(self, item): + self.group.user_set.add(item) -def get_non_group_members(group): - return User.objects.exclude(groups=group).exclude(is_staff=True).exclude(is_superuser=True) + def dispatch(self, request, *args, **kwargs): + Permission.objects.check_permissions(request.user, [PERMISSION_GROUP_EDIT]) + 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 super(GroupMembersView, self).dispatch(request, *args, **kwargs) -def group_members(request, group_id): - Permission.objects.check_permissions(request.user, [PERMISSION_GROUP_EDIT]) - group = get_object_or_404(Group, pk=group_id) + def left_list(self): + return generate_choices_w_labels(User.objects.exclude(groups=self.group).exclude(is_staff=True).exclude(is_superuser=True), display_object_type=False) - return assign_remove( - request, - left_list=lambda: generate_choices_w_labels(get_non_group_members(group), display_object_type=False), - right_list=lambda: generate_choices_w_labels(get_group_members(group), display_object_type=False), - add_method=lambda x: group.user_set.add(x), - remove_method=lambda x: group.user_set.remove(x), - left_list_title=_('Non members of group: %s') % group, - right_list_title=_('Members of group: %s') % group, - decode_content_type=True, - extra_context={ - 'object': group, - } - ) + def right_list(self): + return generate_choices_w_labels(self.group.user_set.all(), display_object_type=False) + + def remove(self, item): + self.group.user_set.remove(item) + + def get_context_data(self, **kwargs): + data = super(GroupMembersView, self).get_context_data(**kwargs) + data.update({ + 'object': self.group, + }) + + return data