make domain matching work, fix minio + cloudflare r2

This commit is contained in:
sam 2024-03-31 17:03:13 +02:00
parent 66a5dfb433
commit 59ad391a2b
Signed by: sam
GPG key ID: B4EF20DDE721CAA1
3 changed files with 21 additions and 3 deletions

View file

@ -6,8 +6,10 @@ from . import blueprints
from .db.aio import async_session from .db.aio import async_session
from .db.util import validate_token from .db.util import validate_token
from .exceptions import ErrorCode, ExpectedError from .exceptions import ErrorCode, ExpectedError
from .settings import SECRET_KEY, BASE_DOMAIN
app = Quart(__name__) app = Quart(__name__, host_matching=True, static_host=BASE_DOMAIN)
app.secret_key = SECRET_KEY
app = cors( app = cors(
app, app,
allow_origin="*", allow_origin="*",

View file

@ -24,6 +24,7 @@ with env.prefixed("MINIO_"):
"SECRET_KEY": env("SECRET_KEY"), "SECRET_KEY": env("SECRET_KEY"),
"BUCKET": env("BUCKET"), "BUCKET": env("BUCKET"),
"SECURE": env.bool("SECURE", True), "SECURE": env.bool("SECURE", True),
"REGION": env("REGION", "auto"),
} }
# The base domain the API is served on. This must be set. # The base domain the API is served on. This must be set.

View file

@ -21,11 +21,16 @@ minio = Minio(
access_key=MINIO["ACCESS_KEY"], access_key=MINIO["ACCESS_KEY"],
secret_key=MINIO["SECRET_KEY"], secret_key=MINIO["SECRET_KEY"],
secure=MINIO["SECURE"], secure=MINIO["SECURE"],
region=MINIO["REGION"],
) )
bucket = MINIO["BUCKET"] bucket = MINIO["BUCKET"]
def convert_avatar(uri: str) -> bytes: def convert_avatar(uri: str) -> bytes:
"""Converts a base64 data URI into a WebP image.
Images are resized and cropped to 512x512 and exported with quality 95.
Only PNG, WebP, and JPEG images are allowed as input."""
if not uri.startswith("data:image/"): if not uri.startswith("data:image/"):
raise ValueError("Not a data URI") raise ValueError("Not a data URI")
@ -45,6 +50,9 @@ def convert_avatar(uri: str) -> bytes:
@app.task @app.task
def process_user_avatar(user_id: int, avatar: str) -> None: def process_user_avatar(user_id: int, avatar: str) -> None:
"""Processes an avatar string, uploads it to S3, and updates the user's avatar hash.
Also deletes the old avatar if one was already set."""
with session() as conn: with session() as conn:
user = conn.scalar(select(User).where(User.id == user_id)) user = conn.scalar(select(User).where(User.id == user_id))
if not user: if not user:
@ -66,12 +74,14 @@ def process_user_avatar(user_id: int, avatar: str) -> None:
conn.execute(update(User).values(avatar=hash).where(User.id == user_id)) conn.execute(update(User).values(avatar=hash).where(User.id == user_id))
conn.commit() conn.commit()
if old_hash: if old_hash and old_hash != hash:
minio.remove_object(bucket, f"users/{user_id}/avatars/{old_hash}.webp") minio.remove_object(bucket, f"users/{user_id}/avatars/{old_hash}.webp")
@app.task @app.task
def delete_user_avatar(user_id: int) -> None: def delete_user_avatar(user_id: int) -> None:
"""Deletes a user's avatar."""
with session() as conn: with session() as conn:
user = conn.scalar(select(User).where(User.id == user_id)) user = conn.scalar(select(User).where(User.id == user_id))
if not user: if not user:
@ -91,6 +101,9 @@ def delete_user_avatar(user_id: int) -> None:
@app.task @app.task
def process_member_avatar(member_id: int, avatar: str) -> None: def process_member_avatar(member_id: int, avatar: str) -> None:
"""Processes an avatar string, uploads it to S3, and updates the member's avatar hash.
Also deletes the old avatar if one was already set."""
with session() as conn: with session() as conn:
member = conn.scalar(select(Member).where(Member.id == member_id)) member = conn.scalar(select(Member).where(Member.id == member_id))
if not member: if not member:
@ -114,12 +127,14 @@ def process_member_avatar(member_id: int, avatar: str) -> None:
conn.execute(update(Member).values(avatar=hash).where(Member.id == member_id)) conn.execute(update(Member).values(avatar=hash).where(Member.id == member_id))
conn.commit() conn.commit()
if old_hash: if old_hash and old_hash != hash:
minio.remove_object(bucket, f"members/{member_id}/avatars/{old_hash}.webp") minio.remove_object(bucket, f"members/{member_id}/avatars/{old_hash}.webp")
@app.task @app.task
def delete_member_avatar(member_id: int) -> None: def delete_member_avatar(member_id: int) -> None:
"""Deletes a member's avatar."""
with session() as conn: with session() as conn:
member = conn.scalar(select(Member).where(Member.id == member_id)) member = conn.scalar(select(Member).where(Member.id == member_id))
if not member: if not member: