mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-15 15:30:16 +02:00
Added support for group leaders to manage groups
This commit is contained in:
parent
9eba5607d2
commit
83b62525eb
@ -111,6 +111,7 @@ TEMPLATES = [
|
|||||||
'authentication.context_processors.states',
|
'authentication.context_processors.states',
|
||||||
'authentication.context_processors.membership_state',
|
'authentication.context_processors.membership_state',
|
||||||
'authentication.context_processors.sso',
|
'authentication.context_processors.sso',
|
||||||
|
'groupmanagement.context_processors.can_manage_groups',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
5
groupmanagement/context_processors.py
Normal file
5
groupmanagement/context_processors.py
Normal 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)}
|
@ -1,5 +1,6 @@
|
|||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from authentication.managers import UserState
|
||||||
|
|
||||||
class GroupManager:
|
class GroupManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -9,6 +10,10 @@ class GroupManager:
|
|||||||
def get_joinable_groups():
|
def get_joinable_groups():
|
||||||
return Group.objects.exclude(authgroup__internal=True)
|
return Group.objects.exclude(authgroup__internal=True)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def get_group_leaders_groups(user):
|
||||||
|
return Group.objects.filter(authgroup__group_leaders__in=[user])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def joinable_group(group):
|
def joinable_group(group):
|
||||||
"""
|
"""
|
||||||
@ -18,3 +23,34 @@ class GroupManager:
|
|||||||
:return: bool True if its joinable, False otherwise
|
:return: bool True if its joinable, False otherwise
|
||||||
"""
|
"""
|
||||||
return not group.authgroup.internal
|
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
|
||||||
|
@ -1,18 +1,18 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
from django.contrib.auth.decorators import login_required
|
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.auth.models import Group
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from notifications import notify
|
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.utils.translation import ugettext_lazy as _
|
||||||
from django.db.models import Count
|
from django.db.models import Count
|
||||||
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
||||||
from django.http import Http404
|
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
|
import logging
|
||||||
|
|
||||||
@ -20,17 +20,25 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('auth.group_management')
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_management(request):
|
def group_management(request):
|
||||||
logger.debug("group_management called by user %s" % request.user)
|
logger.debug("group_management called by user %s" % request.user)
|
||||||
acceptrequests = []
|
acceptrequests = []
|
||||||
leaverequests = []
|
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:
|
if grouprequest.leave_request:
|
||||||
leaverequests.append(grouprequest)
|
leaverequests.append(grouprequest)
|
||||||
else:
|
else:
|
||||||
acceptrequests.append(grouprequest)
|
acceptrequests.append(grouprequest)
|
||||||
|
|
||||||
logger.debug("Providing user %s with %s acceptrequests and %s leaverequests." % (
|
logger.debug("Providing user %s with %s acceptrequests and %s leaverequests." % (
|
||||||
request.user, len(acceptrequests), len(leaverequests)))
|
request.user, len(acceptrequests), len(leaverequests)))
|
||||||
|
|
||||||
@ -40,11 +48,18 @@ def group_management(request):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('auth.group_management')
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_membership(request):
|
def group_membership(request):
|
||||||
logger.debug("group_membership called by user %s" % request.user)
|
logger.debug("group_membership called by user %s" % request.user)
|
||||||
# Get all open and closed groups
|
# 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}
|
render_items = {'groups': groups}
|
||||||
|
|
||||||
@ -52,14 +67,17 @@ def group_membership(request):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('auth.group_management')
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_membership_list(request, group_id):
|
def group_membership_list(request, group_id):
|
||||||
logger.debug("group_membership_list called by user %s for group id %s" % (request.user, group_id))
|
logger.debug("group_membership_list called by user %s for group id %s" % (request.user, group_id))
|
||||||
try:
|
try:
|
||||||
group = Group.objects.get(id=group_id)
|
group = Group.objects.get(id=group_id)
|
||||||
|
|
||||||
# Check its a joinable group i.e. not corp or internal
|
# 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
|
raise PermissionDenied
|
||||||
|
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
@ -81,13 +99,20 @@ def group_membership_list(request, group_id):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('auth.group_management')
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_membership_remove(request, group_id, user_id):
|
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" %
|
logger.debug("group_membership_remove called by user %s for group id %s on user id %s" %
|
||||||
(request.user, group_id, user_id))
|
(request.user, group_id, user_id))
|
||||||
try:
|
try:
|
||||||
group = Group.objects.get(id=group_id)
|
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:
|
try:
|
||||||
user = group.user_set.get(id=user_id)
|
user = group.user_set.get(id=user_id)
|
||||||
# Remove group from user
|
# Remove group from user
|
||||||
@ -103,12 +128,17 @@ def group_membership_remove(request, group_id, user_id):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('auth.group_management')
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_accept_request(request, group_request_id):
|
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))
|
logger.debug("group_accept_request called by user %s for grouprequest id %s" % (request.user, group_request_id))
|
||||||
try:
|
try:
|
||||||
group_request = GroupRequest.objects.get(id=group_request_id)
|
group_request = GroupRequest.objects.get(id=group_request_id)
|
||||||
group, created = Group.objects.get_or_create(name=group_request.group.name)
|
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.groups.add(group)
|
||||||
group_request.user.save()
|
group_request.user.save()
|
||||||
group_request.delete()
|
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)
|
message="Your application to %s has been accepted." % group_request.group)
|
||||||
messages.success(request,
|
messages.success(request,
|
||||||
'Accepted application from %s to %s.' % (group_request.main_char, group_request.group))
|
'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:
|
except:
|
||||||
messages.error(request, 'An unhandled error occurred while processing the application from %s to %s.' % (
|
messages.error(request, 'An unhandled error occurred while processing the application from %s to %s.' % (
|
||||||
group_request.main_char, group_request.group))
|
group_request.main_char, group_request.group))
|
||||||
@ -129,12 +164,15 @@ def group_accept_request(request, group_request_id):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('auth.group_management')
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_reject_request(request, group_request_id):
|
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))
|
logger.debug("group_reject_request called by user %s for group request id %s" % (request.user, group_request_id))
|
||||||
try:
|
try:
|
||||||
group_request = GroupRequest.objects.get(id=group_request_id)
|
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:
|
if group_request:
|
||||||
logger.info("User %s rejected group request from user %s to group %s" % (
|
logger.info("User %s rejected group request from user %s to group %s" % (
|
||||||
request.user, group_request.user, group_request.group.name))
|
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)
|
message="Your application to %s has been rejected." % group_request.group)
|
||||||
messages.success(request,
|
messages.success(request,
|
||||||
'Rejected application from %s to %s.' % (group_request.main_char, group_request.group))
|
'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:
|
except:
|
||||||
messages.error(request, 'An unhandled error occured while processing the application from %s to %s.' % (
|
messages.error(request, 'An unhandled error occured while processing the application from %s to %s.' % (
|
||||||
group_request.main_char, group_request.group))
|
group_request.main_char, group_request.group))
|
||||||
@ -154,12 +197,16 @@ def group_reject_request(request, group_request_id):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('auth.group_management')
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_leave_accept_request(request, group_request_id):
|
def group_leave_accept_request(request, group_request_id):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"group_leave_accept_request called by user %s for group request id %s" % (request.user, group_request_id))
|
"group_leave_accept_request called by user %s for group request id %s" % (request.user, group_request_id))
|
||||||
try:
|
try:
|
||||||
group_request = GroupRequest.objects.get(id=group_request_id)
|
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, created = Group.objects.get_or_create(name=group_request.group.name)
|
||||||
group_request.user.groups.remove(group)
|
group_request.user.groups.remove(group)
|
||||||
group_request.user.save()
|
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)
|
message="Your request to leave %s has been accepted." % group_request.group)
|
||||||
messages.success(request,
|
messages.success(request,
|
||||||
'Accepted application from %s to leave %s.' % (group_request.main_char, group_request.group))
|
'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:
|
except:
|
||||||
messages.error(request, 'An unhandled error occured while processing the application from %s to leave %s.' % (
|
messages.error(request, 'An unhandled error occured while processing the application from %s to leave %s.' % (
|
||||||
group_request.main_char, group_request.group))
|
group_request.main_char, group_request.group))
|
||||||
@ -181,13 +232,16 @@ def group_leave_accept_request(request, group_request_id):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('auth.group_management')
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_leave_reject_request(request, group_request_id):
|
def group_leave_reject_request(request, group_request_id):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"group_leave_reject_request called by user %s for group request id %s" % (request.user, group_request_id))
|
"group_leave_reject_request called by user %s for group request id %s" % (request.user, group_request_id))
|
||||||
try:
|
try:
|
||||||
group_request = GroupRequest.objects.get(id=group_request_id)
|
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:
|
if group_request:
|
||||||
group_request.delete()
|
group_request.delete()
|
||||||
logger.info("User %s rejected group leave request from user %s for group %s" % (
|
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)
|
message="Your request to leave %s has been rejected." % group_request.group)
|
||||||
messages.success(request, 'Rejected application from %s to leave %s.' % (
|
messages.success(request, 'Rejected application from %s to leave %s.' % (
|
||||||
group_request.main_char, group_request.group))
|
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:
|
except:
|
||||||
messages.error(request, 'An unhandled error occured while processing the application from %s to leave %s.' % (
|
messages.error(request, 'An unhandled error occured while processing the application from %s to leave %s.' % (
|
||||||
group_request.main_char, group_request.group))
|
group_request.main_char, group_request.group))
|
||||||
|
@ -165,7 +165,7 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if perms.auth.group_management %}
|
{% if can_manage_groups %}
|
||||||
<li>
|
<li>
|
||||||
<a class="{% navactive request 'auth_group_management' %}" href="{% url 'auth_group_management' %}">
|
<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" %}
|
<i class="fa fa-lock fa-sitemap fa-fw grayiconecolor"></i>{% trans " Group Management" %}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user