diff --git a/spire/humbug/actions.py b/spire/humbug/actions.py index 98dce96..d56a70d 100644 --- a/spire/humbug/actions.py +++ b/spire/humbug/actions.py @@ -11,6 +11,7 @@ from .models import HumbugEvent, HumbugBugoutUser, HumbugBugoutUserToken from ..broodusers import bugout_api, BugoutAPICallFailed from ..utils.settings import ( + MAX_TAG_LENGTH, INSTALLATION_TOKEN, BOT_INSTALLATION_TOKEN_HEADER, auth_url_from_env, @@ -54,6 +55,12 @@ class HumbugTokenNotFound(Exception): """ +class HumbugTagTooLong(Exception): + """ + Raised on actions when put tag with len more then 256 symbols. + """ + + public_user_permission_at_journal = ["journals.read", "journals.entries.create"] @@ -187,9 +194,7 @@ def generate_humbug_dependencies( async def remove_humbug_dependencies( - db_session: Session, - token: UUID, - humbug_event: HumbugEvent, + db_session: Session, token: UUID, humbug_event: HumbugEvent, ) -> None: """ Delete autogenerated user and remove it from journal holders. @@ -355,9 +360,7 @@ async def create_humbug_user( Create bugout autogenerated user for Humbug integration. """ new_humbug_user = HumbugBugoutUser( - user_id=user_id, - access_token_id=access_token_id, - event_id=event_id, + user_id=user_id, access_token_id=access_token_id, event_id=event_id, ) db_session.add(new_humbug_user) db_session.commit() @@ -473,12 +476,16 @@ async def push_pack_to_journals_api( tags.append(f"reporter_token:{str(restricted_token)}") report.tags = tags + for tag in [tag for tag in report.tags if tag]: + if len(tag) > MAX_TAG_LENGTH: + raise HumbugTagTooLong(f"Tag {tag} is too long.") + entries_pack_request = JournalEntryListContent( entries=[ JournalEntryContent( title=report.title, content=report.content, - tags=report.tags, + tags=[tag for tag in report.tags if tag], context_id=str(restricted_token), context_type="humbug", created_at=report.created_at, diff --git a/spire/humbug/api.py b/spire/humbug/api.py index d1e230f..44353f5 100644 --- a/spire/humbug/api.py +++ b/spire/humbug/api.py @@ -1,6 +1,7 @@ from datetime import datetime import logging from uuid import UUID +import json from fastapi import ( FastAPI, @@ -17,6 +18,8 @@ from typing import List from sqlalchemy.orm import Session +from spire.utils.settings import MAX_TAG_LENGTH, MAX_TAGS_SIZE + from . import actions from .data import ( HumbugCreateReportTask, @@ -269,10 +272,7 @@ async def delete_humbug_integration_handler( ) background_tasks.add_task( - actions.remove_humbug_dependencies, - db_session, - user_token, - humbug_event, + actions.remove_humbug_dependencies, db_session, user_token, humbug_event, ) return HumbugIntegrationResponse( @@ -515,6 +515,11 @@ async def create_report( status_code=404, detail="Humbug integration not found in database" ) + if len("".join(report.tags)) > MAX_TAGS_SIZE: + raise HTTPException( + status_code=400, detail=f"Tags size limit is {MAX_TAGS_SIZE} Bytes" + ) + if store_ip: client_ips = actions.process_ip_headers( request.headers.get("x-forwarded-for", None) @@ -528,8 +533,7 @@ async def create_report( redis_client.rpush( REDIS_REPORTS_QUEUE, HumbugCreateReportTask( - report=report, - bugout_token=restricted_token, + report=report, bugout_token=restricted_token, ).json(), ) except Exception as err: @@ -553,6 +557,10 @@ async def create_report( raise HTTPException( status_code=404, detail="Humbug integration not found in database" ) + except actions.HumbugTagTooLong as err: + raise HTTPException( + status_code=400, detail=f"Tag size limit is {MAX_TAG_LENGTH} Bytes", + ) except Exception as err: logger.error(str(err)) raise HTTPException(status_code=500) @@ -585,10 +593,14 @@ async def bulk_create_reports( if not sync: reports_pack = [] for report in reports_list: + if len("".join(report.tags)) > MAX_TAGS_SIZE: + raise HTTPException( + status_code=400, detail=f"Tags size limit is {MAX_TAGS_SIZE} Bytes" + ) + reports_pack.append( HumbugCreateReportTask( - report=report, - bugout_token=restricted_token, + report=report, bugout_token=restricted_token, ).json() ) @@ -596,8 +608,7 @@ async def bulk_create_reports( redis_client = db.redis_connection() redis_client.rpush( - REDIS_REPORTS_QUEUE, - *reports_pack, + REDIS_REPORTS_QUEUE, *reports_pack, ) except Exception as err: logger.error(f"Error bulk push reports to redis: {err}") @@ -620,6 +631,10 @@ async def bulk_create_reports( raise HTTPException( status_code=404, detail="Humbug integration not found in database" ) + except actions.HumbugTagTooLong as err: + raise HTTPException( + status_code=400, detail=f"Tag size limit is {MAX_TAG_LENGTH} Bytes", + ) except Exception as err: logger.error(str(err)) raise HTTPException(status_code=500) diff --git a/spire/utils/settings.py b/spire/utils/settings.py index f9cd297..f1efb03 100644 --- a/spire/utils/settings.py +++ b/spire/utils/settings.py @@ -2,6 +2,8 @@ import os from typing import Any, cast, Union +from spire.humbug.actions import HumbugTagTooLong + class BugoutAuthConfigurationError(ValueError): """ @@ -10,6 +12,9 @@ class BugoutAuthConfigurationError(ValueError): """ +HUMBUG_REPORTS_MAX_TAG_LENGTH = os.getenv("HUMBUG_REPORTS_MAX_TAG_LENGTH", 256) +HUMBUG_REPORTS_MAX_TAGS_SIZE = os.getenv("HUMBUG_REPORTS_MAX_TAGS_SIZE", 512 * 1024) + BUGOUT_TIMEOUT_SECONDS_RAW = os.environ.get("BUGOUT_TIMEOUT_SECONDS", 5) try: BUGOUT_TIMEOUT_SECONDS = int(BUGOUT_TIMEOUT_SECONDS_RAW)