Merge branch 'restrict_group_states' into 'master'

Restrict groups by state.

See merge request allianceauth/allianceauth!1095
This commit is contained in:
Basraah 2018-10-09 02:06:44 +00:00
commit 5a16c9c495
5 changed files with 57 additions and 13 deletions

View File

@ -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 = ''

View File

@ -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

View File

@ -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'),
),
]

View File

@ -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):

View File

@ -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"))