Added support for group leaders to manage groups

This commit is contained in:
Basraah 2016-12-05 21:49:12 +10:00
parent 9eba5607d2
commit 83b62525eb
5 changed files with 117 additions and 17 deletions

View File

@ -111,6 +111,7 @@ TEMPLATES = [
'authentication.context_processors.states',
'authentication.context_processors.membership_state',
'authentication.context_processors.sso',
'groupmanagement.context_processors.can_manage_groups',
],
},
},

View File

@ -0,0 +1,5 @@
from groupmanagement.managers import GroupManager
def can_manage_groups(request):
return {'can_manage_groups': GroupManager.can_manage_groups(request.user)}

View File

@ -1,5 +1,6 @@
from django.contrib.auth.models import Group
from django.conf import settings
from authentication.managers import UserState
class GroupManager:
def __init__(self):
@ -9,6 +10,10 @@ class GroupManager:
def get_joinable_groups():
return Group.objects.exclude(authgroup__internal=True)
@staticmethod
def get_group_leaders_groups(user):
return Group.objects.filter(authgroup__group_leaders__in=[user])
@staticmethod
def joinable_group(group):
"""
@ -18,3 +23,34 @@ class GroupManager:
:return: bool True if its joinable, False otherwise
"""
return not group.authgroup.internal
@staticmethod
def has_management_permission(user):
return user.has_perm('auth.group_management')
@classmethod
def can_manage_groups(cls, user):
"""
For use with user_passes_test decorator.
Check if the user can manage groups. Either has the
auth.group_management permission or is a leader of at least one group
and is also a Member.
:param user: django.contrib.auth.models.User for the request
:return: bool True if user can manage groups, False otherwise
"""
if user.is_authenticated:
return cls.has_management_permission(user) or (user.leads_groups.all() and UserState.member_state(user))
return False
@classmethod
def can_manage_group(cls, user, group):
"""
Check user has permission to manage the given group
:param user: User object to test permission of
:param group: Group object the user is attempting to manage
:return: True if the user can manage the group
"""
if user.is_authenticated:
return cls.has_management_permission(user) or (
user.leads_groups.filter(group=group).exists() and UserState.member_state(user))
return False

View File

@ -1,18 +1,18 @@
from __future__ import unicode_literals
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import permission_required
from django.contrib.auth.decorators import user_passes_test
from django.contrib.auth.models import Group
from django.contrib import messages
from notifications import notify
from groupmanagement.managers import GroupManager
from groupmanagement.models import GroupRequest
from authentication.models import AuthServicesInfo
from eveonline.managers import EveManager
from django.utils.translation import ugettext_lazy as _
from django.db.models import Count
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.http import Http404
from groupmanagement.managers import GroupManager
from groupmanagement.models import GroupRequest
from authentication.models import AuthServicesInfo
from eveonline.managers import EveManager
import logging
@ -20,17 +20,25 @@ logger = logging.getLogger(__name__)
@login_required
@permission_required('auth.group_management')
@user_passes_test(GroupManager.can_manage_groups)
def group_management(request):
logger.debug("group_management called by user %s" % request.user)
acceptrequests = []
leaverequests = []
for grouprequest in GroupRequest.objects.all():
if GroupManager.has_management_permission(request.user):
# Full access
group_requests = GroupRequest.objects.all()
else:
# Group specific leader
group_requests = GroupRequest.objects.filter(group__authgroup__group_leaders__in=[request.user])
for grouprequest in group_requests:
if grouprequest.leave_request:
leaverequests.append(grouprequest)
else:
acceptrequests.append(grouprequest)
logger.debug("Providing user %s with %s acceptrequests and %s leaverequests." % (
request.user, len(acceptrequests), len(leaverequests)))
@ -40,11 +48,18 @@ def group_management(request):
@login_required
@permission_required('auth.group_management')
@user_passes_test(GroupManager.can_manage_groups)
def group_membership(request):
logger.debug("group_membership called by user %s" % request.user)
# Get all open and closed groups
groups = Group.objects.exclude(authgroup__internal=True).annotate(num_members=Count('user')).order_by('name')
if GroupManager.has_management_permission(request.user):
# Full access
groups = GroupManager.get_joinable_groups()
else:
# Group leader specific
groups = GroupManager.get_group_leaders_groups(request.user)
groups = groups.exclude(authgroup__internal=True).annotate(num_members=Count('user')).order_by('name')
render_items = {'groups': groups}
@ -52,14 +67,17 @@ def group_membership(request):
@login_required
@permission_required('auth.group_management')
@user_passes_test(GroupManager.can_manage_groups)
def group_membership_list(request, group_id):
logger.debug("group_membership_list called by user %s for group id %s" % (request.user, group_id))
try:
group = Group.objects.get(id=group_id)
# Check its a joinable group i.e. not corp or internal
if not GroupManager.joinable_group(group):
# And the user has permission to manage it
if not GroupManager.joinable_group(group) or not GroupManager.can_manage_group(request.user, group):
logger.warning("User %s attempted to view the membership of group %s but permission was denied" %
(request.user, group_id))
raise PermissionDenied
except ObjectDoesNotExist:
@ -81,13 +99,20 @@ def group_membership_list(request, group_id):
@login_required
@permission_required('auth.group_management')
@user_passes_test(GroupManager.can_manage_groups)
def group_membership_remove(request, group_id, user_id):
logger.debug("group_membership_remove called by user %s for group id %s on user id %s" %
(request.user, group_id, user_id))
try:
group = Group.objects.get(id=group_id)
# Check its a joinable group i.e. not corp or internal
# And the user has permission to manage it
if not GroupManager.joinable_group(group) or not GroupManager.can_manage_group(request.user, group):
logger.warning("User %s attempted to remove a user from group %s but permission was denied" % (request.user,
group_id))
raise PermissionDenied
try:
user = group.user_set.get(id=user_id)
# Remove group from user
@ -103,12 +128,17 @@ def group_membership_remove(request, group_id, user_id):
@login_required
@permission_required('auth.group_management')
@user_passes_test(GroupManager.can_manage_groups)
def group_accept_request(request, group_request_id):
logger.debug("group_accept_request called by user %s for grouprequest id %s" % (request.user, group_request_id))
try:
group_request = GroupRequest.objects.get(id=group_request_id)
group, created = Group.objects.get_or_create(name=group_request.group.name)
if not GroupManager.joinable_group(group_request.group) or \
not GroupManager.can_manage_group(request.user, group_request.group):
raise PermissionDenied
group_request.user.groups.add(group)
group_request.user.save()
group_request.delete()
@ -118,6 +148,11 @@ def group_accept_request(request, group_request_id):
message="Your application to %s has been accepted." % group_request.group)
messages.success(request,
'Accepted application from %s to %s.' % (group_request.main_char, group_request.group))
except PermissionDenied as p:
logger.warning("User %s attempted to accept group join request %s but permission was denied" %
(request.user, group_request_id))
raise p
except:
messages.error(request, 'An unhandled error occurred while processing the application from %s to %s.' % (
group_request.main_char, group_request.group))
@ -129,12 +164,15 @@ def group_accept_request(request, group_request_id):
@login_required
@permission_required('auth.group_management')
@user_passes_test(GroupManager.can_manage_groups)
def group_reject_request(request, group_request_id):
logger.debug("group_reject_request called by user %s for group request id %s" % (request.user, group_request_id))
try:
group_request = GroupRequest.objects.get(id=group_request_id)
if not GroupManager.can_manage_group(request.user, group_request.group):
raise PermissionDenied
if group_request:
logger.info("User %s rejected group request from user %s to group %s" % (
request.user, group_request.user, group_request.group.name))
@ -143,6 +181,11 @@ def group_reject_request(request, group_request_id):
message="Your application to %s has been rejected." % group_request.group)
messages.success(request,
'Rejected application from %s to %s.' % (group_request.main_char, group_request.group))
except PermissionDenied as p:
logger.warning("User %s attempted to reject group join request %s but permission was denied" %
(request.user, group_request_id))
raise p
except:
messages.error(request, 'An unhandled error occured while processing the application from %s to %s.' % (
group_request.main_char, group_request.group))
@ -154,12 +197,16 @@ def group_reject_request(request, group_request_id):
@login_required
@permission_required('auth.group_management')
@user_passes_test(GroupManager.can_manage_groups)
def group_leave_accept_request(request, group_request_id):
logger.debug(
"group_leave_accept_request called by user %s for group request id %s" % (request.user, group_request_id))
try:
group_request = GroupRequest.objects.get(id=group_request_id)
if not GroupManager.can_manage_group(request.user, group_request.group):
raise PermissionDenied
group, created = Group.objects.get_or_create(name=group_request.group.name)
group_request.user.groups.remove(group)
group_request.user.save()
@ -170,6 +217,10 @@ def group_leave_accept_request(request, group_request_id):
message="Your request to leave %s has been accepted." % group_request.group)
messages.success(request,
'Accepted application from %s to leave %s.' % (group_request.main_char, group_request.group))
except PermissionDenied as p:
logger.warning("User %s attempted to accept group leave request %s but permission was denied" %
(request.user, group_request_id))
raise p
except:
messages.error(request, 'An unhandled error occured while processing the application from %s to leave %s.' % (
group_request.main_char, group_request.group))
@ -181,13 +232,16 @@ def group_leave_accept_request(request, group_request_id):
@login_required
@permission_required('auth.group_management')
@user_passes_test(GroupManager.can_manage_groups)
def group_leave_reject_request(request, group_request_id):
logger.debug(
"group_leave_reject_request called by user %s for group request id %s" % (request.user, group_request_id))
try:
group_request = GroupRequest.objects.get(id=group_request_id)
if not GroupManager.can_manage_group(request.user, group_request.group):
raise PermissionDenied
if group_request:
group_request.delete()
logger.info("User %s rejected group leave request from user %s for group %s" % (
@ -196,6 +250,10 @@ def group_leave_reject_request(request, group_request_id):
message="Your request to leave %s has been rejected." % group_request.group)
messages.success(request, 'Rejected application from %s to leave %s.' % (
group_request.main_char, group_request.group))
except PermissionDenied as p:
logger.warning("User %s attempted to reject group leave request %s but permission was denied" %
(request.user, group_request_id))
raise p
except:
messages.error(request, 'An unhandled error occured while processing the application from %s to leave %s.' % (
group_request.main_char, group_request.group))

View File

@ -165,7 +165,7 @@
</li>
{% endif %}
{% if perms.auth.group_management %}
{% if can_manage_groups %}
<li>
<a class="{% navactive request 'auth_group_management' %}" href="{% url 'auth_group_management' %}">
<i class="fa fa-lock fa-sitemap fa-fw grayiconecolor"></i>{% trans " Group Management" %}