bugbounty_gpt/__main__.py (72 lines of code) (raw):

import logging import asyncio from bugbounty_gpt.db import db_handler from bugbounty_gpt.db.models import SubmissionState from bugbounty_gpt.handlers.openai_handler import OpenAIHandler from bugbounty_gpt.handlers.submission_handler import BugCrowdSubmission from bugbounty_gpt.handlers.bugcrowd_api import BugCrowdAPI from bugbounty_gpt.env import USER_ID, FILTER_PROGRAM, RESPONSE_CATEGORIES, SQLALCHEMY_URL from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine from sqlalchemy.orm import sessionmaker logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') logger = logging.getLogger(__name__) logger.info("Configuration is valid.") logger.info("Initializing database connection.") engine = create_async_engine(SQLALCHEMY_URL, echo=False) SessionLocal = sessionmaker( bind=engine, class_=AsyncSession, expire_on_commit=False, ) SEEN_SUBMISSIONS = [] async def process_new_submissions(): """ Fetch and process new submissions that are not duplicates and store them in the database. """ params = { 'filter[program]': FILTER_PROGRAM, 'filter[state]': 'new', 'filter[duplicate]': 'false' } async with SessionLocal() as session: if (submissions := await BugCrowdAPI.fetch_submissions(params)) is not None: for submission in submissions: # Submission processing submission_id = submission['id'] if submission_id in SEEN_SUBMISSIONS: continue user_id = submission['relationships']['researcher']['data']['id'] submission_content = submission['attributes']['description'] classification, reasoning = await OpenAIHandler.classify_submission(submission_content) submission_data = { 'submission_id': submission_id, 'user_id': user_id, 'classification': classification, 'submission_state': SubmissionState.NEW, 'reasoning': reasoning } SEEN_SUBMISSIONS.append(submission_id) await db_handler.insert_submission(session, submission_data) async def process_in_scope_submissions(): """ Process submissions that are in scope by generating comments, assigning users, closing submissions, and updating their state in the database. """ async with SessionLocal() as session: states = [SubmissionState.NEW] classifications = RESPONSE_CATEGORIES # Using the RESPONSE_CATEGORIES from config in_scope_submissions = await db_handler.fetch_submission_by_state_and_classification(session, states, classifications) for submission_data in in_scope_submissions: submission = BugCrowdSubmission(submission_data.submission_id, submission_data.classification, submission_data.reasoning) user_id = USER_ID # From config if await submission.is_submission_new(): comment_body = submission.generate_comment_text() if comment_body: await submission.create_comment(comment_body) await submission.close_submission() await db_handler.update_submission_state(session, submission.submission_id, SubmissionState.UPDATED) else: await db_handler.update_submission_state(session, submission.submission_id, SubmissionState.UPDATED_OUT_OF_BAND) async def main(): """ Main loop that repeatedly fetches and processes new submissions and in-scope submissions. """ while True: logger.info("Fetching and processing new submissions...") await process_new_submissions() logger.info("Processing in-scope submissions...") await process_in_scope_submissions() minutes_waited = 1 logger.info(f"Doing nothing for {minutes_waited} minutes....") await asyncio.sleep(60 * minutes_waited) if __name__ == "__main__": asyncio.run(main())