fix: add security checks and tests for code review
Security: - Add authorization checks to list_packages, update_package, delete_package endpoints - Add MAX_TOTAL_ARTIFACTS limit (1000) to prevent memory exhaustion during dependency resolution - Add TooManyArtifactsError exception for proper error handling UI: - Display reverse dependency errors in PackagePage - Add warning display for failed dependency fetches in DependencyGraph Tests: - Add unit tests for metadata extraction (deb, wheel, tarball, jar) - Add unit tests for rate limit configuration - Add unit tests for PyPI registry client
This commit is contained in:
@@ -147,6 +147,7 @@ from .dependencies import (
|
||||
DependencyConflictError,
|
||||
DependencyNotFoundError,
|
||||
DependencyDepthExceededError,
|
||||
TooManyArtifactsError,
|
||||
)
|
||||
from .config import get_settings, get_env_upstream_sources
|
||||
from .checksum import (
|
||||
@@ -2666,10 +2667,10 @@ def list_packages(
|
||||
format: Optional[str] = Query(default=None, description="Filter by package format"),
|
||||
platform: Optional[str] = Query(default=None, description="Filter by platform"),
|
||||
db: Session = Depends(get_db),
|
||||
current_user: Optional[User] = Depends(get_current_user_optional),
|
||||
):
|
||||
project = db.query(Project).filter(Project.name == project_name).first()
|
||||
if not project:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
# Check read access (handles private project visibility)
|
||||
project = check_project_access(db, project_name, current_user, "read")
|
||||
|
||||
# Validate sort field
|
||||
valid_sort_fields = {
|
||||
@@ -2950,13 +2951,13 @@ def update_package(
|
||||
package_update: PackageUpdate,
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: Optional[User] = Depends(get_current_user_optional),
|
||||
):
|
||||
"""Update a package's metadata."""
|
||||
user_id = get_user_id(request)
|
||||
|
||||
project = db.query(Project).filter(Project.name == project_name).first()
|
||||
if not project:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
# Check write access to project
|
||||
project = check_project_access(db, project_name, current_user, "write")
|
||||
|
||||
package = (
|
||||
db.query(Package)
|
||||
@@ -3033,6 +3034,7 @@ def delete_package(
|
||||
package_name: str,
|
||||
request: Request,
|
||||
db: Session = Depends(get_db),
|
||||
current_user: Optional[User] = Depends(get_current_user_optional),
|
||||
):
|
||||
"""
|
||||
Delete a package and all its versions.
|
||||
@@ -3043,9 +3045,8 @@ def delete_package(
|
||||
"""
|
||||
user_id = get_user_id(request)
|
||||
|
||||
project = db.query(Project).filter(Project.name == project_name).first()
|
||||
if not project:
|
||||
raise HTTPException(status_code=404, detail="Project not found")
|
||||
# Check write access to project (deletion requires write permission)
|
||||
project = check_project_access(db, project_name, current_user, "write")
|
||||
|
||||
package = (
|
||||
db.query(Package)
|
||||
@@ -7137,6 +7138,15 @@ async def resolve_artifact_dependencies(
|
||||
"max_depth": e.max_depth,
|
||||
}
|
||||
)
|
||||
except TooManyArtifactsError as e:
|
||||
raise HTTPException(
|
||||
status_code=400,
|
||||
detail={
|
||||
"error": "too_many_artifacts",
|
||||
"message": str(e),
|
||||
"max_artifacts": e.max_artifacts,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
# --- Upstream Caching Routes ---
|
||||
|
||||
Reference in New Issue
Block a user