Compare commits

..
1 Commits
Author SHA1 Message Date
LeoVasanko c79cb497ee Fix profile image path on OIDC. 2026-05-22 02:45:12 +00:00
3 changed files with 39 additions and 2 deletions
+1 -1
View File
@@ -46,7 +46,7 @@ def avatar_url(user_uuid: UUID) -> str | None:
"""Return the absolute public avatar URL for a user, or None.""" """Return the absolute public avatar URL for a user, or None."""
if not avatar_path(user_uuid).is_file(): if not avatar_path(user_uuid).is_file():
return None return None
return f"{hostutil.auth_site_url()}api/user/{user_uuid}/profile.webp" return hostutil.api_url(f"user/{user_uuid}/profile.webp")
def current_avatar_url(user_uuid: UUID) -> str | None: def current_avatar_url(user_uuid: UUID) -> str | None:
+10
View File
@@ -29,6 +29,16 @@ def ui_base_path() -> str:
return "/" if is_root_mode() else "/auth/" return "/" if is_root_mode() else "/auth/"
def api_url(path: str = "") -> str:
"""Return an absolute URL under the canonical /auth/api/ prefix."""
cfg = _cfg()
base = cfg.site_url if cfg else "https://localhost"
if not path:
return f"{base}/auth/api/"
normalized = path.lstrip("/")
return f"{base}/auth/api/{normalized}"
def auth_site_url() -> str: def auth_site_url() -> str:
"""Return the base URL for the auth site UI (computed at startup).""" """Return the base URL for the auth site UI (computed at startup)."""
cfg = _cfg() cfg = _cfg()
+28 -1
View File
@@ -13,6 +13,7 @@ These tests cover:
import secrets import secrets
from datetime import UTC, datetime, timedelta from datetime import UTC, datetime, timedelta
from urllib.parse import urlsplit from urllib.parse import urlsplit
from uuid import UUID
import httpx import httpx
import pytest import pytest
@@ -21,7 +22,7 @@ from paskia import authcode
from paskia.authsession import EXPIRES from paskia.authsession import EXPIRES
from paskia.db import delete_session from paskia.db import delete_session
from paskia.db.structs import Client from paskia.db.structs import Client
from paskia.util import oidjwt from paskia.util import avatar, hostutil, oidjwt
from paskia.util.passphrase import generate from paskia.util.passphrase import generate
from tests.conftest import auth_headers, create_test_image_bytes, create_test_session from tests.conftest import auth_headers, create_test_image_bytes, create_test_session
@@ -59,6 +60,32 @@ class TestSettingsEndpoint:
assert "picture" in response.json()["claims_supported"] assert "picture" in response.json()["claims_supported"]
class TestAvatarUrls:
"""Tests for avatar URL helpers."""
def test_avatar_url_uses_canonical_public_path_in_auth_host_mode(
self, tmp_path, monkeypatch
):
"""Absolute avatar URLs should preserve /auth/api even with an auth host."""
db_root = tmp_path / "test-avatar-db.paskiadb"
monkeypatch.setenv("PASKIA_DB", str(db_root))
monkeypatch.setattr(
hostutil,
"api_url",
lambda path="": f"https://auth.zi.fi/auth/api/{path.lstrip('/')}",
)
user_uuid = test_uuid = UUID("019c6831-84cf-7b88-b66c-c8165890b7c5")
path = db_root / "users" / str(test_uuid) / "profile.webp"
path.parent.mkdir(parents=True, exist_ok=True)
path.write_bytes(b"RIFF1234WEBP")
assert avatar.avatar_url(user_uuid) == (
"https://auth.zi.fi/auth/api/user/"
"019c6831-84cf-7b88-b66c-c8165890b7c5/profile.webp"
)
class TestValidateEndpoint: class TestValidateEndpoint:
"""Tests for POST /auth/api/validate""" """Tests for POST /auth/api/validate"""