import asyncio import sys from pathlib import Path import jwt import pytest from fastapi import HTTPException from fastapi.security import HTTPAuthorizationCredentials ROOT = Path(__file__).resolve().parents[2] API_ROOT = ROOT / "apps" / "api" if str(API_ROOT) not in sys.path: sys.path.insert(0, str(API_ROOT)) from app.config import settings from app.middleware.auth import get_current_user, get_current_user_optional, require_workspace_access from packages.domain.auth import password_hasher from packages.domain.entities import User class InMemoryUserRepository: def __init__(self): self.users = {} def save(self, user): self.users[user.id] = user def find_by_id(self, user_id): return self.users.get(user_id) def find_by_email(self, email): return next((user for user in self.users.values() if user.email == email), None) def find_by_username(self, username): return next((user for user in self.users.values() if user.username == username), None) def find_by_verification_token(self, token): return None def find_by_password_reset_token(self, token): return None def delete(self, user_id): return self.users.pop(user_id, None) is not None def _repo_with_user(): repo = InMemoryUserRepository() user = User( id="user-1", email="user@example.com", username="user", display_name="User", password_hash=password_hasher.hash_password("Password1"), ) repo.save(user) return repo def _credentials(token_type="user_auth"): token = jwt.encode({"sub": "user-1", "sid": "session-1", "type": token_type}, settings.JWT_SECRET_KEY, "HS256") return HTTPAuthorizationCredentials(scheme="Bearer", credentials=token) def test_legacy_middleware_get_current_user_delegates_to_canonical_auth(): user = asyncio.run(get_current_user(asyncio.run(_authenticated_user()))) assert user.id == "user-1" def test_legacy_middleware_optional_user_returns_none_without_credentials(): assert asyncio.run(get_current_user_optional(None, _repo_with_user())) is None def test_legacy_middleware_optional_user_returns_user_with_valid_credentials(): user = asyncio.run(get_current_user_optional(_credentials(), _repo_with_user())) assert user is not None assert user.id == "user-1" def test_workspace_dependency_allows_member_access(): repo = _WorkspaceMemberRepositoryStub(role="member") workspace_id, role = require_workspace_access("workspace-1", _repo_with_user().find_by_id("user-1"), repo) assert workspace_id == "workspace-1" assert role == "member" def test_workspace_dependency_rejects_non_member(): with pytest.raises(HTTPException) as error: require_workspace_access( "workspace-1", _repo_with_user().find_by_id("user-1"), _WorkspaceMemberRepositoryStub() ) assert error.value.status_code == 403 class _WorkspaceMemberRepositoryStub: def __init__(self, role=None): self.role = role def find_by_workspace_and_user(self, workspace_id, user_id): if self.role is None: return None from packages.domain.entities import WorkspaceMember return WorkspaceMember(id="member-1", workspace_id=workspace_id, user_id=user_id, role=self.role) async def _authenticated_user(): from app.auth import get_current_user as get_authenticated_user return await get_authenticated_user(_credentials(), _repo_with_user())