mirror of
https://github.com/bellingcat/auto-archiver-api.git
synced 2026-06-12 13:38:33 +03:00
feat: /sheet endpoint and new security protocol
This commit is contained in:
63
src/main.py
63
src/main.py
@@ -15,17 +15,18 @@ from worker import create_archive_task, create_sheet_task, celery
|
||||
from db import crud, models, schemas
|
||||
from db.database import engine, SessionLocal
|
||||
from sqlalchemy.orm import Session
|
||||
from security import get_bearer_auth, get_basic_auth, bearer_security, get_bearer_auth_public
|
||||
from security import get_bearer_auth, get_basic_auth, bearer_security
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# Configuration
|
||||
ALLOWED_ORIGINS = os.environ.get("ALLOWED_ORIGINS", "chrome-extension://ondkcheoicfckabcnkdgbepofpjmjcmb,chrome-extension://ojcimmjndnlmmlgnjaeojoebaceokpdp").split(",")
|
||||
VERSION = "0.4.0"
|
||||
# min-version refers to the version of auto-archiver-extension on the webstore
|
||||
BREAKING_CHANGES = {"minVersion": "0.3.0", "message": "The latest update has breaking changes, please update the extension to the most recent version."}
|
||||
VERSION = "0.5.0"
|
||||
|
||||
app = FastAPI()
|
||||
# min-version refers to the version of auto-archiver-extension on the webstore
|
||||
BREAKING_CHANGES = {"minVersion": "0.3.1", "message": "The latest update has breaking changes, please update the extension to the most recent version."}
|
||||
|
||||
app = FastAPI(title="Auto-Archiver API", version=VERSION, contact={"name":"Bellingcat", "url":"https://github.com/bellingcat/auto-archiver-api"})
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=ALLOWED_ORIGINS,
|
||||
@@ -39,7 +40,14 @@ def get_db():
|
||||
session = SessionLocal()
|
||||
try: yield session
|
||||
finally: session.close()
|
||||
|
||||
|
||||
# logging configurations
|
||||
logger.add("logs/api_logs.log", retention="30 days", rotation="3 days")
|
||||
@app.middleware("http")
|
||||
async def logging_middleware(request: Request, call_next):
|
||||
response = await call_next(request)
|
||||
logger.info(f"{request.client.host}:{request.client.port} {request.method} {request.url._url} - HTTP {response.status_code}")
|
||||
return response
|
||||
|
||||
@app.get("/")
|
||||
async def home(request: Request):
|
||||
@@ -53,14 +61,6 @@ async def home(request: Request):
|
||||
except Exception as e: logger.error(e)
|
||||
return JSONResponse(status)
|
||||
|
||||
# logging configurations
|
||||
logger.add("logs/api_logs.log", retention="30 days", rotation="3 days")
|
||||
@app.middleware("http")
|
||||
async def logging_middleware(request: Request, call_next):
|
||||
response = await call_next(request)
|
||||
logger.info(f"{request.client.host}:{request.client.port} {request.method} {request.url._url} - HTTP {response.status_code}")
|
||||
return response
|
||||
|
||||
|
||||
# Bearer protected below
|
||||
|
||||
@@ -69,22 +69,17 @@ def get_user_groups(db: Session = Depends(get_db), email = Depends(get_bearer_au
|
||||
return crud.get_user_groups(db, email)
|
||||
|
||||
@app.get("/tasks/search-url", response_model=list[schemas.Archive])
|
||||
def search(url:str, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), _email = Depends(get_bearer_auth)):
|
||||
return crud.search_tasks_by_url(db, url, skip=skip, limit=limit)
|
||||
|
||||
# @app.get("/tasks/search", response_model=list[schemas.Task])
|
||||
# def search(skip: int = 0, limit: int = 100, db: Session = Depends(get_db), email = Depends(get_bearer_auth)):
|
||||
# return crud.get_tasks(db, skip=skip, limit=limit)
|
||||
def search(url:str, skip: int = 0, limit: int = 100, db: Session = Depends(get_db), email = Depends(get_bearer_auth)):
|
||||
return crud.search_tasks_by_url(db, url, email, skip=skip, limit=limit)
|
||||
|
||||
@app.get("/tasks/sync", response_model=list[schemas.Archive])
|
||||
def search(skip: int = 0, limit: int = 100, db: Session = Depends(get_db), email = Depends(get_bearer_auth)):
|
||||
return crud.search_tasks_by_email(db, email, skip=skip, limit=limit)
|
||||
|
||||
@app.post("/tasks", status_code=201)
|
||||
def run_task(archive:schemas.ArchiveCreate, email = Depends(get_bearer_auth)):
|
||||
def archive_sheet(archive:schemas.ArchiveCreate, email = Depends(get_bearer_auth)):
|
||||
archive.author_id = email
|
||||
url = archive.url
|
||||
logger.warning(archive)
|
||||
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}")
|
||||
@@ -92,22 +87,10 @@ def run_task(archive:schemas.ArchiveCreate, email = Depends(get_bearer_auth)):
|
||||
task = create_archive_task.delay(archive.json())
|
||||
return JSONResponse({"id": task.id})
|
||||
|
||||
# @app.post("/tasks", status_code=201)
|
||||
# def run_task(payload = Body(...), email = Depends(get_bearer_auth)):
|
||||
# url = payload.get('url')
|
||||
# public = payload.get('public', True)
|
||||
# group = payload.get('group', None)
|
||||
# logger.info(f"new {public=} task for {email=} and {group=}: {url}")
|
||||
# if type(url)!=str or len(url)<=5:
|
||||
# raise HTTPException(status_code=422, detail=f"Invalid URL received: {url}")
|
||||
# task = create_archive_task.delay(url=payload.get('url'), email=email, public=public, group=group)
|
||||
# return JSONResponse({"id": task.id})
|
||||
|
||||
@app.get("/tasks/{task_id}")
|
||||
def get_status(task_id, email = Depends(get_bearer_auth)):
|
||||
logger.info(f"status check for user {email}")
|
||||
task_result = AsyncResult(task_id, app=celery)
|
||||
logger.info(task_result)
|
||||
result = {
|
||||
"id": task_id,
|
||||
"status": task_result.status,
|
||||
@@ -116,7 +99,10 @@ def get_status(task_id, email = Depends(get_bearer_auth)):
|
||||
try:
|
||||
if task_result.result and "error" in task_result.result:
|
||||
result["status"] = "FAILURE"
|
||||
except Exception as e: logger.error(traceback.format_exc())
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
logger.error(traceback.format_exc())
|
||||
result["status"] = "FAILURE"
|
||||
try:
|
||||
json_result = jsonable_encoder(result, exclude_unset=True)
|
||||
return JSONResponse(json_result)
|
||||
@@ -131,7 +117,7 @@ def get_status(task_id, email = Depends(get_bearer_auth)):
|
||||
|
||||
|
||||
@app.delete("/tasks/{task_id}")
|
||||
def get_status(task_id, db: Session = Depends(get_db), email = Depends(get_bearer_auth)):
|
||||
def delete_task(task_id, db: Session = Depends(get_db), email = Depends(get_bearer_auth)):
|
||||
logger.info(f"deleting task {task_id} request by {email}")
|
||||
return JSONResponse({
|
||||
"id": task_id,
|
||||
@@ -139,8 +125,9 @@ def get_status(task_id, db: Session = Depends(get_db), email = Depends(get_beare
|
||||
})
|
||||
|
||||
@app.post("/sheet", status_code=201)
|
||||
def run_task(sheet:schemas.SubmitSheet, email = Depends(get_bearer_auth_public)):
|
||||
logger.info(f"LAUNCHING SHEET TASK for {email=}")
|
||||
def archive_sheet(sheet:schemas.SubmitSheet, email = Depends(get_bearer_auth)):
|
||||
logger.info(f"SHEET TASK for {sheet=}")
|
||||
sheet.author_id = email
|
||||
if not sheet.sheet_name and not sheet.sheet_id:
|
||||
raise HTTPException(status_code=422, detail=f"sheet name or id is required")
|
||||
task = create_sheet_task.delay(sheet.json())
|
||||
|
||||
Reference in New Issue
Block a user