Merge branch 'feature_admin_update' into 'master'

Improve admin site lists for users, groups and service users

See merge request allianceauth/allianceauth!1164
This commit is contained in:
Ariel Rin
2020-02-18 08:34:19 +00:00
26 changed files with 2145 additions and 282 deletions

View File

@@ -1,9 +1,50 @@
from django.contrib import admin
from django import forms
from django.contrib import admin
from django.db.models.functions import Lower
from django.urls import reverse
from django.utils.html import format_html
from allianceauth import hooks
from allianceauth.eveonline.models import EveCharacter
from allianceauth.authentication.admin import user_profile_pic, \
user_username, user_main_organization, MainCorporationsFilter,\
MainAllianceFilter
from .models import NameFormatConfig
class ServicesUserAdmin(admin.ModelAdmin):
"""Parent class for UserAdmin classes for all services"""
class Media:
css = {
"all": ("services/admin.css",)
}
search_fields = (
'user__username',
'uid'
)
ordering = ('user__username', )
list_select_related = True
list_display = (
user_profile_pic,
user_username,
user_main_organization,
'_date_joined'
)
list_filter = (
MainCorporationsFilter,
MainAllianceFilter,
'user__date_joined'
)
def _date_joined(self, obj):
return obj.user.date_joined
_date_joined.short_description = 'date joined'
_date_joined.admin_order_field = 'user__date_joined'
class NameFormatConfigForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(NameFormatConfigForm, self).__init__(*args, **kwargs)

View File

@@ -1,9 +1,18 @@
from django.contrib import admin
from .models import DiscordUser
from ...admin import ServicesUserAdmin
class DiscordUserAdmin(admin.ModelAdmin):
list_display = ('user', 'uid')
search_fields = ('user__username', 'uid')
@admin.register(DiscordUser)
class DiscordUserAdmin(ServicesUserAdmin):
list_display = ServicesUserAdmin.list_display + (
'_uid',
)
def _uid(self, obj):
return obj.uid
_uid.short_description = 'Discord ID (UID)'
_uid.admin_order_field = 'uid'
admin.site.register(DiscordUser, DiscordUserAdmin)

View File

@@ -0,0 +1,10 @@
from django.contrib.auth.models import User, Group, Permission
from allianceauth.tests.auth_utils import AuthUtils
DEFAULT_AUTH_GROUP = 'Member'
MODULE_PATH = 'allianceauth.services.modules.discord'
def add_permissions():
permission = Permission.objects.get(codename='access_discord')
members = Group.objects.get_or_create(name=DEFAULT_AUTH_GROUP)[0]
AuthUtils.add_permissions_to_groups([permission], [members])

View File

@@ -0,0 +1,268 @@
from unittest.mock import patch
from django.test import TestCase, RequestFactory
from django.contrib import admin
from django.contrib.admin.sites import AdminSite
from django.contrib.auth.models import User
from allianceauth.authentication.models import CharacterOwnership
from allianceauth.eveonline.models import (
EveCharacter, EveCorporationInfo, EveAllianceInfo
)
from ....admin import (
user_profile_pic,
user_username,
user_main_organization,
ServicesUserAdmin,
MainCorporationsFilter,
MainAllianceFilter
)
from ..admin import (
DiscordUser,
DiscordUserAdmin
)
class TestDiscordUserAdmin(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
# user 1 - corp and alliance, normal user
cls.character_1 = EveCharacter.objects.create(
character_id='1001',
character_name='Bruce Wayne',
corporation_id='2001',
corporation_name='Wayne Technologies',
corporation_ticker='WT',
alliance_id='3001',
alliance_name='Wayne Enterprises',
alliance_ticker='WE',
)
cls.character_1a = EveCharacter.objects.create(
character_id='1002',
character_name='Batman',
corporation_id='2001',
corporation_name='Wayne Technologies',
corporation_ticker='WT',
alliance_id='3001',
alliance_name='Wayne Enterprises',
alliance_ticker='WE',
)
alliance = EveAllianceInfo.objects.create(
alliance_id='3001',
alliance_name='Wayne Enterprises',
alliance_ticker='WE',
executor_corp_id='2001'
)
EveCorporationInfo.objects.create(
corporation_id='2001',
corporation_name='Wayne Technologies',
corporation_ticker='WT',
member_count=42,
alliance=alliance
)
cls.user_1 = User.objects.create_user(
cls.character_1.character_name.replace(' ', '_'),
'abc@example.com',
'password'
)
CharacterOwnership.objects.create(
character=cls.character_1,
owner_hash='x1' + cls.character_1.character_name,
user=cls.user_1
)
CharacterOwnership.objects.create(
character=cls.character_1a,
owner_hash='x1' + cls.character_1a.character_name,
user=cls.user_1
)
cls.user_1.profile.main_character = cls.character_1
cls.user_1.profile.save()
DiscordUser.objects.create(
user=cls.user_1,
uid=1001
)
# user 2 - corp only, staff
cls.character_2 = EveCharacter.objects.create(
character_id=1003,
character_name='Clark Kent',
corporation_id=2002,
corporation_name='Daily Planet',
corporation_ticker='DP',
alliance_id=None
)
EveCorporationInfo.objects.create(
corporation_id=2002,
corporation_name='Daily Plane',
corporation_ticker='DP',
member_count=99,
alliance=None
)
cls.user_2 = User.objects.create_user(
cls.character_2.character_name.replace(' ', '_'),
'abc@example.com',
'password'
)
CharacterOwnership.objects.create(
character=cls.character_2,
owner_hash='x1' + cls.character_2.character_name,
user=cls.user_2
)
cls.user_2.profile.main_character = cls.character_2
cls.user_2.profile.save()
DiscordUser.objects.create(
user=cls.user_2,
uid=1002
)
# user 3 - no main, no group, superuser
cls.character_3 = EveCharacter.objects.create(
character_id=1101,
character_name='Lex Luthor',
corporation_id=2101,
corporation_name='Lex Corp',
corporation_ticker='LC',
alliance_id=None
)
EveCorporationInfo.objects.create(
corporation_id=2101,
corporation_name='Lex Corp',
corporation_ticker='LC',
member_count=666,
alliance=None
)
EveAllianceInfo.objects.create(
alliance_id='3101',
alliance_name='Lex World Domination',
alliance_ticker='LWD',
executor_corp_id=''
)
cls.user_3 = User.objects.create_user(
cls.character_3.character_name.replace(' ', '_'),
'abc@example.com',
'password'
)
CharacterOwnership.objects.create(
character=cls.character_3,
owner_hash='x1' + cls.character_3.character_name,
user=cls.user_3
)
DiscordUser.objects.create(
user=cls.user_3,
uid=1003
)
def setUp(self):
self.factory = RequestFactory()
self.modeladmin = DiscordUserAdmin(
model=DiscordUser, admin_site=AdminSite()
)
# column rendering
def test_user_profile_pic_u1(self):
expected = ('<img src="https://images.evetech.net/characters/1001/'
'portrait?size=32" class="img-circle">')
self.assertEqual(user_profile_pic(self.user_1.discord), expected)
def test_user_profile_pic_u3(self):
self.assertIsNone(user_profile_pic(self.user_3.discord))
def test_user_username_u1(self):
expected = (
'<strong><a href="/admin/discord/discorduser/{}/change/">'
'Bruce_Wayne</a></strong><br>Bruce Wayne'.format(
self.user_1.discord.pk
)
)
self.assertEqual(user_username(self.user_1.discord), expected)
def test_user_username_u3(self):
expected = (
'<strong><a href="/admin/discord/discorduser/{}/change/">'
'Lex_Luthor</a></strong>'.format(self.user_3.discord.pk)
)
self.assertEqual(user_username(self.user_3.discord), expected)
def test_user_main_organization_u1(self):
expected = 'Wayne Technologies<br>Wayne Enterprises'
result = user_main_organization(self.user_1.discord)
self.assertEqual(result, expected)
def test_user_main_organization_u2(self):
expected = 'Daily Planet'
result = user_main_organization(self.user_2.discord)
self.assertEqual(result, expected)
def test_user_main_organization_u3(self):
expected = None
result = user_main_organization(self.user_3.discord)
self.assertEqual(result, expected)
# actions
# filters
def test_filter_main_corporations(self):
class DiscordUserAdminTest(ServicesUserAdmin):
list_filter = (MainCorporationsFilter,)
my_modeladmin = DiscordUserAdminTest(DiscordUser, AdminSite())
# Make sure the lookups are correct
request = self.factory.get('/')
request.user = self.user_1
changelist = my_modeladmin.get_changelist_instance(request)
filters = changelist.get_filters(request)
filterspec = filters[0][0]
expected = [
('2002', 'Daily Planet'),
('2001', 'Wayne Technologies'),
]
self.assertEqual(filterspec.lookup_choices, expected)
# Make sure the correct queryset is returned
request = self.factory.get(
'/',
{'main_corporation_id__exact': self.character_1.corporation_id}
)
request.user = self.user_1
changelist = my_modeladmin.get_changelist_instance(request)
queryset = changelist.get_queryset(request)
expected = [self.user_1.discord]
self.assertSetEqual(set(queryset), set(expected))
def test_filter_main_alliances(self):
class DiscordUserAdminTest(ServicesUserAdmin):
list_filter = (MainAllianceFilter,)
my_modeladmin = DiscordUserAdminTest(DiscordUser, AdminSite())
# Make sure the lookups are correct
request = self.factory.get('/')
request.user = self.user_1
changelist = my_modeladmin.get_changelist_instance(request)
filters = changelist.get_filters(request)
filterspec = filters[0][0]
expected = [
('3001', 'Wayne Enterprises'),
]
self.assertEqual(filterspec.lookup_choices, expected)
# Make sure the correct queryset is returned
request = self.factory.get(
'/',
{'main_alliance_id__exact': self.character_1.alliance_id}
)
request.user = self.user_1
changelist = my_modeladmin.get_changelist_instance(request)
queryset = changelist.get_queryset(request)
expected = [self.user_1.discord]
self.assertSetEqual(set(queryset), set(expected))

View File

@@ -0,0 +1,127 @@
from unittest import mock
from django.test import TestCase, RequestFactory
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from allianceauth.tests.auth_utils import AuthUtils
from ..auth_hooks import DiscordService
from ..models import DiscordUser
from ..tasks import DiscordTasks
from ..manager import DiscordOAuthManager
from . import DEFAULT_AUTH_GROUP, add_permissions, MODULE_PATH
class DiscordHooksTestCase(TestCase):
def setUp(self):
self.member = 'member_user'
member = AuthUtils.create_member(self.member)
DiscordUser.objects.create(user=member, uid='12345')
self.none_user = 'none_user'
none_user = AuthUtils.create_user(self.none_user)
self.service = DiscordService
add_permissions()
def test_has_account(self):
member = User.objects.get(username=self.member)
none_user = User.objects.get(username=self.none_user)
self.assertTrue(DiscordTasks.has_account(member))
self.assertFalse(DiscordTasks.has_account(none_user))
def test_service_enabled(self):
service = self.service()
member = User.objects.get(username=self.member)
none_user = User.objects.get(username=self.none_user)
self.assertTrue(service.service_active_for_user(member))
self.assertFalse(service.service_active_for_user(none_user))
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_update_all_groups(self, manager):
service = self.service()
service.update_all_groups()
# Check member and blue user have groups updated
self.assertTrue(manager.update_groups.called)
self.assertEqual(manager.update_groups.call_count, 1)
def test_update_groups(self):
# Check member has Member group updated
with mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') as manager:
service = self.service()
member = User.objects.get(username=self.member)
AuthUtils.disconnect_signals()
service.update_groups(member)
self.assertTrue(manager.update_groups.called)
args, kwargs = manager.update_groups.call_args
user_id, groups = args
self.assertIn(DEFAULT_AUTH_GROUP, groups)
self.assertEqual(user_id, member.discord.uid)
# Check none user does not have groups updated
with mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') as manager:
service = self.service()
none_user = User.objects.get(username=self.none_user)
service.update_groups(none_user)
self.assertFalse(manager.update_groups.called)
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_validate_user(self, manager):
service = self.service()
# Test member is not deleted
member = User.objects.get(username=self.member)
service.validate_user(member)
self.assertTrue(member.discord)
# Test none user is deleted
none_user = User.objects.get(username=self.none_user)
DiscordUser.objects.create(user=none_user, uid='abc123')
service.validate_user(none_user)
self.assertTrue(manager.delete_user.called)
with self.assertRaises(ObjectDoesNotExist):
none_discord = User.objects.get(username=self.none_user).discord
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_sync_nickname(self, manager):
service = self.service()
member = User.objects.get(username=self.member)
AuthUtils.add_main_character(member, 'test user', '12345', corp_ticker='AAUTH')
service.sync_nickname(member)
self.assertTrue(manager.update_nickname.called)
args, kwargs = manager.update_nickname.call_args
self.assertEqual(args[0], member.discord.uid)
self.assertEqual(args[1], 'test user')
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_delete_user(self, manager):
member = User.objects.get(username=self.member)
service = self.service()
result = service.delete_user(member)
self.assertTrue(result)
self.assertTrue(manager.delete_user.called)
with self.assertRaises(ObjectDoesNotExist):
discord_user = User.objects.get(username=self.member).discord
def test_render_services_ctrl(self):
service = self.service()
member = User.objects.get(username=self.member)
request = RequestFactory().get('/services/')
request.user = member
response = service.render_services_ctrl(request)
self.assertTemplateUsed(service.service_ctrl_template)
self.assertIn('/discord/reset/', response)
self.assertIn('/discord/deactivate/', response)
# Test register becomes available
member.discord.delete()
member = User.objects.get(username=self.member)
request.user = member
response = service.render_services_ctrl(request)
self.assertIn('/discord/activate/', response)
# TODO: Test update nicknames

View File

@@ -2,197 +2,15 @@ import json
import urllib
import datetime
import requests_mock
from django_webtest import WebTest
from unittest import mock
from django.test import TestCase, RequestFactory
from django.contrib.auth.models import User, Group, Permission
from django.core.exceptions import ObjectDoesNotExist
from django.test import TestCase
from django.conf import settings
from allianceauth.tests.auth_utils import AuthUtils
from .auth_hooks import DiscordService
from .models import DiscordUser
from .tasks import DiscordTasks
from .manager import DiscordOAuthManager
from . import manager
from ..manager import DiscordOAuthManager
from .. import manager
MODULE_PATH = 'allianceauth.services.modules.discord'
DEFAULT_AUTH_GROUP = 'Member'
def add_permissions():
permission = Permission.objects.get(codename='access_discord')
members = Group.objects.get_or_create(name=DEFAULT_AUTH_GROUP)[0]
AuthUtils.add_permissions_to_groups([permission], [members])
class DiscordHooksTestCase(TestCase):
def setUp(self):
self.member = 'member_user'
member = AuthUtils.create_member(self.member)
DiscordUser.objects.create(user=member, uid='12345')
self.none_user = 'none_user'
none_user = AuthUtils.create_user(self.none_user)
self.service = DiscordService
add_permissions()
def test_has_account(self):
member = User.objects.get(username=self.member)
none_user = User.objects.get(username=self.none_user)
self.assertTrue(DiscordTasks.has_account(member))
self.assertFalse(DiscordTasks.has_account(none_user))
def test_service_enabled(self):
service = self.service()
member = User.objects.get(username=self.member)
none_user = User.objects.get(username=self.none_user)
self.assertTrue(service.service_active_for_user(member))
self.assertFalse(service.service_active_for_user(none_user))
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_update_all_groups(self, manager):
service = self.service()
service.update_all_groups()
# Check member and blue user have groups updated
self.assertTrue(manager.update_groups.called)
self.assertEqual(manager.update_groups.call_count, 1)
def test_update_groups(self):
# Check member has Member group updated
with mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') as manager:
service = self.service()
member = User.objects.get(username=self.member)
AuthUtils.disconnect_signals()
service.update_groups(member)
self.assertTrue(manager.update_groups.called)
args, kwargs = manager.update_groups.call_args
user_id, groups = args
self.assertIn(DEFAULT_AUTH_GROUP, groups)
self.assertEqual(user_id, member.discord.uid)
# Check none user does not have groups updated
with mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') as manager:
service = self.service()
none_user = User.objects.get(username=self.none_user)
service.update_groups(none_user)
self.assertFalse(manager.update_groups.called)
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_validate_user(self, manager):
service = self.service()
# Test member is not deleted
member = User.objects.get(username=self.member)
service.validate_user(member)
self.assertTrue(member.discord)
# Test none user is deleted
none_user = User.objects.get(username=self.none_user)
DiscordUser.objects.create(user=none_user, uid='abc123')
service.validate_user(none_user)
self.assertTrue(manager.delete_user.called)
with self.assertRaises(ObjectDoesNotExist):
none_discord = User.objects.get(username=self.none_user).discord
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_sync_nickname(self, manager):
service = self.service()
member = User.objects.get(username=self.member)
AuthUtils.add_main_character(member, 'test user', '12345', corp_ticker='AAUTH')
service.sync_nickname(member)
self.assertTrue(manager.update_nickname.called)
args, kwargs = manager.update_nickname.call_args
self.assertEqual(args[0], member.discord.uid)
self.assertEqual(args[1], 'test user')
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_delete_user(self, manager):
member = User.objects.get(username=self.member)
service = self.service()
result = service.delete_user(member)
self.assertTrue(result)
self.assertTrue(manager.delete_user.called)
with self.assertRaises(ObjectDoesNotExist):
discord_user = User.objects.get(username=self.member).discord
def test_render_services_ctrl(self):
service = self.service()
member = User.objects.get(username=self.member)
request = RequestFactory().get('/services/')
request.user = member
response = service.render_services_ctrl(request)
self.assertTemplateUsed(service.service_ctrl_template)
self.assertIn('/discord/reset/', response)
self.assertIn('/discord/deactivate/', response)
# Test register becomes available
member.discord.delete()
member = User.objects.get(username=self.member)
request.user = member
response = service.render_services_ctrl(request)
self.assertIn('/discord/activate/', response)
# TODO: Test update nicknames
class DiscordViewsTestCase(WebTest):
def setUp(self):
self.member = AuthUtils.create_member('auth_member')
AuthUtils.add_main_character(self.member, 'test character', '1234', '2345', 'test corp', 'testc')
add_permissions()
def login(self):
self.app.set_user(self.member)
@mock.patch(MODULE_PATH + '.views.DiscordOAuthManager')
def test_activate(self, manager):
self.login()
manager.generate_oauth_redirect_url.return_value = '/example.com/oauth/'
response = self.app.get('/discord/activate/', auto_follow=False)
self.assertRedirects(response, expected_url='/example.com/oauth/', target_status_code=404)
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_callback(self, manager):
self.login()
manager.add_user.return_value = '1234'
response = self.app.get('/discord/callback/', params={'code': '1234'})
self.member = User.objects.get(pk=self.member.pk)
self.assertTrue(manager.add_user.called)
self.assertEqual(manager.update_nickname.called, settings.DISCORD_SYNC_NAMES)
self.assertEqual(self.member.discord.uid, '1234')
self.assertRedirects(response, expected_url='/services/', target_status_code=200)
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_reset(self, manager):
self.login()
DiscordUser.objects.create(user=self.member, uid='12345')
manager.delete_user.return_value = True
response = self.app.get('/discord/reset/')
self.assertRedirects(response, expected_url='/discord/activate/', target_status_code=302)
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_deactivate(self, manager):
self.login()
DiscordUser.objects.create(user=self.member, uid='12345')
manager.delete_user.return_value = True
response = self.app.get('/discord/deactivate/')
self.assertTrue(manager.delete_user.called)
self.assertRedirects(response, expected_url='/services/', target_status_code=200)
with self.assertRaises(ObjectDoesNotExist):
discord_user = User.objects.get(pk=self.member.pk).discord
from . import DEFAULT_AUTH_GROUP, add_permissions, MODULE_PATH
class DiscordManagerTestCase(TestCase):

View File

@@ -0,0 +1,66 @@
from django_webtest import WebTest
from unittest import mock
from django.test import TestCase
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
from allianceauth.tests.auth_utils import AuthUtils
from ..models import DiscordUser
from ..manager import DiscordOAuthManager
from . import DEFAULT_AUTH_GROUP, add_permissions, MODULE_PATH
class DiscordViewsTestCase(WebTest):
def setUp(self):
self.member = AuthUtils.create_member('auth_member')
AuthUtils.add_main_character(self.member, 'test character', '1234', '2345', 'test corp', 'testc')
add_permissions()
def login(self):
self.app.set_user(self.member)
@mock.patch(MODULE_PATH + '.views.DiscordOAuthManager')
def test_activate(self, manager):
self.login()
manager.generate_oauth_redirect_url.return_value = '/example.com/oauth/'
response = self.app.get('/discord/activate/', auto_follow=False)
self.assertRedirects(response, expected_url='/example.com/oauth/', target_status_code=404)
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_callback(self, manager):
self.login()
manager.add_user.return_value = '1234'
response = self.app.get('/discord/callback/', params={'code': '1234'})
self.member = User.objects.get(pk=self.member.pk)
self.assertTrue(manager.add_user.called)
self.assertEqual(manager.update_nickname.called, settings.DISCORD_SYNC_NAMES)
self.assertEqual(self.member.discord.uid, '1234')
self.assertRedirects(response, expected_url='/services/', target_status_code=200)
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_reset(self, manager):
self.login()
DiscordUser.objects.create(user=self.member, uid='12345')
manager.delete_user.return_value = True
response = self.app.get('/discord/reset/')
self.assertRedirects(response, expected_url='/discord/activate/', target_status_code=302)
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_deactivate(self, manager):
self.login()
DiscordUser.objects.create(user=self.member, uid='12345')
manager.delete_user.return_value = True
response = self.app.get('/discord/deactivate/')
self.assertTrue(manager.delete_user.called)
self.assertRedirects(response, expected_url='/services/', target_status_code=200)
with self.assertRaises(ObjectDoesNotExist):
discord_user = User.objects.get(pk=self.member.pk).discord

View File

@@ -1,9 +1,11 @@
from django.contrib import admin
from .models import DiscourseUser
from ...admin import ServicesUserAdmin
class DiscourseUserAdmin(admin.ModelAdmin):
list_display = ('user',)
search_fields = ('user__username',)
admin.site.register(DiscourseUser, DiscourseUserAdmin)
@admin.register(DiscourseUser)
class DiscourseUserAdmin(ServicesUserAdmin):
list_display = ServicesUserAdmin.list_display + (
'enabled',
)

View File

@@ -1,10 +1,18 @@
from django.contrib import admin
from .models import MumbleUser
from ...admin import ServicesUserAdmin
class MumbleUserAdmin(admin.ModelAdmin):
fields = ('user', 'username', 'groups') # pwhash is hidden from admin panel
list_display = ('user', 'username', 'groups')
search_fields = ('user__username', 'username', 'groups')
@admin.register(MumbleUser)
class MumbleUserAdmin(ServicesUserAdmin):
list_display = ServicesUserAdmin.list_display + (
'username',
'groups',
)
search_fields = ServicesUserAdmin.search_fields + (
'username',
'groups'
)
admin.site.register(MumbleUser, MumbleUserAdmin)
fields = ('user', 'username', 'groups') # pwhash is hidden from admin panel

View File

@@ -1,9 +1,11 @@
from django.contrib import admin
from .models import OpenfireUser
from ...admin import ServicesUserAdmin
class OpenfireUserAdmin(admin.ModelAdmin):
list_display = ('user', 'username')
search_fields = ('user__username', 'username')
@admin.register(OpenfireUser)
class OpenfireUserAdmin(ServicesUserAdmin):
list_display = ServicesUserAdmin.list_display + ('username',)
search_fields = ServicesUserAdmin.search_fields + ('username', )
admin.site.register(OpenfireUser, OpenfireUserAdmin)

View File

@@ -1,9 +1,9 @@
from django.contrib import admin
from .models import Phpbb3User
from ...admin import ServicesUserAdmin
class Phpbb3UserAdmin(admin.ModelAdmin):
list_display = ('user', 'username')
search_fields = ('user__username', 'username')
admin.site.register(Phpbb3User, Phpbb3UserAdmin)
@admin.register(Phpbb3User)
class Phpbb3UserAdmin(ServicesUserAdmin):
list_display = ServicesUserAdmin.list_display + ('username',)
search_fields = ServicesUserAdmin.search_fields + ('username', )

View File

@@ -1,9 +1,10 @@
from django.contrib import admin
from .models import SmfUser
from ...admin import ServicesUserAdmin
class SmfUserAdmin(admin.ModelAdmin):
list_display = ('user', 'username')
search_fields = ('user__username', 'username')
admin.site.register(SmfUser, SmfUserAdmin)
@admin.register(SmfUser)
class SmfUserAdmin(ServicesUserAdmin):
list_display = ServicesUserAdmin.list_display + ('username',)
search_fields = ServicesUserAdmin.search_fields + ('username', )

View File

@@ -1,22 +1,36 @@
from django.contrib import admin
from .models import AuthTS, Teamspeak3User, StateGroup
from ...admin import ServicesUserAdmin
class Teamspeak3UserAdmin(admin.ModelAdmin):
list_display = ('user', 'uid', 'perm_key')
search_fields = ('user__username', 'uid', 'perm_key')
@admin.register(Teamspeak3User)
class Teamspeak3UserAdmin(ServicesUserAdmin):
list_display = ServicesUserAdmin.list_display + (
'uid',
'perm_key'
)
@admin.register(AuthTS)
class AuthTSgroupAdmin(admin.ModelAdmin):
fields = ['auth_group', 'ts_group']
ordering = ('auth_group__name', )
list_select_related = True
list_display = ('auth_group', '_ts_group')
list_filter = ('ts_group', )
fields = ('auth_group', 'ts_group')
filter_horizontal = ('ts_group',)
def _ts_group(self, obj):
return [x for x in obj.ts_group.all().order_by('ts_group_id')]
_ts_group.short_description = 'ts groups'
#_ts_group.admin_order_field = 'profile__state'
@admin.register(StateGroup)
class StateGroupAdmin(admin.ModelAdmin):
list_display = ('state', 'ts_group')
search_fields = ('state__name', 'ts_group__ts_group_name')
admin.site.register(AuthTS, AuthTSgroupAdmin)
admin.site.register(Teamspeak3User, Teamspeak3UserAdmin)

View File

@@ -1,9 +1,10 @@
from django.contrib import admin
from .models import XenforoUser
from ...admin import ServicesUserAdmin
class XenforoUserAdmin(admin.ModelAdmin):
list_display = ('user', 'username')
search_fields = ('user__username', 'username')
admin.site.register(XenforoUser, XenforoUserAdmin)
@admin.register(XenforoUser)
class XenforoUserAdmin(ServicesUserAdmin):
list_display = ServicesUserAdmin.list_display + ('username',)
search_fields = ServicesUserAdmin.search_fields + ('username', )

View File

@@ -0,0 +1,6 @@
/*
CSS for allianceauth admin site
*/
.img-circle { border-radius: 50%; }
.column-user_profile_pic { width: 50px; }