mirror of
https://github.com/bellingcat/auto-archiver-api.git
synced 2026-06-11 21:18:35 +03:00
pushing bulk of changes
This commit is contained in:
@@ -6,8 +6,9 @@ from sqlalchemy.orm import Session
|
||||
from core.config import VERSION, BREAKING_CHANGES
|
||||
from core.logging import log_error
|
||||
from db import crud, schemas
|
||||
from db.database import get_db_dependency, get_db
|
||||
from web.security import get_user_auth, bearer_security
|
||||
from db.database import get_db_dependency
|
||||
from db.user_state import UserState
|
||||
from web.security import get_user_auth, bearer_security, get_active_user_state
|
||||
|
||||
default_router = APIRouter()
|
||||
|
||||
@@ -18,8 +19,7 @@ async def home(request: Request):
|
||||
status = {"version": VERSION, "breakingChanges": BREAKING_CHANGES}
|
||||
try:
|
||||
email = await get_user_auth(await bearer_security(request))
|
||||
with get_db() as db:
|
||||
status["groups"] = crud.get_user_groups(db, email)
|
||||
status["groups"] = crud.get_user_groups(email)
|
||||
except HTTPException: pass # not authenticated is fine
|
||||
except Exception as e: log_error(e)
|
||||
return JSONResponse(status)
|
||||
@@ -31,13 +31,28 @@ async def health():
|
||||
|
||||
|
||||
@default_router.get("/user/active", summary="Check if the user is active and can use the tool.")
|
||||
# TODO: reorder db dependencies to after auth
|
||||
async def active(db: Session = Depends(get_db_dependency), email=Depends(get_user_auth)) -> schemas.ActiveUser:
|
||||
return {"active": crud.is_active_user(db, email)}
|
||||
|
||||
|
||||
@default_router.get("/groups")
|
||||
def get_user_groups(db: Session = Depends(get_db_dependency), email=Depends(get_user_auth)) -> list[str]:
|
||||
return crud.get_user_groups(db, email)
|
||||
def get_user_groups(email=Depends(get_user_auth)) -> list[str]:
|
||||
return crud.get_user_groups(email)
|
||||
|
||||
|
||||
@default_router.get("/permissions")
|
||||
def get_user_groups(
|
||||
user: UserState = Depends(get_active_user_state),
|
||||
) -> list[str]:
|
||||
return JSONResponse({
|
||||
"groups": user.user_groups_names,
|
||||
"allowedFrequencies": list(user.allowed_frequencies),
|
||||
"sheet_quota": user.sheet_quota,
|
||||
"monthly_urls": user.monthly_urls,
|
||||
"monthly_mbs": user.monthly_mbs,
|
||||
#TODO: should this return
|
||||
})
|
||||
|
||||
|
||||
@default_router.get('/favicon.ico', include_in_schema=False)
|
||||
|
||||
@@ -5,7 +5,8 @@ from fastapi.responses import JSONResponse
|
||||
from sqlalchemy import exc
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from web.security import token_api_key_auth, get_active_user_auth
|
||||
from db.user_state import UserState
|
||||
from web.security import token_api_key_auth, get_active_user_auth, get_active_user_state
|
||||
from db import schemas, crud
|
||||
from db.database import get_db_dependency
|
||||
from worker.main import create_sheet_task
|
||||
@@ -16,19 +17,21 @@ sheet_router = APIRouter(prefix="/sheet", tags=["Google Spreadsheet operations"]
|
||||
@sheet_router.post("/create", status_code=201, summary="Store a new Google Sheet for regular archiving.")
|
||||
def create_sheet(
|
||||
sheet: schemas.SheetAdd,
|
||||
email=Depends(get_active_user_auth),
|
||||
user: UserState = Depends(get_active_user_state),
|
||||
db: Session = Depends(get_db_dependency),
|
||||
) -> schemas.SheetResponse:
|
||||
user_groups_names = crud.get_user_groups(db, email)
|
||||
|
||||
if sheet.group_id not in user_groups_names:
|
||||
if not user.in_group(sheet.group_id):
|
||||
raise HTTPException(status_code=403, detail="User does not have access to this group.")
|
||||
|
||||
if not crud.has_quota_sheet(db, email, user_groups_names):
|
||||
if not user.has_quota_sheet():
|
||||
raise HTTPException(status_code=429, detail="User has reached their sheet quota.")
|
||||
|
||||
if not user.is_sheet_frequency_allowed(sheet.frequency):
|
||||
raise HTTPException(status_code=422, detail=f"Invalid frequency: {sheet.frequency}. Must be one of {user.allowed_frequencies}")
|
||||
|
||||
try:
|
||||
return crud.create_sheet(db, sheet.id, sheet.name, email, sheet.group_id, sheet.frequency)
|
||||
return crud.create_sheet(db, sheet.id, sheet.name, user.email, sheet.group_id, sheet.frequency)
|
||||
except exc.IntegrityError as e:
|
||||
raise HTTPException(status_code=400, detail="Sheet with this ID already exists.") from e
|
||||
|
||||
@@ -56,22 +59,30 @@ def delete_sheet(
|
||||
@sheet_router.post("/{id}/archive", status_code=201, summary="Trigger an archiving task for a GSheet you own.", response_description="task_id for the archiving task.")
|
||||
def archive_user_sheet(
|
||||
id: str,
|
||||
email=Depends(get_active_user_auth),
|
||||
user: UserState = Depends(get_active_user_state),
|
||||
db: Session = Depends(get_db_dependency),
|
||||
) -> schemas.Task:
|
||||
|
||||
#TODO: are we enabling manual triggers?
|
||||
# if not user.can_manually_trigger():
|
||||
# raise HTTPException(status_code=429, detail="User cannot manually trigger archiving tasks.")
|
||||
|
||||
sheet = crud.get_user_sheet(db, email, sheet_id=id)
|
||||
sheet = crud.get_user_sheet(db, user.email, sheet_id=id)
|
||||
if not sheet:
|
||||
raise HTTPException(status_code=403, detail="No access to this sheet.")
|
||||
|
||||
task = create_sheet_task.delay(schemas.SubmitSheet(sheet_id=id, author_id=email, group=sheet.group_id).model_dump_json())
|
||||
# TODO: what happens if user is taken out of group after sheet is created? this should be checked in a cronjob that notifies the user
|
||||
if not user.in_group(sheet.group_id):
|
||||
raise HTTPException(status_code=403, detail="User does not have access to this group.")
|
||||
|
||||
task = create_sheet_task.delay(schemas.SubmitSheet(sheet_id=id, author_id=user.email, group=sheet.group_id).model_dump_json())
|
||||
|
||||
return JSONResponse({"id": task.id}, status_code=201)
|
||||
|
||||
|
||||
@sheet_router.post("/archive", status_code=201, summary="Trigger an archiving task for any GSheet with an API token.", response_description="task_id for the archiving task.")
|
||||
def archive_sheet(
|
||||
sheet: schemas.SubmitSheet, #TODO: replace with simpler model
|
||||
sheet: schemas.SubmitSheet, # TODO: replace with simpler model
|
||||
auth=Depends(token_api_key_auth)
|
||||
) -> schemas.Task:
|
||||
sheet.author_id = sheet.author_id or "api-endpoint"
|
||||
|
||||
@@ -8,7 +8,7 @@ from web.security import get_user_auth, get_token_or_user_auth
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from db import crud, schemas
|
||||
from db.database import get_db_dependency
|
||||
from db.database import get_db, get_db_dependency
|
||||
|
||||
from worker.main import create_archive_task
|
||||
|
||||
@@ -16,14 +16,28 @@ url_router = APIRouter(prefix="/url", tags=["Single URL operations"])
|
||||
|
||||
|
||||
@url_router.post("/archive", status_code=201, summary="Submit a single URL archive request, starts an archiving task.", response_description="task_id for the archiving task, will match the archive id.")
|
||||
def archive_url(archive: schemas.ArchiveCreate, email=Depends(get_token_or_user_auth)) -> schemas.Task:
|
||||
archive.author_id = email
|
||||
url = archive.url
|
||||
logger.info(f"new {archive.public=} task for {email=} and {archive.group_id=}: {url}")
|
||||
if type(url) != str or len(url) <= 5:
|
||||
raise HTTPException(status_code=422, detail=f"Invalid URL received: {url}")
|
||||
logger.info("creating task")
|
||||
task = create_archive_task.delay(archive.model_dump_json())
|
||||
def archive_url(
|
||||
archive: schemas.ArchiveTrigger,
|
||||
email=Depends(get_token_or_user_auth)
|
||||
) -> schemas.Task:
|
||||
logger.info(f"new {archive.public=} task for {email=} and {archive.group_id=}: {archive.url}")
|
||||
|
||||
# TODO: implement quota
|
||||
|
||||
if archive.group_id:
|
||||
with get_db() as db:
|
||||
if not crud.is_user_in_group(db, email, archive.group_id):
|
||||
raise HTTPException(status_code=403, detail="User does not have access to this group.")
|
||||
|
||||
# TODO: deprecate ArchiveCreate
|
||||
backwards_compatible_archive = schemas.ArchiveCreate(
|
||||
url=archive.url,
|
||||
author_id=email,
|
||||
group_id=archive.group_id,
|
||||
public=archive.public,
|
||||
)
|
||||
|
||||
task = create_archive_task.delay(backwards_compatible_archive.model_dump_json())
|
||||
task_response = schemas.Task(id=task.id)
|
||||
return JSONResponse(task_response.model_dump(), status_code=201)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user