Initial curated RAGcore source from c16667f0c9397e2bfc8dd0255b114fba23c8d05e

This commit is contained in:
Public Source Publisher committed 2026-10-01 01:34:21 +02:00
commit 7ca726caf2
659 files changed
+98171

No files matched your search

+150
View File
@@ -0,0 +1,150 @@
"""SessionService: state validation and session rotation."""
from __future__ import annotations
from collections.abc import Mapping
from uuid import uuid4
import pytest
from ragcore.application.auth import InvalidStateError, PendingLogin, SessionService
from ragcore.application.auth.ports import AuthorizationChallenge
from ragcore.domain.auth import OidcClaims
from ragcore.domain.control import Role
class FakeOidcProvider:
def __init__(self, claims: OidcClaims) -> None:
self.claims = claims
self.challenge_calls: list[str] = []
self.login_calls: list[tuple[str, str, str, str]] = []
async def build_authorization_challenge(self, *, redirect_uri: str) -> AuthorizationChallenge:
self.challenge_calls.append(redirect_uri)
return AuthorizationChallenge(
redirect_url="https://idp.example.test/authorize?...",
state=f"state-{len(self.challenge_calls)}",
nonce=f"nonce-{len(self.challenge_calls)}",
code_verifier=f"verifier-{len(self.challenge_calls)}",
)
async def complete_login(
self, *, code: str, code_verifier: str, nonce: str, redirect_uri: str
) -> OidcClaims:
self.login_calls.append((code, code_verifier, nonce, redirect_uri))
return self.claims
def _service(
provider: FakeOidcProvider, *, group_roles: Mapping[str, Role] | None = None
) -> SessionService:
return SessionService(
provider=provider,
group_roles=group_roles or {"ragcore-editors": Role.EDITOR},
workspace_id=uuid4(),
)
async def test_start_login_returns_a_redirect_and_pending_login() -> None:
provider = FakeOidcProvider(OidcClaims(subject="alice", email=None, groups=()))
service = _service(provider)
start = await service.start_login(redirect_uri="https://ragcore.example.test/auth/callback")
assert start.redirect_url.startswith("https://idp.example.test/")
assert start.pending.state
assert start.pending.nonce
assert start.pending.code_verifier
assert provider.challenge_calls == ["https://ragcore.example.test/auth/callback"]
async def test_complete_login_mints_a_session_with_mapped_roles() -> None:
provider = FakeOidcProvider(
OidcClaims(subject="alice", email="alice@example.test", groups=("ragcore-editors",))
)
service = _service(provider)
start = await service.start_login(redirect_uri="https://ragcore.example.test/auth/callback")
session = await service.complete_login(
code="auth-code",
state=start.pending.state,
pending=start.pending,
redirect_uri="https://ragcore.example.test/auth/callback",
)
assert session.subject == "alice"
assert session.roles == frozenset({Role.EDITOR})
assert session.csrf_token
assert not session.is_expired
assert provider.login_calls == [
("auth-code", start.pending.code_verifier, start.pending.nonce, "https://ragcore.example.test/auth/callback")
]
async def test_mismatched_state_is_rejected() -> None:
provider = FakeOidcProvider(OidcClaims(subject="alice", email=None, groups=()))
service = _service(provider)
start = await service.start_login(redirect_uri="https://ragcore.example.test/auth/callback")
with pytest.raises(InvalidStateError):
await service.complete_login(
code="auth-code",
state="a-completely-different-state",
pending=start.pending,
redirect_uri="https://ragcore.example.test/auth/callback",
)
# The provider is never even asked to exchange the code once state fails.
assert provider.login_calls == []
async def test_two_logins_never_reuse_the_same_session_id_session_rotation() -> None:
"""Session rotation's standard security meaning: the post-authentication
session identifier is never the pending (pre-authentication) one, and a
fresh login always mints a brand-new session -- never resurrects or
reuses a previous one, defeating session-fixation attacks.
"""
provider = FakeOidcProvider(OidcClaims(subject="alice", email=None, groups=()))
service = _service(provider)
first_start = await service.start_login(redirect_uri="https://ragcore.example.test/auth/callback")
first_session = await service.complete_login(
code="code-1",
state=first_start.pending.state,
pending=first_start.pending,
redirect_uri="https://ragcore.example.test/auth/callback",
)
second_start = await service.start_login(redirect_uri="https://ragcore.example.test/auth/callback")
second_session = await service.complete_login(
code="code-2",
state=second_start.pending.state,
pending=second_start.pending,
redirect_uri="https://ragcore.example.test/auth/callback",
)
assert first_session.id != second_session.id
assert first_session.csrf_token != second_session.csrf_token
async def test_unrecognized_groups_produce_a_roleless_session() -> None:
provider = FakeOidcProvider(
OidcClaims(subject="mallory", email=None, groups=("not-a-real-group",))
)
service = _service(provider, group_roles={"ragcore-admins": Role.PLATFORM_ADMIN})
start = await service.start_login(redirect_uri="https://ragcore.example.test/auth/callback")
session = await service.complete_login(
code="auth-code",
state=start.pending.state,
pending=start.pending,
redirect_uri="https://ragcore.example.test/auth/callback",
)
assert session.roles == frozenset()
def test_pending_login_is_an_immutable_value() -> None:
pending = PendingLogin(state="s", nonce="n", code_verifier="v")
with pytest.raises(AttributeError):
pending.state = "other" # type: ignore[misc]