Add pyproject.toml for consolidated project configuration and replace Black, isort, and Flake8 with Ruff

- Introduced `pyproject.toml` to centralize backend tool configurations (e.g., Ruff, mypy, coverage, pytest).
- Replaced Black, isort, and Flake8 with Ruff for linting, formatting, and import sorting.
- Updated `requirements.txt` to include Ruff and remove replaced tools.
- Added `Makefile` to streamline development workflows with commands for linting, formatting, type-checking, testing, and cleanup.
This commit is contained in:
2025-11-10 11:55:15 +01:00
parent a5c671c133
commit c589b565f0
86 changed files with 4572 additions and 3956 deletions

View File

@@ -7,13 +7,13 @@ Critical security tests covering:
These tests prevent unauthorized access and privilege escalation.
"""
import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.user import User
from app.models.organization import Organization
from app.crud.user import user as user_crud
from app.models.organization import Organization
from app.models.user import User
class TestInactiveUserBlocking:
@@ -29,11 +29,7 @@ class TestInactiveUserBlocking:
@pytest.mark.asyncio
async def test_inactive_user_cannot_access_protected_endpoints(
self,
client: AsyncClient,
async_test_db,
async_test_user: User,
user_token: str
self, client: AsyncClient, async_test_db, async_test_user: User, user_token: str
):
"""
Test that inactive users are blocked from protected endpoints.
@@ -44,12 +40,11 @@ class TestInactiveUserBlocking:
3. User tries to access protected endpoint with valid token
4. System MUST reject (account inactive)
"""
test_engine, SessionLocal = async_test_db
_test_engine, SessionLocal = async_test_db
# Step 1: Verify user can access endpoint while active
response = await client.get(
"/api/v1/users/me",
headers={"Authorization": f"Bearer {user_token}"}
"/api/v1/users/me", headers={"Authorization": f"Bearer {user_token}"}
)
assert response.status_code == 200, "Active user should have access"
@@ -61,8 +56,7 @@ class TestInactiveUserBlocking:
# Step 3: User tries to access endpoint with same token
response = await client.get(
"/api/v1/users/me",
headers={"Authorization": f"Bearer {user_token}"}
"/api/v1/users/me", headers={"Authorization": f"Bearer {user_token}"}
)
# Step 4: System MUST reject (covers lines 52-57)
@@ -75,18 +69,14 @@ class TestInactiveUserBlocking:
@pytest.mark.asyncio
async def test_inactive_user_blocked_from_organization_endpoints(
self,
client: AsyncClient,
async_test_db,
async_test_user: User,
user_token: str
self, client: AsyncClient, async_test_db, async_test_user: User, user_token: str
):
"""
Test that inactive users can't access organization endpoints.
Ensures the inactive check applies to ALL protected endpoints.
"""
test_engine, SessionLocal = async_test_db
_test_engine, SessionLocal = async_test_db
# Deactivate user
async with SessionLocal() as session:
@@ -97,7 +87,7 @@ class TestInactiveUserBlocking:
# Try to list organizations
response = await client.get(
"/api/v1/organizations/me",
headers={"Authorization": f"Bearer {user_token}"}
headers={"Authorization": f"Bearer {user_token}"},
)
# Must be blocked
@@ -122,7 +112,7 @@ class TestSuperuserPrivilegeEscalation:
client: AsyncClient,
async_test_db,
async_test_superuser: User,
superuser_token: str
superuser_token: str,
):
"""
Test that superusers automatically get OWNER role in organizations.
@@ -131,14 +121,11 @@ class TestSuperuserPrivilegeEscalation:
Superusers can manage any organization without being explicitly added.
This is for platform administration.
"""
test_engine, SessionLocal = async_test_db
_test_engine, SessionLocal = async_test_db
# Step 1: Create an organization (owned by someone else)
async with SessionLocal() as session:
org = Organization(
name="Test Organization",
slug="test-org"
)
org = Organization(name="Test Organization", slug="test-org")
session.add(org)
await session.commit()
await session.refresh(org)
@@ -148,7 +135,7 @@ class TestSuperuserPrivilegeEscalation:
# (They're not a member, but should auto-get OWNER role)
response = await client.get(
f"/api/v1/organizations/{org_id}",
headers={"Authorization": f"Bearer {superuser_token}"}
headers={"Authorization": f"Bearer {superuser_token}"},
)
# Step 3: Should have access (covers lines 154-157)
@@ -161,21 +148,18 @@ class TestSuperuserPrivilegeEscalation:
client: AsyncClient,
async_test_db,
async_test_superuser: User,
superuser_token: str
superuser_token: str,
):
"""
Test that superusers have full management access to all organizations.
Ensures the OWNER role privilege escalation works end-to-end.
"""
test_engine, SessionLocal = async_test_db
_test_engine, SessionLocal = async_test_db
# Create an organization
async with SessionLocal() as session:
org = Organization(
name="Test Organization",
slug="test-org"
)
org = Organization(name="Test Organization", slug="test-org")
session.add(org)
await session.commit()
await session.refresh(org)
@@ -185,34 +169,29 @@ class TestSuperuserPrivilegeEscalation:
response = await client.put(
f"/api/v1/organizations/{org_id}",
headers={"Authorization": f"Bearer {superuser_token}"},
json={"name": "Updated Name"}
json={"name": "Updated Name"},
)
# Should succeed (superuser has OWNER privileges)
assert response.status_code in [200, 404], "Superuser should be able to manage any org"
assert response.status_code in [200, 404], (
"Superuser should be able to manage any org"
)
# Note: Might be 404 if org endpoints require membership, but the role check passes
@pytest.mark.asyncio
async def test_regular_user_does_not_get_owner_role(
self,
client: AsyncClient,
async_test_db,
async_test_user: User,
user_token: str
self, client: AsyncClient, async_test_db, async_test_user: User, user_token: str
):
"""
Sanity check: Regular users don't get automatic OWNER role.
Ensures the superuser check is working correctly (line 154).
"""
test_engine, SessionLocal = async_test_db
_test_engine, SessionLocal = async_test_db
# Create an organization
async with SessionLocal() as session:
org = Organization(
name="Test Organization",
slug="test-org"
)
org = Organization(name="Test Organization", slug="test-org")
session.add(org)
await session.commit()
await session.refresh(org)
@@ -221,8 +200,10 @@ class TestSuperuserPrivilegeEscalation:
# Regular user tries to access it (not a member)
response = await client.get(
f"/api/v1/organizations/{org_id}",
headers={"Authorization": f"Bearer {user_token}"}
headers={"Authorization": f"Bearer {user_token}"},
)
# Should be denied (not a member, not a superuser)
assert response.status_code in [403, 404], "Regular user shouldn't access non-member org"
assert response.status_code in [403, 404], (
"Regular user shouldn't access non-member org"
)