Sentry file, and header linting hints
This commit is contained in:
@@ -0,0 +1,3 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Binwalk Analyzer for Image Submissions."""
|
"""Binwalk Analyzer for Image Submissions."""
|
||||||
|
|
||||||
import shutil
|
import shutil
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Bits Decomposer Analyzer for Image Submissions."""
|
"""Bits Decomposer Analyzer for Image Submissions."""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Exiftool Analyzer for Image Submissions."""
|
"""Exiftool Analyzer for Image Submissions."""
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Foremost Analyzer for Image Submissions."""
|
"""Foremost Analyzer for Image Submissions."""
|
||||||
|
|
||||||
import shutil
|
import shutil
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Image size bruteforcer for common PNG sizes."""
|
"""Image size bruteforcer for common PNG sizes."""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""OpenStego Analyzer for Image Submissions."""
|
"""OpenStego Analyzer for Image Submissions."""
|
||||||
|
|
||||||
import shutil
|
import shutil
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Outguess Analyzer for Image Submissions."""
|
"""Outguess Analyzer for Image Submissions."""
|
||||||
|
|
||||||
import shutil
|
import shutil
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Pngcheck Analyzer for Image Submissions."""
|
"""Pngcheck Analyzer for Image Submissions."""
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Steghide Analyzer for Image Submissions."""
|
"""Steghide Analyzer for Image Submissions."""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Strings Analyzer for Image Submissions."""
|
"""Strings Analyzer for Image Submissions."""
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Custom Analyzer for Image Submissions."""
|
"""Custom Analyzer for Image Submissions."""
|
||||||
|
|
||||||
import shutil
|
import shutil
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Utility functions for analyzers modules."""
|
"""Utility functions for analyzers modules."""
|
||||||
|
|
||||||
import fcntl
|
import fcntl
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Zsteg Analyzer for Image Submissions."""
|
"""Zsteg Analyzer for Image Submissions."""
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|||||||
+7
-32
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Aperi'Solve Flask application."""
|
"""Aperi'Solve Flask application."""
|
||||||
|
|
||||||
import hashlib
|
import hashlib
|
||||||
@@ -9,46 +12,18 @@ from pathlib import Path
|
|||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
from sentry_sdk.integrations.flask import FlaskIntegration
|
|
||||||
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
|
||||||
from sentry_sdk.integrations.rq import RqIntegration
|
|
||||||
from sentry_sdk.integrations.threading import ThreadingIntegration
|
|
||||||
|
|
||||||
from flask import Flask, Response, abort, jsonify, render_template, request, send_file
|
from flask import Flask, Response, abort, jsonify, render_template, request, send_file
|
||||||
from redis import Redis
|
from redis import Redis
|
||||||
from rq import Queue
|
from rq import Queue
|
||||||
|
|
||||||
|
from .sentry import initialize_sentry
|
||||||
|
|
||||||
|
initialize_sentry()
|
||||||
|
|
||||||
from .cleanup import cleanup_old_entries
|
from .cleanup import cleanup_old_entries
|
||||||
from .config import IMAGE_EXTENSIONS, RESULT_FOLDER, WORKER_FILES
|
from .config import IMAGE_EXTENSIONS, RESULT_FOLDER, WORKER_FILES
|
||||||
from .models import Image, Submission, db, init_db
|
from .models import Image, Submission, db, init_db
|
||||||
|
|
||||||
SENTRY_DSN = os.environ.get("SENTRY_DSN")
|
|
||||||
ENVIRONMENT = os.environ.get("ENVIRONMENT", "development")
|
|
||||||
|
|
||||||
if SENTRY_DSN:
|
|
||||||
sentry_sdk.init(
|
|
||||||
dsn=SENTRY_DSN,
|
|
||||||
integrations=[
|
|
||||||
FlaskIntegration(),
|
|
||||||
SqlalchemyIntegration(),
|
|
||||||
RqIntegration(),
|
|
||||||
ThreadingIntegration(propagate_hub=True),
|
|
||||||
],
|
|
||||||
# Set traces_sample_rate to 1.0 to capture 100% of transactions for performance monitoring.
|
|
||||||
# Adjust this value in production (e.g., 0.1 for 10%)
|
|
||||||
traces_sample_rate=float(os.environ.get("SENTRY_TRACES_SAMPLE_RATE", "0.1")),
|
|
||||||
# Set profiles_sample_rate to 1.0 to profile 100% of sampled transactions.
|
|
||||||
profiles_sample_rate=float(os.environ.get("SENTRY_PROFILES_SAMPLE_RATE", "0.1")),
|
|
||||||
# Environment tag (production, staging, development)
|
|
||||||
environment=ENVIRONMENT,
|
|
||||||
# Release version (use git commit hash or version number)
|
|
||||||
release=os.environ.get("SENTRY_RELEASE", "1.0.0"),
|
|
||||||
# Send default PII (user IPs, etc.) - set to False for privacy
|
|
||||||
send_default_pii=False,
|
|
||||||
# Enable automatic breadcrumb tracking
|
|
||||||
enable_tracing=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
app: Flask = Flask(__name__)
|
app: Flask = Flask(__name__)
|
||||||
app.json.sort_keys = False # type: ignore
|
app.json.sort_keys = False # type: ignore
|
||||||
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DB_URI")
|
app.config["SQLALCHEMY_DATABASE_URI"] = os.environ.get("DB_URI")
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Cleanup old entries in the database and file system."""
|
"""Cleanup old entries in the database and file system."""
|
||||||
|
|
||||||
import shutil
|
import shutil
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Aperi'Solve configuration variables."""
|
"""Aperi'Solve configuration variables."""
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""This module defines the database models for the Aperi'Solve application."""
|
"""This module defines the database models for the Aperi'Solve application."""
|
||||||
|
|
||||||
import itertools
|
import itertools
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
|
"""Sentry initialization for Aperisolve."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import sentry_sdk
|
||||||
|
from sentry_sdk.integrations.flask import FlaskIntegration
|
||||||
|
from sentry_sdk.integrations.rq import RqIntegration
|
||||||
|
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
||||||
|
from sentry_sdk.integrations.threading import ThreadingIntegration
|
||||||
|
|
||||||
|
SENTRY_DSN = os.environ.get("SENTRY_DSN")
|
||||||
|
ENVIRONMENT = os.environ.get("ENVIRONMENT", "development")
|
||||||
|
|
||||||
|
|
||||||
|
def initialize_sentry() -> None:
|
||||||
|
"""Initialize Sentry SDK once, safely."""
|
||||||
|
|
||||||
|
# No DSN → do nothing
|
||||||
|
dsn = os.environ.get("SENTRY_DSN")
|
||||||
|
if not dsn:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Prevent double initialization (Flask + RQ, CLI, tests, etc.)
|
||||||
|
if sentry_sdk.Hub.current.client is not None:
|
||||||
|
return
|
||||||
|
|
||||||
|
sentry_sdk.init(
|
||||||
|
dsn=dsn,
|
||||||
|
integrations=[
|
||||||
|
FlaskIntegration(),
|
||||||
|
SqlalchemyIntegration(),
|
||||||
|
RqIntegration(),
|
||||||
|
ThreadingIntegration(propagate_hub=True),
|
||||||
|
],
|
||||||
|
traces_sample_rate=float(os.environ.get("SENTRY_TRACES_SAMPLE_RATE", "0.1")),
|
||||||
|
profiles_sample_rate=float(
|
||||||
|
os.environ.get("SENTRY_PROFILES_SAMPLE_RATE", "0.1")
|
||||||
|
),
|
||||||
|
environment=os.environ.get("ENVIRONMENT", "development"),
|
||||||
|
release=os.environ.get("SENTRY_RELEASE", "1.0.0"),
|
||||||
|
send_default_pii=False,
|
||||||
|
enable_tracing=True,
|
||||||
|
)
|
||||||
+10
-24
@@ -1,32 +1,19 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Asynchronous worker for analyzing image submissions."""
|
"""Asynchronous worker for analyzing image submissions."""
|
||||||
|
|
||||||
import os
|
|
||||||
import threading
|
import threading
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
import sentry_sdk
|
import sentry_sdk
|
||||||
from sentry_sdk.integrations.rq import RqIntegration
|
|
||||||
from sentry_sdk.integrations.threading import ThreadingIntegration
|
|
||||||
from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
|
|
||||||
|
|
||||||
# Initialize Sentry for workers (separate process from Flask app)
|
from .sentry import initialize_sentry
|
||||||
SENTRY_DSN = os.environ.get("SENTRY_DSN")
|
|
||||||
if SENTRY_DSN:
|
|
||||||
sentry_sdk.init(
|
|
||||||
dsn=SENTRY_DSN,
|
|
||||||
integrations=[
|
|
||||||
RqIntegration(),
|
|
||||||
ThreadingIntegration(propagate_hub=True), # Capture exceptions in threads
|
|
||||||
SqlalchemyIntegration(),
|
|
||||||
],
|
|
||||||
traces_sample_rate=float(os.environ.get("SENTRY_TRACES_SAMPLE_RATE", "0.1")),
|
|
||||||
environment=os.environ.get("ENVIRONMENT", "development"),
|
|
||||||
release=os.environ.get("SENTRY_RELEASE", "1.0.0"),
|
|
||||||
send_default_pii=False,
|
|
||||||
)
|
|
||||||
|
|
||||||
from .analyzers.binwalk import analyze_binwalk
|
initialize_sentry()
|
||||||
|
|
||||||
|
from .analyzers.binwalk import analyze_binwalk # pylint: disable=C0413
|
||||||
from .analyzers.decomposer import analyze_decomposer
|
from .analyzers.decomposer import analyze_decomposer
|
||||||
from .analyzers.exiftool import analyze_exiftool
|
from .analyzers.exiftool import analyze_exiftool
|
||||||
from .analyzers.foremost import analyze_foremost
|
from .analyzers.foremost import analyze_foremost
|
||||||
@@ -74,8 +61,7 @@ def analyze_image(submission_hash: str) -> None:
|
|||||||
|
|
||||||
if not submission or not image: # No submission found
|
if not submission or not image: # No submission found
|
||||||
sentry_sdk.capture_message(
|
sentry_sdk.capture_message(
|
||||||
f"Submission or image not found: {submission_hash}",
|
f"Submission or image not found: {submission_hash}", level="warning"
|
||||||
level="warning"
|
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -127,10 +113,10 @@ def analyze_image(submission_hash: str) -> None:
|
|||||||
for thread in threads:
|
for thread in threads:
|
||||||
thread.join()
|
thread.join()
|
||||||
|
|
||||||
submission.status = "completed"
|
submission.status = "completed" # type: ignore
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
sentry_sdk.capture_exception(e)
|
sentry_sdk.capture_exception(e)
|
||||||
submission.status = "error"
|
submission.status = "error" # type: ignore
|
||||||
finally:
|
finally:
|
||||||
db.session.commit() # pylint: disable=no-member
|
db.session.commit() # pylint: disable=no-member
|
||||||
# Flush Sentry events - wait up to 5 seconds for events to be sent
|
# Flush Sentry events - wait up to 5 seconds for events to be sent
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# flake8: noqa: E203,E501,W503
|
||||||
|
# pylint: disable=C0413,W0718,R0903,R0801
|
||||||
|
# mypy: disable-error-code=unused-awaitable
|
||||||
"""Aperi'Solve WSGI runner."""
|
"""Aperi'Solve WSGI runner."""
|
||||||
|
|
||||||
from .app import app as application
|
from .app import app as application
|
||||||
|
|||||||
Reference in New Issue
Block a user