1
0
mirror of https://github.com/peeringdb/peeringdb.git synced 2024-05-11 05:55:09 +00:00

Support 202106 (#994)

* fixes #965: intermittent bug during consolidation of notifications

* fixes #863: better visibility for input validation errors

* fixes #375: re-evaluate affiliation requests on email change

* fixes #741: remove data quality validation for superusers

* fixes #587: customizable pagination in django admin

* fixes #923: Prevent deletion of a last technical contact if there is an existing netixlan object

* better search #23 (first pass)

* black format

* haystack test config to run_tests.py
remove old django_init.py test settings

* black format

* haystack test config fixes

* #23 better search (pt.2)

* rate limit distance queries (#23)
rate limiting based on query filters

* settings controlled blocking of distance filter for unauthenticated / unverified users (#23)

* fix distance filter throttling with api key auth (#23)

* fix anon user access check on distance queries

* search index and performance tweaks

* fix org_id not set in search results

* org id to int

Co-authored-by: Stefan Pratter <stefan@20c.com>
This commit is contained in:
Matt Griswold
2021-07-07 17:57:04 -05:00
committed by GitHub
parent 9f74fb8a11
commit 7c3d160dec
51 changed files with 1853 additions and 784 deletions

View File

@ -80,6 +80,7 @@ from peeringdb_server.models import (
ProtectedAction,
OrganizationAPIKey,
UserAPIKey,
GeoCoordinateCache,
)
from peeringdb_server.mail import mail_users_entity_merge
@ -362,7 +363,130 @@ def soft_delete(modeladmin, request, queryset):
soft_delete.short_description = _("SOFT DELETE")
class SanitizedAdmin:
class CustomResultLengthFilter(admin.SimpleListFilter):
"""
Filter object that enables custom result length
in django-admin change lists
This should only be used in a model admin that extends
CustomResultLengthAdmin
"""
title = _("Resul length")
parameter_name = "sz"
def lookups(self, request, model_admin):
return (
("10", _("Show {} rows").format(10)),
("25", _("Show {} rows").format(25)),
("50", _("Show {} rows").format(50)),
("100", _("Show {} rows").format(100)),
("250", _("Show {} rows").format(250)),
("all", _("Show {} rows").format("all")),
)
def queryset(self, request, queryset):
# we simply give back the queryset, since result
# length is controlled by the changelist instance
# and not the queryset
return queryset
def choices(self, changelist):
value = self.value()
if value is None:
value = f"{changelist.list_per_page}"
for lookup, title in self.lookup_choices:
yield {
"selected": value == str(lookup),
"query_string": changelist.get_query_string(
{self.parameter_name: lookup}
),
"display": title,
}
class CustomResultLengthAdmin:
def get_list_filter(self, request):
list_filter = super().get_list_filter(request)
return list_filter + (CustomResultLengthFilter,)
def get_changelist(self, request, **kwargs):
# handle the customizable result length filter
# in the django-admin change list listings (#587)
#
# this is accomplished through the `sz` url parameter
if "sz" in request.GET:
try:
sz = request.GET.get("sz")
# all currently translates to a max of 100k entries
# this is a conservative limit that should be fine for
# the time being (possible performance concerns going
# bigger than that)
if sz == "all":
sz = request.list_max_show_all = 100000
else:
sz = int(sz)
except TypeError:
# value could not be converted to integer
# fall back to default
sz = self.list_per_page
else:
sz = self.list_per_page
request.list_per_page = sz
return super().get_changelist(request, **kwargs)
def get_changelist_instance(self, request):
"""
Return a `ChangeList` instance based on `request`. May raise
`IncorrectLookupParameters`.
This is copied from the original function in the dango source
for 2.2
We override it here so we can set the list_per_page and list_max_show_all
values on the ChangeList accordingly.
"""
list_display = self.get_list_display(request)
list_display_links = self.get_list_display_links(request, list_display)
# Add the action checkboxes if any actions are available.
if self.get_actions(request):
list_display = ["action_checkbox", *list_display]
sortable_by = self.get_sortable_by(request)
ChangeList = self.get_changelist(request)
list_per_page = getattr(request, "list_per_page", self.list_per_page)
list_max_show_all = getattr(
request, "list_max_show_all", self.list_max_show_all
)
cl = ChangeList(
request,
self.model,
list_display,
list_display_links,
self.get_list_filter(request),
self.date_hierarchy,
self.get_search_fields(request),
self.get_list_select_related(request),
list_per_page,
list_max_show_all,
self.list_editable,
self,
sortable_by,
)
cl.allow_custom_result_length = True
return cl
class SanitizedAdmin(CustomResultLengthAdmin):
def get_readonly_fields(self, request, obj=None):
return ("version",) + tuple(super().get_readonly_fields(request, obj=obj))
@ -777,7 +901,7 @@ class IXLanIXFMemberImportLogEntryInline(admin.TabularInline):
return mark_safe(f'<div style="background-color:{color}">{text}</div>')
class IXLanIXFMemberImportLogAdmin(admin.ModelAdmin):
class IXLanIXFMemberImportLogAdmin(CustomResultLengthAdmin, admin.ModelAdmin):
search_fields = ("ixlan__ix__id",)
list_display = ("id", "ix", "ixlan_name", "source", "created", "changes")
readonly_fields = ("ix", "ixlan_name", "source", "changes")
@ -826,7 +950,7 @@ class SponsorshipOrganizationInline(admin.TabularInline):
}
class SponsorshipAdmin(admin.ModelAdmin):
class SponsorshipAdmin(CustomResultLengthAdmin, admin.ModelAdmin):
list_display = ("organizations", "start_date", "end_date", "level", "status")
readonly_fields = ("organizations", "status", "notify_date")
inlines = (SponsorshipOrganizationInline,)
@ -865,7 +989,7 @@ class PartnershipAdminForm(baseForms.ModelForm):
fk_handleref_filter(self, "org")
class PartnershipAdmin(admin.ModelAdmin):
class PartnershipAdmin(CustomResultLengthAdmin, admin.ModelAdmin):
list_display = ("org_name", "level", "status")
readonly_fields = ("status", "org_name")
form = PartnershipAdminForm
@ -1548,7 +1672,7 @@ class CommandLineToolPrepareForm(baseForms.Form):
tool = baseForms.ChoiceField(choices=COMMANDLINE_TOOLS)
class CommandLineToolAdmin(admin.ModelAdmin):
class CommandLineToolAdmin(CustomResultLengthAdmin, admin.ModelAdmin):
"""
View that lets staff users run peeringdb command line tools
"""
@ -1705,7 +1829,7 @@ class CommandLineToolAdmin(admin.ModelAdmin):
)
class IXFImportEmailAdmin(admin.ModelAdmin):
class IXFImportEmailAdmin(CustomResultLengthAdmin, admin.ModelAdmin):
list_display = (
"subject",
"recipients",
@ -1764,7 +1888,7 @@ class DeskProTicketCCInline(admin.TabularInline):
model = DeskProTicketCC
class DeskProTicketAdmin(admin.ModelAdmin):
class DeskProTicketAdmin(CustomResultLengthAdmin, admin.ModelAdmin):
list_display = (
"id",
"subject",
@ -1837,7 +1961,7 @@ def apply_ixf_member_data(modeladmin, request, queryset):
apply_ixf_member_data.short_description = _("Apply")
class IXFMemberDataAdmin(admin.ModelAdmin):
class IXFMemberDataAdmin(CustomResultLengthAdmin, admin.ModelAdmin):
change_form_template = "admin/ixf_member_data_change_form.html"
list_display = (
@ -1991,7 +2115,7 @@ class EnvironmentSettingForm(baseForms.ModelForm):
fields = ["setting", "value"]
class EnvironmentSettingAdmin(admin.ModelAdmin):
class EnvironmentSettingAdmin(CustomResultLengthAdmin, admin.ModelAdmin):
list_display = ["setting", "value", "created", "updated", "user"]
fields = ["setting", "value"]
@ -2016,6 +2140,20 @@ class UserAPIKeyAdmin(APIKeyModelAdmin):
search_fields = ("prefix", "user__username", "user__email")
class GeoCoordinateAdmin(admin.ModelAdmin):
list_display = [
"id",
"country",
"city",
"state",
"zipcode",
"address1",
"longitude",
"latitude",
"fetched",
]
# Commented out via issue #860
# admin.site.register(EnvironmentSetting, EnvironmentSettingAdmin)
admin.site.register(IXFMemberData, IXFMemberDataAdmin)
@ -2043,3 +2181,4 @@ admin.site.register(IXFImportEmail, IXFImportEmailAdmin)
admin.site.unregister(APIKey)
admin.site.register(OrganizationAPIKey, OrganizationAPIKeyAdmin)
admin.site.register(UserAPIKey, UserAPIKeyAdmin)
admin.site.register(GeoCoordinateCache, GeoCoordinateAdmin)