Enable group state restrictions to work with internal groups

This commit is contained in:
Erik Kalkoken 2020-12-19 02:05:05 +00:00 committed by Ariel Rin
parent 08e9676760
commit 4fd6f06c0b
2 changed files with 95 additions and 50 deletions

View File

@ -1,16 +1,22 @@
from allianceauth.authentication.signals import state_changed
from .managers import GroupManager
from .models import Group
from django.dispatch import receiver
import logging import logging
from django.dispatch import receiver
from allianceauth.authentication.signals import state_changed
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@receiver(state_changed) @receiver(state_changed)
def check_groups_on_state_change(sender, user, state, **kwargs): def check_groups_on_state_change(sender, user, state, **kwargs):
logger.debug("Updating auth groups for {}".format(user)) logger.debug(
visible_groups = GroupManager.get_joinable_groups(state) "Checking group memberships for %s based on new state %s" % (user, state)
visible_groups = visible_groups | Group.objects.select_related('authgroup').filter(authgroup__internal=True) )
groups = user.groups.all() state_groups = (
for g in groups: user.groups.select_related("authgroup").exclude(authgroup__states=None)
if g not in visible_groups: )
user.groups.remove(g) for group in state_groups:
if not group.authgroup.states.filter(id=state.id).exists():
logger.info(
"Removing user %s from group %s due to missing state" % (user, group)
)
user.groups.remove(group)

View File

@ -1,61 +1,100 @@
from unittest import mock
from django.test import TestCase from django.test import TestCase
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
from allianceauth.eveonline.models import EveCorporationInfo, EveAllianceInfo from allianceauth.eveonline.models import EveCorporationInfo
from allianceauth.eveonline.autogroups.models import AutogroupsConfig
from allianceauth.tests.auth_utils import AuthUtils from allianceauth.tests.auth_utils import AuthUtils
from ..signals import check_groups_on_state_change
class TestCheckGroupsOnStateChange(TestCase):
class GroupManagementStateTestCase(TestCase):
@classmethod @classmethod
def setUpTestData(cls): def setUpTestData(cls):
cls.user = AuthUtils.create_user('test') cls.user = AuthUtils.create_user('test')
AuthUtils.add_main_character( cls.character = AuthUtils.add_main_character_2(
cls.user, 'test character', '1', corp_id='2', corp_name='test_corp', corp_ticker='TEST', alliance_id='3', alliance_name='TEST' cls.user, 'test character', 1001, corp_id=2001, corp_name='test corp 1', corp_ticker='TEST'
) )
cls.user.profile.refresh_from_db() cls.user.profile.refresh_from_db()
cls.alliance = EveAllianceInfo.objects.create( cls.corp_1 = EveCorporationInfo.objects.create(
alliance_id='3', alliance_name='test alliance', alliance_ticker='TEST', executor_corp_id='2' corporation_id=2001, corporation_name='test corp 1', corporation_ticker='C1', member_count=1
) )
cls.corp = EveCorporationInfo.objects.create( cls.corp_2 = EveCorporationInfo.objects.create(
corporation_id='2', corporation_name='test corp', corporation_ticker='TEST', alliance=cls.alliance, member_count=1 corporation_id=2002, corporation_name='test corp 2', corporation_ticker='C2', member_count=1
) )
cls.state_group = Group.objects.create(name='state_group') cls.guest_state = AuthUtils.get_guest_state()
cls.open_group = Group.objects.create(name='open_group') cls.test_state_1 = AuthUtils.create_state('test_state_1', 500)
cls.state = AuthUtils.create_state('test state', 500) cls.test_state_2 = AuthUtils.create_state('test_state_2', 600)
cls.state_group.authgroup.states.add(cls.state)
cls.state_group.authgroup.internal = False
cls.state_group.save()
def setUp(self): def setUp(self):
self.user.refresh_from_db() self.user.refresh_from_db()
self.state.refresh_from_db()
def _refresh_user(self): def _refresh_user(self):
self.user = User.objects.get(pk=self.user.pk) self.user = User.objects.get(pk=self.user.pk)
def _refresh_test_group(self):
self.state_group = Group.objects.get(pk=self.state_group.pk)
def test_drop_state_group(self): def test_drop_state_group(self):
self.user.groups.add(self.open_group) """
self.user.groups.add(self.state_group) given user is member of: state group, normal group and auto group
self.assertEqual(self.user.profile.state.name, "Guest") when user looses state
then user is automatically kicked from state group
and remains member of normal group and auto group
"""
# setup
state_group = Group.objects.create(name='state_group')
state_group.authgroup.states.add(self.test_state_1)
state_group.authgroup.internal = False
state_group.save()
normal_group = Group.objects.create(name='normal_group')
normal_group.authgroup.internal = False
normal_group.save()
internal_group = Group.objects.create(name='internal_group')
autogroup_config = AutogroupsConfig.objects.create(corp_groups=True)
autogroup_config.states.add(self.test_state_1)
autogroup_config.states.add(self.guest_state)
auto_group = autogroup_config.corp_managed_groups.first()
internal_state_group = Group.objects.create(name='internal_state_group')
internal_state_group.authgroup.states.add(self.test_state_1)
self.test_state_1.member_corporations.add(self.corp_1)
self.user.groups.add(normal_group)
self.user.groups.add(internal_group)
self.user.groups.add(state_group)
self.user.groups.add(internal_state_group)
self.state.member_corporations.add(self.corp) # user changes state back to guest
self._refresh_user() self.test_state_1.member_corporations.clear()
self.assertEqual(self.user.profile.state, self.state)
groups = self.user.groups.all()
self.assertIn(self.state_group, groups) #keeps group
self.assertIn(self.open_group, groups) #public group unafected
self.state.member_corporations.clear() # assert
self._refresh_user() self._refresh_user()
self.assertEqual(self.user.profile.state.name, "Guest") self.assertEqual(self.user.profile.state, self.guest_state)
groups = self.user.groups.all() groups = self.user.groups.all()
self.assertNotIn(self.state_group, groups) #looses group self.assertNotIn(state_group, groups) # looses state group
self.assertIn(self.open_group, groups) #public group unafected self.assertNotIn(internal_state_group, groups) # looses state group
self.assertIn(normal_group, groups) # normal group unafected
self.assertIn(internal_group, groups) # internal group unafected
self.assertIn(auto_group, groups) # auto group unafected
def test_change_to_other_state(self):
"""
given a state group with 2 allowed states
when user changes from one state to the other
then user remains member of that group
"""
# setup
state_group = Group.objects.create(name='state_group')
state_group.authgroup.states.add(self.test_state_1)
state_group.authgroup.states.add(self.test_state_2)
self.test_state_1.member_corporations.add(self.corp_1)
self.test_state_2.member_corporations.add(self.corp_2)
self.user.groups.add(state_group)
# user changes state back to guest
self.character.corporation_id = 2002
self.character.corporation_name = "test corp 2"
self.character.save()
# assert
self._refresh_user()
self.assertEqual(self.user.profile.state, self.test_state_2)
groups = self.user.groups.all()
self.assertIn(state_group, groups)