sprint1 complete: rate limiting on permission changes + sprint1 fully done
This commit is contained in:
@@ -9,6 +9,7 @@ from fastapi import APIRouter, Depends, HTTPException, Query, status
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
from sqlalchemy.ext.asyncio import AsyncSession
|
||||||
|
|
||||||
from app.core.db import get_db
|
from app.core.db import get_db
|
||||||
|
from app.core.rate_limit import check_rate_limit
|
||||||
from app.deps import get_current_user, get_redis_dep, require_permission
|
from app.deps import get_current_user, get_redis_dep, require_permission
|
||||||
from app.schemas.entity_permission import (
|
from app.schemas.entity_permission import (
|
||||||
EntityPermissionCreate,
|
EntityPermissionCreate,
|
||||||
@@ -18,6 +19,10 @@ from app.services import entity_permission_service
|
|||||||
|
|
||||||
router = APIRouter(prefix="/api/v1/permissions", tags=["entity-permissions"])
|
router = APIRouter(prefix="/api/v1/permissions", tags=["entity-permissions"])
|
||||||
|
|
||||||
|
# Rate limits for permission changes (prevent abuse/DoS)
|
||||||
|
_PERM_RATE_LIMIT_MAX = 50 # max changes per minute
|
||||||
|
_PERM_RATE_LIMIT_WINDOW = 60 # 60 seconds
|
||||||
|
|
||||||
|
|
||||||
@router.get("/{entity_type}/{entity_id}")
|
@router.get("/{entity_type}/{entity_id}")
|
||||||
async def list_entity_permissions(
|
async def list_entity_permissions(
|
||||||
@@ -48,6 +53,12 @@ async def create_entity_permission(
|
|||||||
"""Grant or update a permission on any entity for a user, group, role, or guest."""
|
"""Grant or update a permission on any entity for a user, group, role, or guest."""
|
||||||
tenant_id = uuid.UUID(current_user["tenant_id"])
|
tenant_id = uuid.UUID(current_user["tenant_id"])
|
||||||
user_id = uuid.UUID(current_user["user_id"])
|
user_id = uuid.UUID(current_user["user_id"])
|
||||||
|
# Rate limit: max 50 permission changes per minute per user
|
||||||
|
await check_rate_limit(
|
||||||
|
f"perm_change:{user_id}",
|
||||||
|
_PERM_RATE_LIMIT_MAX,
|
||||||
|
_PERM_RATE_LIMIT_WINDOW,
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
return await entity_permission_service.create_permission(
|
return await entity_permission_service.create_permission(
|
||||||
db,
|
db,
|
||||||
@@ -75,6 +86,12 @@ async def update_entity_permission(
|
|||||||
):
|
):
|
||||||
"""Update an existing permission entry."""
|
"""Update an existing permission entry."""
|
||||||
tenant_id = uuid.UUID(current_user["tenant_id"])
|
tenant_id = uuid.UUID(current_user["tenant_id"])
|
||||||
|
user_id = uuid.UUID(current_user["user_id"])
|
||||||
|
await check_rate_limit(
|
||||||
|
f"perm_change:{user_id}",
|
||||||
|
_PERM_RATE_LIMIT_MAX,
|
||||||
|
_PERM_RATE_LIMIT_WINDOW,
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
return await entity_permission_service.update_permission(
|
return await entity_permission_service.update_permission(
|
||||||
db,
|
db,
|
||||||
@@ -97,6 +114,12 @@ async def delete_entity_permission(
|
|||||||
):
|
):
|
||||||
"""Revoke a permission entry."""
|
"""Revoke a permission entry."""
|
||||||
tenant_id = uuid.UUID(current_user["tenant_id"])
|
tenant_id = uuid.UUID(current_user["tenant_id"])
|
||||||
|
user_id = uuid.UUID(current_user["user_id"])
|
||||||
|
await check_rate_limit(
|
||||||
|
f"perm_change:{user_id}",
|
||||||
|
_PERM_RATE_LIMIT_MAX,
|
||||||
|
_PERM_RATE_LIMIT_WINDOW,
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
await entity_permission_service.delete_permission(db, tenant_id, permission_id)
|
await entity_permission_service.delete_permission(db, tenant_id, permission_id)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user