fix: a blurred Patreon preview embedded in a viewable post is not downloaded
CI and images / extension-version (push) Successful in 2s
CI and images / lint (push) Successful in 2s
CI and images / extension-test (push) Successful in 20s
CI and images / frontend-build (push) Successful in 22s
CI and images / backend-lint-and-test (push) Failing after 51s
CI and images / integration (push) Successful in 2m34s
CI and images / sign-extension (push) Skipped
CI and images / build-web (push) Skipped
CI and images / smoke-web (push) Skipped
CI and images / promote (push) Skipped
CI and images / refresh-dev (push) Skipped
CI and images / unattended-failure (push) Skipped
CI and images / build-agent (push) Skipped

A post the account can view can show media from a post it can't, such as a
public teaser carrying a paid post's image. Patreon serves that media blurred,
and the post-level gate (current_user_can_view) lets it through. The CDN URL
says so in its render options ({"b": 70, ...}), so extract_media now drops any
item whose URL asks for a blur.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-07 22:18:12 -05:00
co-authored by Claude Opus 5.5
parent f2e4f94a96
commit 2e76ad89fd
2 changed files with 53 additions and 1 deletions
+24
View File
@@ -19,6 +19,7 @@ from backend.app.services.patreon_client import (
PatreonAuthError,
PatreonClient,
PatreonDriftError,
is_blurred_preview,
parse_cursor_from_url,
)
@@ -459,3 +460,26 @@ def test_post_is_gated_viewable_and_missing_are_not_gated():
{"attributes": {"current_user_can_view": None}}
) is False
assert PatreonClient.post_is_gated({}) is False
# A locked preview's render options carry a blur ("b"); an ordinary one doesn't.
BLURRED = ("https://c10.patreonusercontent.com/4/patreon-media/p/post/174446666/"
"743caff4c51648c185e8347271e1a7b7/eyJiIjo3MCwidyI6MTA4MH0%3D/1.png?token-hash=x")
SHARP = ("https://c10.patreonusercontent.com/4/patreon-media/p/post/174446666/"
"843caff4c51648c185e8347271e1a7b7/eyJ3IjoxMDgwfQ%3D%3D/1.png?token-hash=x")
def test_a_blurred_locked_preview_is_recognised_by_its_render_options():
assert is_blurred_preview(BLURRED)
assert not is_blurred_preview(SHARP)
assert not is_blurred_preview("https://example.com/eyJnot-json/1.png")
assert not is_blurred_preview("https://example.com/plain/1.png")
def test_a_viewable_post_embedding_a_blurred_preview_skips_just_that_image(client):
post = {"id": "174448839", "type": "post", "attributes": {
"current_user_can_view": True,
"content": f'<p><img src="{BLURRED}"></p><p><img src="{SHARP}"></p>',
}, "relationships": {}}
items = client.extract_media(post, {})
assert [m.url for m in items] == [SHARP]