fix(favicon): favicon podąża za hostem w multi-tenant (3.7)#653
Open
mpasternak wants to merge 2 commits into
Open
fix(favicon): favicon podąża za hostem w multi-tenant (3.7)#653mpasternak wants to merge 2 commits into
mpasternak wants to merge 2 commits into
Conversation
`django-favicon-plus-reloaded` renderuje favicon przez `Favicon.on_site`
(CurrentSiteManager), który filtruje po literalnym `settings.SITE_ID`.
`SiteResolutionMiddleware` nie podmienia SITE_ID per request, więc dotąd
wszystkie uczelnie dostawały favicon site'u o SITE_ID zamiast własnego.
Fix bez patchowania biblioteki: nowy tag `bpp.templatetags.favicon_bpp.
place_favicon` pyta zwykły `Favicon.objects` po `request.site` (Host →
Site). Fragment `{% cache 3600 favicon request.get_host %}` w bare.html
dostaje vary_on na hoście, a wpis `favicon` znika z allowlisty strażnika
`test_cache_fragmentow_vary_on.py` — inaczej cache fragmentu podałby
favicon jednej uczelni pod domeną innej.
Testy (na realnym backendzie LocMem): różne hosty → różne favicony,
izolacja cache fragmentu per host, trafienie dla tego samego hosta.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019GmViAsaif9MXeuDMA5NHX
…tenantów Krytyczny finding z code review: biblioteczny Favicon.save woła Favicon.on_site.exclude(pk).update(isFavicon=False), a on_site to CurrentSiteManager po literalnym settings.SITE_ID. Zapis favicona DOWOLNEGO tenanta gasił więc isFavicon faviconom site'u o SITE_ID (realnej uczelni) — utworzenie favicona tenanta B kasowało favicon tenanta A spod SITE_ID. Monkeypatch Favicon.save w BppConfig.ready() zawęża reset do self.site (Favicon.objects.filter(site=self.site)) zamiast globalnego on_site. Obejmuje wszystkie ścieżki zapisu (w tym admin biblioteki). Test: dodano test clobberingu tworzący favicony NORMALNĄ ścieżką create()/save() (jak admin) — pada na starej ścieżce bibliotecznej, przechodzi po patchu. Fixture'y przestały wymuszać isFavicon przez .update() omijające save() (maskowały buga) i używają teraz save(). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019GmViAsaif9MXeuDMA5NHX
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Favicon nie podążał za hostem w multi-tenant —
django-favicon-plus-reloadedużywa
CurrentSiteManagerfiltrującego po literalnymsettings.SITE_ID,którego
SiteResolutionMiddlewarenie podmienia. Wszystkie uczelnie dostawałyfavicon site'u o
SITE_ID(poz. 3.7 audytu).Zmiana (ścieżka w repo, bez forka biblioteki)
place_faviconpytaFavicon.objects.filter(site=request.site, isFavicon=True)zamiast globalnegomanagera.
vary_on:{% cache 3600 favicon request.get_host %},wpis zdjęty z allowlisty strażnika
test_cache_fragmentow_vary_on.py(bofragmenty
{% cache %}nie mają hosta w kluczu — reguła Bump mixin-deep from 1.3.1 to 1.3.2 #4 audytu; bez tegocache podałby favicon jednej uczelni innej).
Favicon.save()bibliotekigasił
isFaviconpoon_site(SITE_ID) → zapis favicona dowolnego tenantagasił favicon tenanta
SITE_ID. MonkeypatchFavicon.savewBppConfig.ready()zawęża reset do
filter(site=self.site). Idempotentny (guard_bpp_per_site_patched), obejmuje wszystkie ścieżki zapisu (w tym admin).Weryfikacja
vary_on(request.get_host) spójny z wymiarem rozdzielczości (host) — brak„ten sam klucz, inny favicon"; strażnik zielony, regresja zapewniona z konstrukcji.
tenanta A (test pada), z patchem przeżywa. Fixture'y używają realnej ścieżki
save()(nie obchodzą jej przez.update()).admin objęty, sygnatura zachowana). 7 passed.
Poz. 3.7 audytu.
🤖 Generated with Claude Code
https://claude.ai/code/session_019GmViAsaif9MXeuDMA5NHX