Adding settings for users lists, showing all auto groups in groups

This commit is contained in:
ErikKalkoken 2020-02-07 17:21:33 +01:00
parent 9d0a65a516
commit 0caac20d77
7 changed files with 241 additions and 31 deletions

View File

@ -19,6 +19,7 @@ from allianceauth.authentication.models import State, get_guest_state,\
from allianceauth.hooks import get_hooks
from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo
from allianceauth.eveonline.tasks import update_character
from .app_settings import *
if 'allianceauth.eveonline.autogroups' in settings.INSTALLED_APPS:
_has_auto_groups = True
@ -27,10 +28,6 @@ else:
_has_auto_groups = False
_USERS_MAX_GROUPS = 5
_USERS_MAX_CHARACTERS = 3
def make_service_hooks_update_groups_action(service):
"""
Make a admin action for the given service
@ -324,7 +321,10 @@ class UserAdmin(BaseUserAdmin):
.filter(user=obj)\
.order_by('character__character_name')
]
return list_2_html_w_tooltips(my_characters, _USERS_MAX_CHARACTERS)
return list_2_html_w_tooltips(
my_characters,
AUTHENTICATION_ADMIN_USERS_MAX_CHARS
)
_characters.short_description = 'characters'
@ -347,7 +347,10 @@ class UserAdmin(BaseUserAdmin):
.order_by('name')
]
return list_2_html_w_tooltips(my_groups, _USERS_MAX_GROUPS)
return list_2_html_w_tooltips(
my_groups,
AUTHENTICATION_ADMIN_USERS_MAX_GROUPS
)
_groups.short_description = 'groups'

View File

@ -0,0 +1,46 @@
from django.conf import settings
def _clean_setting(
name: str,
default_value: object,
min_value: int = None,
max_value: int = None,
required_type: type = None
):
"""cleans the input for a custom setting
Will use `default_value` if settings does not exit or has the wrong type
or is outside define boundaries (for int only)
Need to define `required_type` if `default_value` is `None`
Will assume `min_value` of 0 for int (can be overriden)
Returns cleaned value for setting
"""
if default_value is None and not required_type:
raise ValueError('You must specify a required_type for None defaults')
if not required_type:
required_type = type(default_value)
if min_value is None and required_type == int:
min_value = 0
if (hasattr(settings, name)
and isinstance(getattr(settings, name), required_type)
and (min_value is None or getattr(settings, name) >= min_value)
and (max_value is None or getattr(settings, name) <= max_value)
):
return getattr(settings, name)
else:
return default_value
AUTHENTICATION_ADMIN_USERS_MAX_GROUPS = \
_clean_setting('AUTHENTICATION_ADMIN_USERS_MAX_GROUPS', 10)
AUTHENTICATION_ADMIN_USERS_MAX_CHARS = \
_clean_setting('AUTHENTICATION_ADMIN_USERS_MAX_CHARS', 5)

View File

@ -2,6 +2,7 @@
CSS for allianceauth admin site
*/
/* styling for profile pic */
.img-circle { border-radius: 50%; }
.column-_profile_pic { width: 50px; }

View File

@ -1,23 +1,28 @@
from unittest import mock
from io import StringIO
from django.test import TestCase
from django.contrib.auth.models import User
from allianceauth.tests.auth_utils import AuthUtils
from .models import CharacterOwnership, UserProfile, State, get_guest_state, OwnershipRecord
from .backends import StateBackend
from .tasks import check_character_ownership
from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo
from esi.models import Token
from esi.errors import IncompleteResponseError
from allianceauth.authentication.decorators import main_character_required
from django.test.client import RequestFactory
from django.http.response import HttpResponse
from django.contrib.auth.models import AnonymousUser
from django.conf import settings
from django.shortcuts import reverse
from django.core.management import call_command
from urllib import parse
from django.conf import settings
from django.contrib.auth.models import AnonymousUser, User
from django.core.management import call_command
from django.http.response import HttpResponse
from django.shortcuts import reverse
from django.test import TestCase
from django.test.client import RequestFactory
from allianceauth.authentication.decorators import main_character_required
from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo,\
EveAllianceInfo
from allianceauth.tests.auth_utils import AuthUtils
from esi.errors import IncompleteResponseError
from esi.models import Token
from ..backends import StateBackend
from ..models import CharacterOwnership, UserProfile, State, get_guest_state,\
OwnershipRecord
from ..tasks import check_character_ownership
MODULE_PATH = 'allianceauth.authentication'

View File

@ -0,0 +1,108 @@
from unittest.mock import Mock, patch
from django.test import TestCase
from .. import app_settings
MODULE_PATH = 'allianceauth.authentication'
class TestSetAppSetting(TestCase):
@patch(MODULE_PATH + '.app_settings.settings')
def test_default_if_not_set(self, mock_settings):
mock_settings.TEST_SETTING_DUMMY = Mock(spec=None)
result = app_settings._clean_setting(
'TEST_SETTING_DUMMY',
False,
)
self.assertEqual(result, False)
@patch(MODULE_PATH + '.app_settings.settings')
def test_default_if_not_set_for_none(self, mock_settings):
mock_settings.TEST_SETTING_DUMMY = Mock(spec=None)
result = app_settings._clean_setting(
'TEST_SETTING_DUMMY',
None,
required_type=int
)
self.assertEqual(result, None)
@patch(MODULE_PATH + '.app_settings.settings')
def test_true_stays_true(self, mock_settings):
mock_settings.TEST_SETTING_DUMMY = True
result = app_settings._clean_setting(
'TEST_SETTING_DUMMY',
False,
)
self.assertEqual(result, True)
@patch(MODULE_PATH + '.app_settings.settings')
def test_false_stays_false(self, mock_settings):
mock_settings.TEST_SETTING_DUMMY = False
result = app_settings._clean_setting(
'TEST_SETTING_DUMMY',
False
)
self.assertEqual(result, False)
@patch(MODULE_PATH + '.app_settings.settings')
def test_default_for_invalid_type_bool(self, mock_settings):
mock_settings.TEST_SETTING_DUMMY = 'invalid type'
result = app_settings._clean_setting(
'TEST_SETTING_DUMMY',
False
)
self.assertEqual(result, False)
@patch(MODULE_PATH + '.app_settings.settings')
def test_default_for_invalid_type_int(self, mock_settings):
mock_settings.TEST_SETTING_DUMMY = 'invalid type'
result = app_settings._clean_setting(
'TEST_SETTING_DUMMY',
50
)
self.assertEqual(result, 50)
@patch(MODULE_PATH + '.app_settings.settings')
def test_default_if_below_minimum_1(self, mock_settings):
mock_settings.TEST_SETTING_DUMMY = -5
result = app_settings._clean_setting(
'TEST_SETTING_DUMMY',
default_value=50
)
self.assertEqual(result, 50)
@patch(MODULE_PATH + '.app_settings.settings')
def test_default_if_below_minimum_2(self, mock_settings):
mock_settings.TEST_SETTING_DUMMY = -50
result = app_settings._clean_setting(
'TEST_SETTING_DUMMY',
default_value=50,
min_value=-10
)
self.assertEqual(result, 50)
@patch(MODULE_PATH + '.app_settings.settings')
def test_default_for_invalid_type_int(self, mock_settings):
mock_settings.TEST_SETTING_DUMMY = 1000
result = app_settings._clean_setting(
'TEST_SETTING_DUMMY',
default_value=50,
max_value=100
)
self.assertEqual(result, 50)
@patch(MODULE_PATH + '.app_settings.settings')
def test_default_is_none_needs_required_type(self, mock_settings):
mock_settings.TEST_SETTING_DUMMY = 'invalid type'
with self.assertRaises(ValueError):
result = app_settings._clean_setting(
'TEST_SETTING_DUMMY',
default_value=None
)

View File

@ -35,6 +35,49 @@ class AuthGroupInlineAdmin(admin.StackedInline):
return request.user.has_perm('auth.change_group')
if _has_auto_groups:
class IsAutoGroupFilter(admin.SimpleListFilter):
title = 'auto group'
parameter_name = 'auto_group'
def lookups(self, request, model_admin):
return (
('Yes', 'Yes'),
('No', 'No'),
)
def queryset(self, request, queryset):
value = self.value()
if value == 'Yes':
return queryset.exclude(
managedalliancegroup__exact=None,
managedcorpgroup__exact=None
)
elif value == 'No':
return queryset.filter(managedalliancegroup__exact=None).filter(managedcorpgroup__exact=None)
else:
return queryset
class HasLeaderFilter(admin.SimpleListFilter):
title = 'has leader'
parameter_name = 'has_leader'
def lookups(self, request, model_admin):
return (
('Yes', 'Yes'),
('No', 'No'),
)
def queryset(self, request, queryset):
value = self.value()
if value == 'Yes':
return queryset.filter(authgroup__group_leaders__isnull=False)
elif value == 'No':
return queryset.filter(authgroup__group_leaders__isnull=True)
else:
return queryset
class GroupAdmin(admin.ModelAdmin):
list_select_related = True
ordering = ('name', )
@ -50,7 +93,9 @@ class GroupAdmin(admin.ModelAdmin):
'authgroup__internal',
'authgroup__hidden',
'authgroup__open',
'authgroup__public'
'authgroup__public',
IsAutoGroupFilter,
HasLeaderFilter
)
search_fields = ('name', 'authgroup__description')
@ -58,13 +103,9 @@ class GroupAdmin(admin.ModelAdmin):
inlines = (AuthGroupInlineAdmin,)
def get_queryset(self, request):
qs = super().get_queryset(request)
if _has_auto_groups:
qs = qs\
.filter(managedalliancegroup__exact=None)\
.filter(managedcorpgroup__exact=None)
qs = super().get_queryset(request)
qs = qs.annotate(
member_count=Count('user', distinct=True),
member_count=Count('user', distinct=True),
)
return qs
@ -80,11 +121,17 @@ class GroupAdmin(admin.ModelAdmin):
def has_leader(self, obj):
return obj.authgroup.group_leaders.exists()
has_leader.boolean = True
has_leader.boolean = True
def _properties(self, obj):
properties = list()
if obj.authgroup.internal:
if _has_auto_groups and (
obj.managedalliancegroup_set.exists()
or obj.managedcorpgroup_set.exists()
):
properties.append('Auto Group')
elif obj.authgroup.internal:
properties.append('Internal')
else:
if obj.authgroup.hidden: