mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 12:30:15 +02:00
281 lines
8.8 KiB
Python
281 lines
8.8 KiB
Python
from django.apps import apps
|
|
from django.contrib import admin
|
|
|
|
from django.contrib.auth.models import Group as BaseGroup, Permission, User
|
|
from django.db.models import Count, Exists, OuterRef
|
|
from django.db.models.functions import Lower
|
|
from django.db.models.signals import (
|
|
m2m_changed,
|
|
post_delete,
|
|
post_save,
|
|
pre_delete,
|
|
pre_save
|
|
)
|
|
from django.dispatch import receiver
|
|
|
|
from .forms import GroupAdminForm, ReservedGroupNameAdminForm
|
|
from .models import AuthGroup, GroupRequest, ReservedGroupName
|
|
from .tasks import remove_users_not_matching_states_from_group
|
|
|
|
if 'eve_autogroups' in apps.app_configs:
|
|
_has_auto_groups = True
|
|
else:
|
|
_has_auto_groups = False
|
|
|
|
|
|
class AuthGroupInlineAdmin(admin.StackedInline):
|
|
model = AuthGroup
|
|
filter_horizontal = ('group_leaders', 'group_leader_groups', 'states',)
|
|
fields = (
|
|
'description',
|
|
'group_leaders',
|
|
'group_leader_groups',
|
|
'states',
|
|
'internal',
|
|
'hidden',
|
|
'open',
|
|
'public',
|
|
'restricted',
|
|
)
|
|
verbose_name_plural = 'Auth Settings'
|
|
verbose_name = ''
|
|
|
|
def formfield_for_manytomany(self, db_field, request, **kwargs):
|
|
"""overriding this formfield to have sorted lists in the form"""
|
|
if db_field.name == "group_leaders":
|
|
kwargs["queryset"] = User.objects.order_by(Lower('username'))
|
|
elif db_field.name == "group_leader_groups":
|
|
kwargs["queryset"] = Group.objects.order_by(Lower('name'))
|
|
return super().formfield_for_manytomany(db_field, request, **kwargs)
|
|
|
|
def has_delete_permission(self, request, obj=None):
|
|
return False
|
|
|
|
def has_change_permission(self, request, obj=None):
|
|
return request.user.has_perm('auth.change_group')
|
|
|
|
def get_readonly_fields(self, request, obj=None):
|
|
if not request.user.is_superuser:
|
|
return self.readonly_fields + ("restricted",)
|
|
return self.readonly_fields
|
|
|
|
|
|
if _has_auto_groups:
|
|
class IsAutoGroupFilter(admin.SimpleListFilter):
|
|
title = 'auto group'
|
|
parameter_name = 'is_auto_group__exact'
|
|
|
|
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__isnull=True,
|
|
managedcorpgroup__isnull=True
|
|
)
|
|
elif value == 'no':
|
|
return queryset.filter(
|
|
managedalliancegroup__isnull=True,
|
|
managedcorpgroup__isnull=True
|
|
)
|
|
return queryset
|
|
|
|
|
|
class HasLeaderFilter(admin.SimpleListFilter):
|
|
title = 'has leader'
|
|
parameter_name = 'has_leader__exact'
|
|
|
|
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)
|
|
return queryset
|
|
|
|
|
|
class GroupAdmin(admin.ModelAdmin):
|
|
form = GroupAdminForm
|
|
ordering = ('name',)
|
|
list_display = (
|
|
'name',
|
|
'_description',
|
|
'_properties',
|
|
'_member_count',
|
|
'has_leader',
|
|
)
|
|
list_filter = [
|
|
'authgroup__internal',
|
|
'authgroup__hidden',
|
|
'authgroup__open',
|
|
'authgroup__public',
|
|
]
|
|
if _has_auto_groups:
|
|
list_filter.append(IsAutoGroupFilter)
|
|
list_filter.append(HasLeaderFilter)
|
|
|
|
search_fields = ('name', 'authgroup__description')
|
|
|
|
def get_queryset(self, request):
|
|
qs = super().get_queryset(request)
|
|
has_leader_qs = (
|
|
AuthGroup.objects.filter(group=OuterRef('pk'), group_leaders__isnull=False)
|
|
)
|
|
has_leader_groups_qs = (
|
|
AuthGroup.objects.filter(
|
|
group=OuterRef('pk'), group_leader_groups__isnull=False
|
|
)
|
|
)
|
|
qs = (
|
|
qs.select_related('authgroup')
|
|
.annotate(member_count=Count('user', distinct=True))
|
|
.annotate(has_leader=Exists(has_leader_qs))
|
|
.annotate(has_leader_groups=Exists(has_leader_groups_qs))
|
|
)
|
|
if _has_auto_groups:
|
|
is_autogroup_corp = (
|
|
Group.objects.filter(
|
|
pk=OuterRef('pk'), managedcorpgroup__isnull=False
|
|
)
|
|
)
|
|
is_autogroup_alliance = (
|
|
Group.objects.filter(
|
|
pk=OuterRef('pk'), managedalliancegroup__isnull=False
|
|
)
|
|
)
|
|
qs = (
|
|
qs.annotate(is_autogroup_corp=Exists(is_autogroup_corp))
|
|
.annotate(is_autogroup_alliance=Exists(is_autogroup_alliance))
|
|
)
|
|
return qs
|
|
|
|
def _description(self, obj):
|
|
return obj.authgroup.description
|
|
|
|
@admin.display(description='Members', ordering='member_count')
|
|
def _member_count(self, obj):
|
|
return obj.member_count
|
|
|
|
@admin.display(boolean=True)
|
|
def has_leader(self, obj):
|
|
return obj.has_leader or obj.has_leader_groups
|
|
|
|
def _properties(self, obj):
|
|
properties = list()
|
|
if _has_auto_groups and (obj.is_autogroup_corp or obj.is_autogroup_alliance):
|
|
properties.append('Auto Group')
|
|
elif obj.authgroup.internal:
|
|
properties.append('Internal')
|
|
else:
|
|
if obj.authgroup.hidden:
|
|
properties.append('Hidden')
|
|
if obj.authgroup.open:
|
|
properties.append('Open')
|
|
if obj.authgroup.public:
|
|
properties.append('Public')
|
|
if not properties:
|
|
properties.append('Default')
|
|
if obj.authgroup.restricted:
|
|
properties.append('Restricted')
|
|
return properties
|
|
|
|
filter_horizontal = ('permissions',)
|
|
inlines = (AuthGroupInlineAdmin,)
|
|
|
|
def formfield_for_manytomany(self, db_field, request, **kwargs):
|
|
if db_field.name == "permissions":
|
|
kwargs["queryset"] = Permission.objects.select_related("content_type").all()
|
|
return super().formfield_for_manytomany(db_field, request, **kwargs)
|
|
|
|
def save_formset(self, request, form, formset, change):
|
|
for inline_form in formset:
|
|
ag_instance = inline_form.save(commit=False)
|
|
ag_instance.group = form.instance
|
|
ag_instance.save()
|
|
if ag_instance.states.exists():
|
|
remove_users_not_matching_states_from_group.delay(ag_instance.group.pk)
|
|
formset.save()
|
|
|
|
def get_readonly_fields(self, request, obj=None):
|
|
if not request.user.is_superuser:
|
|
return self.readonly_fields + ("permissions",)
|
|
return self.readonly_fields
|
|
|
|
|
|
class Group(BaseGroup):
|
|
class Meta:
|
|
proxy = True
|
|
verbose_name = BaseGroup._meta.verbose_name
|
|
verbose_name_plural = BaseGroup._meta.verbose_name_plural
|
|
|
|
|
|
try:
|
|
admin.site.unregister(BaseGroup)
|
|
finally:
|
|
admin.site.register(Group, GroupAdmin)
|
|
|
|
|
|
@admin.register(GroupRequest)
|
|
class GroupRequestAdmin(admin.ModelAdmin):
|
|
search_fields = ('user__username', )
|
|
list_display = ('id', 'group', 'user', '_leave_request')
|
|
list_filter = (
|
|
('group', admin.RelatedOnlyFieldListFilter),
|
|
('user', admin.RelatedOnlyFieldListFilter),
|
|
'leave_request',
|
|
)
|
|
|
|
@admin.display(boolean=True, description="is leave request")
|
|
def _leave_request(self, obj) -> True:
|
|
return obj.leave_request
|
|
|
|
|
|
@admin.register(ReservedGroupName)
|
|
class ReservedGroupNameAdmin(admin.ModelAdmin):
|
|
form = ReservedGroupNameAdminForm
|
|
list_display = ("name", "created_by", "created_at")
|
|
|
|
def get_form(self, request, *args, **kwargs):
|
|
form = super().get_form(request, *args, **kwargs)
|
|
form.current_user = request.user
|
|
return form
|
|
|
|
def has_change_permission(self, *args, **kwargs) -> bool:
|
|
return False
|
|
|
|
|
|
@receiver(pre_save, sender=Group)
|
|
def redirect_pre_save(sender, signal=None, *args, **kwargs):
|
|
pre_save.send(BaseGroup, *args, **kwargs)
|
|
|
|
|
|
@receiver(post_save, sender=Group)
|
|
def redirect_post_save(sender, signal=None, *args, **kwargs):
|
|
post_save.send(BaseGroup, *args, **kwargs)
|
|
|
|
|
|
@receiver(pre_delete, sender=Group)
|
|
def redirect_pre_delete(sender, signal=None, *args, **kwargs):
|
|
pre_delete.send(BaseGroup, *args, **kwargs)
|
|
|
|
|
|
@receiver(post_delete, sender=Group)
|
|
def redirect_post_delete(sender, signal=None, *args, **kwargs):
|
|
post_delete.send(BaseGroup, *args, **kwargs)
|
|
|
|
|
|
@receiver(m2m_changed, sender=Group.permissions.through)
|
|
def redirect_m2m_changed_permissions(sender, signal=None, *args, **kwargs):
|
|
m2m_changed.send(BaseGroup, *args, **kwargs)
|