parent
296780d5cc
commit
6137149f55
|
@ -17,7 +17,12 @@ from core.html import strip_html
|
||||||
from core.ld import format_ld_date
|
from core.ld import format_ld_date
|
||||||
from core.models import Config
|
from core.models import Config
|
||||||
from core.uploads import upload_emoji_namer
|
from core.uploads import upload_emoji_namer
|
||||||
from core.uris import AutoAbsoluteUrl, RelativeAbsoluteUrl, StaticAbsoluteUrl
|
from core.uris import (
|
||||||
|
AutoAbsoluteUrl,
|
||||||
|
ProxyAbsoluteUrl,
|
||||||
|
RelativeAbsoluteUrl,
|
||||||
|
StaticAbsoluteUrl,
|
||||||
|
)
|
||||||
from stator.models import State, StateField, StateGraph, StatorModel
|
from stator.models import State, StateField, StateGraph, StatorModel
|
||||||
from users.models import Domain
|
from users.models import Domain
|
||||||
|
|
||||||
|
@ -169,8 +174,9 @@ class Emoji(StatorModel):
|
||||||
if self.file:
|
if self.file:
|
||||||
return AutoAbsoluteUrl(self.file.url)
|
return AutoAbsoluteUrl(self.file.url)
|
||||||
elif self.remote_url:
|
elif self.remote_url:
|
||||||
return AutoAbsoluteUrl(
|
return ProxyAbsoluteUrl(
|
||||||
f"/proxy/emoji/{self.pk}/", hash_tail_input=self.remote_url
|
f"/proxy/emoji/{self.pk}/",
|
||||||
|
remote_url=self.remote_url,
|
||||||
)
|
)
|
||||||
return StaticAbsoluteUrl("img/blank-emoji-128.png")
|
return StaticAbsoluteUrl("img/blank-emoji-128.png")
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ from functools import partial
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
from core.uploads import upload_namer
|
from core.uploads import upload_namer
|
||||||
from core.uris import AutoAbsoluteUrl, RelativeAbsoluteUrl
|
from core.uris import ProxyAbsoluteUrl, RelativeAbsoluteUrl
|
||||||
from stator.models import State, StateField, StateGraph, StatorModel
|
from stator.models import State, StateField, StateGraph, StatorModel
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,16 +81,18 @@ class PostAttachment(StatorModel):
|
||||||
elif self.file:
|
elif self.file:
|
||||||
return RelativeAbsoluteUrl(self.file.url)
|
return RelativeAbsoluteUrl(self.file.url)
|
||||||
else:
|
else:
|
||||||
return AutoAbsoluteUrl(
|
return ProxyAbsoluteUrl(
|
||||||
f"/proxy/post_attachment/{self.pk}/", hash_tail_input=self.remote_url
|
f"/proxy/post_attachment/{self.pk}/",
|
||||||
|
remote_url=self.remote_url,
|
||||||
)
|
)
|
||||||
|
|
||||||
def full_url(self):
|
def full_url(self):
|
||||||
if self.file:
|
if self.file:
|
||||||
return RelativeAbsoluteUrl(self.file.url)
|
return RelativeAbsoluteUrl(self.file.url)
|
||||||
else:
|
else:
|
||||||
return AutoAbsoluteUrl(
|
return ProxyAbsoluteUrl(
|
||||||
f"/proxy/post_attachment/{self.pk}/", hash_tail_input=self.remote_url
|
f"/proxy/post_attachment/{self.pk}/",
|
||||||
|
remote_url=self.remote_url,
|
||||||
)
|
)
|
||||||
|
|
||||||
### ActivityPub ###
|
### ActivityPub ###
|
||||||
|
|
32
core/uris.py
32
core/uris.py
|
@ -32,15 +32,8 @@ class AutoAbsoluteUrl(RelativeAbsoluteUrl):
|
||||||
self,
|
self,
|
||||||
relative: str,
|
relative: str,
|
||||||
identity=None,
|
identity=None,
|
||||||
hash_tail_input: str | None = None,
|
|
||||||
hash_tail_length: int = 10,
|
|
||||||
):
|
):
|
||||||
self.relative = relative
|
self.relative = relative
|
||||||
if hash_tail_input:
|
|
||||||
# When provided, attach a hash of the input (typically the proxied URL)
|
|
||||||
# SHA1 chosen as it generally has the best performance in modern python, and security is not a concern
|
|
||||||
# Hash truncation is generally fine, as in the typical use case the hash is scoped to the identity PK
|
|
||||||
self.relative += f"{hashlib.sha1(hash_tail_input.encode('ascii')).hexdigest()[:hash_tail_length]}/"
|
|
||||||
if identity:
|
if identity:
|
||||||
absolute_prefix = f"https://{identity.domain.uri_domain}/"
|
absolute_prefix = f"https://{identity.domain.uri_domain}/"
|
||||||
else:
|
else:
|
||||||
|
@ -48,6 +41,31 @@ class AutoAbsoluteUrl(RelativeAbsoluteUrl):
|
||||||
self.absolute = urljoin(absolute_prefix, self.relative)
|
self.absolute = urljoin(absolute_prefix, self.relative)
|
||||||
|
|
||||||
|
|
||||||
|
class ProxyAbsoluteUrl(AutoAbsoluteUrl):
|
||||||
|
"""
|
||||||
|
AutoAbsoluteUrl variant for proxy paths, that also attaches a remote URI hash
|
||||||
|
plus extension to the end if it can.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
relative: str,
|
||||||
|
identity=None,
|
||||||
|
remote_url: str | None = None,
|
||||||
|
):
|
||||||
|
if remote_url:
|
||||||
|
# See if there is a file extension we can grab
|
||||||
|
extension = "bin"
|
||||||
|
remote_filename = remote_url.split("/")[-1]
|
||||||
|
if "." in remote_filename:
|
||||||
|
extension = remote_filename.split(".")[-1]
|
||||||
|
# When provided, attach a hash of the remote URL
|
||||||
|
# SHA1 chosen as it generally has the best performance in modern python, and security is not a concern
|
||||||
|
# Hash truncation is generally fine, as in the typical use case the hash is scoped to the identity PK.
|
||||||
|
relative += f"{hashlib.sha1(remote_url.encode('ascii')).hexdigest()[:10]}.{extension}"
|
||||||
|
super().__init__(relative, identity)
|
||||||
|
|
||||||
|
|
||||||
class StaticAbsoluteUrl(RelativeAbsoluteUrl):
|
class StaticAbsoluteUrl(RelativeAbsoluteUrl):
|
||||||
"""
|
"""
|
||||||
Creates static URLs given only the static-relative path
|
Creates static URLs given only the static-relative path
|
||||||
|
|
|
@ -212,22 +212,22 @@ urlpatterns = [
|
||||||
path("debug/oauth_authorize/", debug.OauthAuthorize.as_view()),
|
path("debug/oauth_authorize/", debug.OauthAuthorize.as_view()),
|
||||||
# Media/image proxy
|
# Media/image proxy
|
||||||
re_path(
|
re_path(
|
||||||
"^proxy/identity_icon/(?P<identity_id>[^/]+)/((?P<image_hash>[^/]+)/)?$",
|
"^proxy/identity_icon/(?P<identity_id>[^/]+)/((?P<image_hash>[^/]+))?$",
|
||||||
mediaproxy.IdentityIconCacheView.as_view(),
|
mediaproxy.IdentityIconCacheView.as_view(),
|
||||||
name="proxy_identity_icon",
|
name="proxy_identity_icon",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
"^proxy/identity_image/(?P<identity_id>[^/]+)/((?P<image_hash>[^/]+)/)?$",
|
"^proxy/identity_image/(?P<identity_id>[^/]+)/((?P<image_hash>[^/]+))?$",
|
||||||
mediaproxy.IdentityImageCacheView.as_view(),
|
mediaproxy.IdentityImageCacheView.as_view(),
|
||||||
name="proxy_identity_image",
|
name="proxy_identity_image",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
"^proxy/post_attachment/(?P<attachment_id>[^/]+)/((?P<image_hash>[^/]+)/)?$",
|
"^proxy/post_attachment/(?P<attachment_id>[^/]+)/((?P<image_hash>[^/]+))?$",
|
||||||
mediaproxy.PostAttachmentCacheView.as_view(),
|
mediaproxy.PostAttachmentCacheView.as_view(),
|
||||||
name="proxy_post_attachment",
|
name="proxy_post_attachment",
|
||||||
),
|
),
|
||||||
re_path(
|
re_path(
|
||||||
"^proxy/emoji/(?P<emoji_id>[^/]+)/((?P<image_hash>[^/]+)/)?$",
|
"^proxy/emoji/(?P<emoji_id>[^/]+)/((?P<image_hash>[^/]+))?$",
|
||||||
mediaproxy.EmojiCacheView.as_view(),
|
mediaproxy.EmojiCacheView.as_view(),
|
||||||
name="proxy_emoji",
|
name="proxy_emoji",
|
||||||
),
|
),
|
||||||
|
|
|
@ -23,7 +23,12 @@ from core.ld import (
|
||||||
from core.models import Config
|
from core.models import Config
|
||||||
from core.signatures import HttpSignature, RsaKeys
|
from core.signatures import HttpSignature, RsaKeys
|
||||||
from core.uploads import upload_namer
|
from core.uploads import upload_namer
|
||||||
from core.uris import AutoAbsoluteUrl, RelativeAbsoluteUrl, StaticAbsoluteUrl
|
from core.uris import (
|
||||||
|
AutoAbsoluteUrl,
|
||||||
|
ProxyAbsoluteUrl,
|
||||||
|
RelativeAbsoluteUrl,
|
||||||
|
StaticAbsoluteUrl,
|
||||||
|
)
|
||||||
from stator.models import State, StateField, StateGraph, StatorModel
|
from stator.models import State, StateField, StateGraph, StatorModel
|
||||||
from users.models.domain import Domain
|
from users.models.domain import Domain
|
||||||
from users.models.system_actor import SystemActor
|
from users.models.system_actor import SystemActor
|
||||||
|
@ -268,8 +273,9 @@ class Identity(StatorModel):
|
||||||
if self.icon:
|
if self.icon:
|
||||||
return RelativeAbsoluteUrl(self.icon.url)
|
return RelativeAbsoluteUrl(self.icon.url)
|
||||||
elif self.icon_uri:
|
elif self.icon_uri:
|
||||||
return AutoAbsoluteUrl(
|
return ProxyAbsoluteUrl(
|
||||||
f"/proxy/identity_icon/{self.pk}/", hash_tail_input=self.icon_uri
|
f"/proxy/identity_icon/{self.pk}/",
|
||||||
|
remote_url=self.icon_uri,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
return StaticAbsoluteUrl("img/unknown-icon-128.png")
|
return StaticAbsoluteUrl("img/unknown-icon-128.png")
|
||||||
|
@ -281,8 +287,9 @@ class Identity(StatorModel):
|
||||||
if self.image:
|
if self.image:
|
||||||
return AutoAbsoluteUrl(self.image.url)
|
return AutoAbsoluteUrl(self.image.url)
|
||||||
elif self.image_uri:
|
elif self.image_uri:
|
||||||
return AutoAbsoluteUrl(
|
return ProxyAbsoluteUrl(
|
||||||
f"/proxy/identity_image/{self.pk}/", hash_tail_input=self.image_uri
|
f"/proxy/identity_image/{self.pk}/",
|
||||||
|
remote_url=self.image_uri,
|
||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue