From 9dd8357f674b25b2bd66aa81202dbc583f2b6161 Mon Sep 17 00:00:00 2001 From: colcrunch Date: Tue, 9 Oct 2018 02:06:44 +0000 Subject: [PATCH] Restrict groups by state. --- allianceauth/groupmanagement/admin.py | 4 +-- allianceauth/groupmanagement/managers.py | 27 ++++++++++++++++--- .../migrations/0010_authgroup_states.py | 19 +++++++++++++ allianceauth/groupmanagement/models.py | 5 ++++ allianceauth/groupmanagement/views.py | 15 ++++++----- 5 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 allianceauth/groupmanagement/migrations/0010_authgroup_states.py diff --git a/allianceauth/groupmanagement/admin.py b/allianceauth/groupmanagement/admin.py index f6c64bfb..09d2aaa1 100644 --- a/allianceauth/groupmanagement/admin.py +++ b/allianceauth/groupmanagement/admin.py @@ -8,8 +8,8 @@ from .models import GroupRequest class AuthGroupInlineAdmin(admin.StackedInline): model = AuthGroup - filter_horizontal = ('group_leaders',) - fields = ('description', 'group_leaders', 'internal', 'hidden', 'open', 'public') + filter_horizontal = ('group_leaders', 'states',) + fields = ('description', 'group_leaders', 'states', 'internal', 'hidden', 'open', 'public') verbose_name_plural = 'Auth Settings' verbose_name = '' diff --git a/allianceauth/groupmanagement/managers.py b/allianceauth/groupmanagement/managers.py index 0a6ebe24..1f04fefe 100644 --- a/allianceauth/groupmanagement/managers.py +++ b/allianceauth/groupmanagement/managers.py @@ -1,4 +1,5 @@ from django.contrib.auth.models import Group +from django.db.models import Q class GroupManager: @@ -6,7 +7,12 @@ class GroupManager: pass @staticmethod - def get_joinable_groups(): + def get_joinable_groups(state): + return Group.objects.select_related('authgroup').exclude(authgroup__internal=True)\ + .filter(Q(authgroup__states=state) | Q(authgroup__state=None)) + + @staticmethod + def get_all_non_internal_groups(): return Group.objects.select_related('authgroup').exclude(authgroup__internal=True) @staticmethod @@ -14,13 +20,26 @@ class GroupManager: return Group.objects.select_related('authgroup').filter(authgroup__group_leaders__in=[user]) @staticmethod - def joinable_group(group): + def joinable_group(group, state): """ - Check if a group is a user joinable group, i.e. - not an internal group for Corp, Alliance, Members etc + Check if a group is a user/state joinable group, i.e. + not an internal group for Corp, Alliance, Members etc, + or restricted from the user's current state. :param group: django.contrib.auth.models.Group object + :param state: allianceauth.authentication.State object :return: bool True if its joinable, False otherwise """ + if len(group.authgroup.states.all()) != 0 and state not in group.authgroup.states.all(): + return False + return not group.authgroup.internal + + @staticmethod + def check_internal_group(group): + """ + Check if a group is auditable, i.e not an internal group + :param group: django.contrib.auth.models.Group object + :return: bool True if it is auditable, false otherwise + """ return not group.authgroup.internal @staticmethod diff --git a/allianceauth/groupmanagement/migrations/0010_authgroup_states.py b/allianceauth/groupmanagement/migrations/0010_authgroup_states.py new file mode 100644 index 00000000..036e6a2d --- /dev/null +++ b/allianceauth/groupmanagement/migrations/0010_authgroup_states.py @@ -0,0 +1,19 @@ +# Generated by Django 2.0.6 on 2018-07-11 00:17 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('authentication', '0016_ownershiprecord'), + ('groupmanagement', '0008_remove_authgroup_permissions'), + ] + + operations = [ + migrations.AddField( + model_name='authgroup', + name='states', + field=models.ManyToManyField(blank=True, help_text='States listed here will have the ability to join this group provided they have the proper permissions.', related_name='valid_states', to='authentication.State'), + ), + ] diff --git a/allianceauth/groupmanagement/models.py b/allianceauth/groupmanagement/models.py index 4e93a090..ce83dd05 100644 --- a/allianceauth/groupmanagement/models.py +++ b/allianceauth/groupmanagement/models.py @@ -3,6 +3,7 @@ from django.contrib.auth.models import User from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver +from allianceauth.authentication.models import State class GroupRequest(models.Model): @@ -96,6 +97,10 @@ class AuthGroup(models.Model): "specifically. Use the auth.group_management permission to allow " "a user to manage all groups.") + states = models.ManyToManyField(State, related_name='valid_states', blank=True, + help_text="States listed here will have the ability to join this group provided " + "they have the proper permissions.") + description = models.CharField(max_length=512, blank=True, help_text="Description of the group shown to users.") def __str__(self): diff --git a/allianceauth/groupmanagement/views.py b/allianceauth/groupmanagement/views.py index 39014f20..145ae6d2 100755 --- a/allianceauth/groupmanagement/views.py +++ b/allianceauth/groupmanagement/views.py @@ -53,7 +53,7 @@ def group_membership(request): # Get all open and closed groups if GroupManager.has_management_permission(request.user): # Full access - groups = GroupManager.get_joinable_groups() + groups = GroupManager.get_all_non_internal_groups() else: # Group leader specific groups = GroupManager.get_group_leaders_groups(request.user) @@ -100,7 +100,7 @@ def group_membership_list(request, 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): + if not GroupManager.check_internal_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 @@ -131,7 +131,7 @@ def group_membership_remove(request, group_id, user_id): try: # 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): + if not GroupManager.check_internal_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 @@ -162,7 +162,7 @@ def group_accept_request(request, group_request_id): try: group, created = Group.objects.get_or_create(name=group_request.group.name) - if not GroupManager.joinable_group(group_request.group) or \ + if not GroupManager.joinable_group(group_request.group, group_request.user.profile.state) or \ not GroupManager.can_manage_group(request.user, group_request.group): raise PermissionDenied @@ -299,7 +299,7 @@ def groups_view(request): logger.debug("groups_view called by user %s" % request.user) groups = [] - group_query = GroupManager.get_joinable_groups() + group_query = GroupManager.get_joinable_groups(request.user.profile.state) if not request.user.has_perm('groupmanagement.request_groups'): # Filter down to public groups only for non-members @@ -321,7 +321,8 @@ def groups_view(request): def group_request_add(request, group_id): logger.debug("group_request_add called by user %s for group id %s" % (request.user, group_id)) group = Group.objects.get(id=group_id) - if not GroupManager.joinable_group(group): + state = request.user.profile.state + if not GroupManager.joinable_group(group, state): logger.warning("User %s attempted to join group id %s but it is not a joinable group" % (request.user, group_id)) messages.warning(request, _("You cannot join that group")) @@ -351,7 +352,7 @@ def group_request_add(request, group_id): def group_request_leave(request, group_id): logger.debug("group_request_leave called by user %s for group id %s" % (request.user, group_id)) group = Group.objects.get(id=group_id) - if not GroupManager.joinable_group(group): + if not GroupManager.check_internal_group(group): logger.warning("User %s attempted to leave group id %s but it is not a joinable group" % (request.user, group_id)) messages.warning(request, _("You cannot leave that group"))