chore: fix all ruff lint errors + format — 0 errors, 306 tests pass

This commit is contained in:
leocrm-bot
2026-06-29 17:43:56 +02:00
parent 316f323ff4
commit a2452cc04b
81 changed files with 2317 additions and 1128 deletions
+8 -11
View File
@@ -5,7 +5,7 @@ from __future__ import annotations
import uuid
from datetime import datetime
from sqlalchemy import String, DateTime, ForeignKey, Index, UniqueConstraint
from sqlalchemy import DateTime, Index, String, UniqueConstraint
from sqlalchemy.dialects.postgresql import UUID as PGUUID
from sqlalchemy.orm import Mapped, mapped_column
@@ -18,7 +18,10 @@ class Permission(Base, TenantMixin):
__tablename__ = "permissions"
__table_args__ = (
UniqueConstraint(
"tenant_id", "file_id", "user_id", "access_level",
"tenant_id",
"file_id",
"user_id",
"access_level",
name="uq_permissions_file_user_level",
),
Index("ix_permissions_file", "tenant_id", "file_id"),
@@ -30,9 +33,7 @@ class Permission(Base, TenantMixin):
)
file_id: Mapped[uuid.UUID] = mapped_column(PGUUID(as_uuid=True), nullable=False)
user_id: Mapped[uuid.UUID] = mapped_column(PGUUID(as_uuid=True), nullable=False)
group_id: Mapped[uuid.UUID | None] = mapped_column(
PGUUID(as_uuid=True), nullable=True
)
group_id: Mapped[uuid.UUID | None] = mapped_column(PGUUID(as_uuid=True), nullable=True)
access_level: Mapped[str] = mapped_column(String(10), nullable=False, default="read")
@@ -51,10 +52,6 @@ class ShareLink(Base, TenantMixin):
file_id: Mapped[uuid.UUID] = mapped_column(PGUUID(as_uuid=True), nullable=False)
token: Mapped[str] = mapped_column(String(64), nullable=False, unique=True)
password_hash: Mapped[str | None] = mapped_column(String(255), nullable=True)
expires_at: Mapped[datetime | None] = mapped_column(
DateTime(timezone=True), nullable=True
)
expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
access_level: Mapped[str] = mapped_column(String(10), nullable=False, default="download")
created_by: Mapped[uuid.UUID | None] = mapped_column(
PGUUID(as_uuid=True), nullable=True
)
created_by: Mapped[uuid.UUID | None] = mapped_column(PGUUID(as_uuid=True), nullable=True)
@@ -2,10 +2,6 @@
from __future__ import annotations
from typing import Any
from fastapi import APIRouter
from app.plugins.base import BasePlugin
from app.plugins.manifest import PluginManifest, PluginRouteDef
+27 -16
View File
@@ -4,10 +4,10 @@ from __future__ import annotations
import secrets
import uuid
from datetime import datetime, timezone
from datetime import UTC, datetime
from fastapi import APIRouter, Depends, HTTPException, Response, status
from sqlalchemy import select, delete
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.core.auth import hash_password, verify_password
@@ -28,11 +28,14 @@ def _parse_uuid(val: str, field: str) -> uuid.UUID:
try:
return uuid.UUID(val)
except (ValueError, TypeError):
raise HTTPException(400, detail={"detail": f"Invalid {field}", "code": "invalid_id"})
raise HTTPException(
400, detail={"detail": f"Invalid {field}", "code": "invalid_id"}
) from None
# ─── Permissions CRUD ───
@router.get("/files/{file_id}/permissions")
async def list_permissions(
file_id: str,
@@ -85,7 +88,9 @@ async def grant_permission(
)
)
if existing.scalar_one_or_none() is not None:
raise HTTPException(409, detail={"detail": "Permission already exists", "code": "duplicate"})
raise HTTPException(
409, detail={"detail": "Permission already exists", "code": "duplicate"}
)
perm = Permission(
tenant_id=tenant_id,
@@ -135,8 +140,13 @@ async def revoke_permission(
# ─── Permission Check Helper ───
async def check_user_file_permission(
db: AsyncSession, tenant_id: uuid.UUID, file_id: uuid.UUID, user_id: uuid.UUID, required: str = "read"
db: AsyncSession,
tenant_id: uuid.UUID,
file_id: uuid.UUID,
user_id: uuid.UUID,
required: str = "read",
) -> bool:
"""Check if user has required permission on a file."""
result = await db.execute(
@@ -158,6 +168,7 @@ async def check_user_file_permission(
# ─── Share Links ───
@router.post("/files/{file_id}/share-link")
async def create_share_link(
file_id: str,
@@ -219,6 +230,7 @@ async def revoke_share_link(
# ─── Public Share Access (NO AUTH) ───
@public_router.get("/share/{token}")
async def public_access(
token: str,
@@ -229,23 +241,20 @@ async def public_access(
Returns 410 Gone if link is expired.
Returns 403 if password is required but not provided/invalid.
"""
result = await db.execute(
select(ShareLink).where(ShareLink.token == token)
)
result = await db.execute(select(ShareLink).where(ShareLink.token == token))
link = result.scalar_one_or_none()
if link is None:
raise HTTPException(404, detail={"detail": "Share link not found", "code": "not_found"})
# Check expiry
if link.expires_at is not None:
now = datetime.now(timezone.utc)
now = datetime.now(UTC)
if now > link.expires_at:
raise HTTPException(410, detail={"detail": "Share link expired", "code": "expired"})
# Check password
if link.password_hash is not None:
# Password must be provided via query param or header — check query param
from fastapi import Request
# We need the request to get the password param
# For simplicity, return that password is required
raise HTTPException(
@@ -267,25 +276,27 @@ async def public_access_with_password(
db: AsyncSession = Depends(get_db),
):
"""Public share access with password verification — no auth required."""
result = await db.execute(
select(ShareLink).where(ShareLink.token == token)
)
result = await db.execute(select(ShareLink).where(ShareLink.token == token))
link = result.scalar_one_or_none()
if link is None:
raise HTTPException(404, detail={"detail": "Share link not found", "code": "not_found"})
# Check expiry
if link.expires_at is not None:
now = datetime.now(timezone.utc)
now = datetime.now(UTC)
if now > link.expires_at:
raise HTTPException(410, detail={"detail": "Share link expired", "code": "expired"})
# Verify password if required
if link.password_hash is not None:
if body.password is None:
raise HTTPException(401, detail={"detail": "Password required", "code": "password_required"})
raise HTTPException(
401, detail={"detail": "Password required", "code": "password_required"}
)
if not verify_password(body.password, link.password_hash):
raise HTTPException(403, detail={"detail": "Invalid password", "code": "invalid_password"})
raise HTTPException(
403, detail={"detail": "Invalid password", "code": "invalid_password"}
)
return {
"file_id": str(link.file_id),