Initial curated RAGcore source from c16667f0c9397e2bfc8dd0255b114fba23c8d05e
This commit is contained in:
commit
7ca726caf2
659 files changed
+98171
No files matched your search
@@ -0,0 +1,150 @@
|
||||
"""Adversarial tests for the shared Bearer-token principal fallback."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from uuid import UUID, uuid4
|
||||
|
||||
import pytest
|
||||
from fastapi import Request
|
||||
|
||||
from ragcore.api.v1.control.bearer_auth import bearer_principal
|
||||
from ragcore.api.v1.control.dependencies import ControlAPIProblem
|
||||
from ragcore.application.identity.credentials import ServiceAccountCredentialService
|
||||
from ragcore.domain.authorization import Principal, PrincipalType
|
||||
from ragcore.domain.control import Role, Scope, ServiceAccount, Workspace
|
||||
from ragcore.infrastructure.database.identity import InMemoryCredentialRepository
|
||||
|
||||
PEPPER = "test-credential-pepper-that-is-long-enough"
|
||||
|
||||
|
||||
def _token_factory(credential_id: UUID) -> str:
|
||||
return f"rc_sa_{credential_id.hex}_{'a' * 43}"
|
||||
|
||||
|
||||
def _request(headers: dict[bytes, bytes]) -> Request:
|
||||
return Request({"type": "http", "headers": list(headers.items())})
|
||||
|
||||
|
||||
def _service_account(scopes: set[Scope]) -> tuple[Workspace, ServiceAccount]:
|
||||
frozen_scopes = frozenset(scopes)
|
||||
workspace = Workspace(uuid4(), "Test", "test")
|
||||
application = workspace.create_application(
|
||||
id=uuid4(), name="n8n", slug="n8n", scopes=frozen_scopes
|
||||
)
|
||||
account = ServiceAccount(
|
||||
id=uuid4(),
|
||||
workspace_id=workspace.id,
|
||||
application_id=application.id,
|
||||
name="n8n worker",
|
||||
scopes=frozen_scopes,
|
||||
active=True,
|
||||
)
|
||||
return workspace, account
|
||||
|
||||
|
||||
async def _credential_service(
|
||||
account: ServiceAccount | None,
|
||||
) -> ServiceAccountCredentialService:
|
||||
async def load(account_id: UUID) -> ServiceAccount | None:
|
||||
return account if account is not None and account_id == account.id else None
|
||||
|
||||
return ServiceAccountCredentialService(
|
||||
InMemoryCredentialRepository(),
|
||||
PEPPER,
|
||||
service_account_loader=load,
|
||||
token_factory=_token_factory,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.security
|
||||
async def test_bearer_principal_accepts_a_correctly_scoped_token() -> None:
|
||||
workspace, account = _service_account({Scope.SEARCH})
|
||||
credential_service = await _credential_service(account)
|
||||
issued = await credential_service.issue(account, scopes={Scope.SEARCH})
|
||||
|
||||
dependency = bearer_principal(Scope.SEARCH)
|
||||
request = _request({b"authorization": f"Bearer {issued.token}".encode()})
|
||||
|
||||
result = await dependency(request, credential_service)
|
||||
|
||||
assert result.principal_type is PrincipalType.SERVICE_ACCOUNT
|
||||
assert result.id == account.id
|
||||
assert result.workspace_id == workspace.id
|
||||
assert Role.EDITOR in result.roles
|
||||
|
||||
|
||||
@pytest.mark.security
|
||||
async def test_bearer_principal_prefers_an_existing_session_principal() -> None:
|
||||
workspace, account = _service_account({Scope.CONTEXT})
|
||||
credential_service = await _credential_service(account)
|
||||
issued = await credential_service.issue(account, scopes={Scope.CONTEXT})
|
||||
|
||||
session_principal = Principal(
|
||||
id=uuid4(), workspace_id=workspace.id, principal_type=PrincipalType.HUMAN
|
||||
)
|
||||
request = _request({b"authorization": f"Bearer {issued.token}".encode()})
|
||||
request.state.principal = session_principal
|
||||
|
||||
result = await bearer_principal(Scope.CONTEXT)(request, credential_service)
|
||||
|
||||
assert result is session_principal
|
||||
|
||||
|
||||
@pytest.mark.security
|
||||
async def test_bearer_principal_rejects_wrong_scope_missing_header_and_malformed_token() -> None:
|
||||
_workspace, account = _service_account({Scope.SEARCH})
|
||||
credential_service = await _credential_service(account)
|
||||
issued = await credential_service.issue(account, scopes={Scope.SEARCH})
|
||||
dependency = bearer_principal(Scope.ANSWER)
|
||||
scoped_request = _request({b"authorization": f"Bearer {issued.token}".encode()})
|
||||
|
||||
with pytest.raises(ControlAPIProblem) as wrong_scope:
|
||||
await dependency(scoped_request, credential_service)
|
||||
assert wrong_scope.value.status == 401
|
||||
|
||||
with pytest.raises(ControlAPIProblem) as no_header:
|
||||
await dependency(_request({}), credential_service)
|
||||
assert no_header.value.status == 401
|
||||
|
||||
with pytest.raises(ControlAPIProblem) as malformed:
|
||||
await dependency(
|
||||
_request({b"authorization": b"Bearer not-a-real-token"}), credential_service
|
||||
)
|
||||
assert malformed.value.status == 401
|
||||
|
||||
|
||||
@pytest.mark.security
|
||||
async def test_bearer_principal_rejects_deactivated_service_account() -> None:
|
||||
_workspace, account = _service_account({Scope.ANSWER})
|
||||
repository = InMemoryCredentialRepository()
|
||||
|
||||
async def load_active(account_id: UUID) -> ServiceAccount | None:
|
||||
return account if account_id == account.id else None
|
||||
|
||||
issuing_service = ServiceAccountCredentialService(
|
||||
repository, PEPPER, service_account_loader=load_active, token_factory=_token_factory
|
||||
)
|
||||
issued = await issuing_service.issue(account, scopes={Scope.ANSWER})
|
||||
|
||||
inactive_account = ServiceAccount(
|
||||
id=account.id,
|
||||
workspace_id=account.workspace_id,
|
||||
application_id=account.application_id,
|
||||
name=account.name,
|
||||
scopes=account.scopes,
|
||||
active=False,
|
||||
)
|
||||
|
||||
async def load_inactive(account_id: UUID) -> ServiceAccount | None:
|
||||
return inactive_account if account_id == account.id else None
|
||||
|
||||
authenticating_service = ServiceAccountCredentialService(
|
||||
repository, PEPPER, service_account_loader=load_inactive, token_factory=_token_factory
|
||||
)
|
||||
|
||||
with pytest.raises(ControlAPIProblem) as error:
|
||||
await bearer_principal(Scope.ANSWER)(
|
||||
_request({b"authorization": f"Bearer {issued.token}".encode()}),
|
||||
authenticating_service,
|
||||
)
|
||||
assert error.value.status == 401
|
||||
Reference in new issue
Block a user