Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

!feat: secure most of api behind api_key #799

Merged
merged 6 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ HARD_RESET=false
# This will attempt to fix broken symlinks in the library, and then exit after running!
REPAIR_SYMLINKS=false

# Manual api key, must be 32 characters long
API_KEY=1234567890qwertyuiopas

# This is the number of workers to use for reindexing symlinks after a database reset.
# More workers = faster symlinking but uses more memory.
# For lower end machines, stick to around 1-3.
Expand Down
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ rank-torrent-name = "^1.0.2"
jsonschema = "^4.23.0"
scalar-fastapi = "^1.0.3"
psutil = "^6.0.0"
python-dotenv = "^1.0.1"

[tool.poetry.group.dev.dependencies]
pyright = "^1.1.352"
Expand Down
14 changes: 14 additions & 0 deletions src/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from fastapi import HTTPException, Security, status
from fastapi.security import APIKeyHeader
from program.settings.manager import settings_manager

api_key_header = APIKeyHeader(name="x-api-key")

def resolve_api_key(api_key_header: str = Security(api_key_header)):
if api_key_header == settings_manager.settings.api_key:
return True
else:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Missing or invalid API key"
)
5 changes: 0 additions & 5 deletions src/controllers/models/shared.py

This file was deleted.

30 changes: 9 additions & 21 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,17 @@
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request

from controllers.default import router as default_router
from controllers.items import router as items_router
from controllers.scrape import router as scrape_router
from controllers.settings import router as settings_router
from controllers.tmdb import router as tmdb_router
from controllers.webhooks import router as webhooks_router
from controllers.ws import router as ws_router
from scalar_fastapi import get_scalar_api_reference
from program import Program
from program.settings.models import get_version
from routers import app_router
from scalar_fastapi import get_scalar_api_reference
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.requests import Request
from utils.cli import handle_args
from utils.logger import logger
from loguru import logger
from dotenv import load_dotenv

load_dotenv()


class LoguruMiddleware(BaseHTTPMiddleware):
Expand Down Expand Up @@ -62,7 +58,6 @@ async def scalar_html():
)

app.program = Program()

app.add_middleware(LoguruMiddleware)
app.add_middleware(
CORSMiddleware,
Expand All @@ -72,14 +67,7 @@ async def scalar_html():
allow_headers=["*"],
)

app.include_router(default_router)
app.include_router(settings_router)
app.include_router(items_router)
app.include_router(scrape_router)
app.include_router(webhooks_router)
app.include_router(tmdb_router)
app.include_router(ws_router)

app.include_router(app_router)

class Server(uvicorn.Server):
def install_signal_handlers(self):
Expand Down
2 changes: 1 addition & 1 deletion src/program/content/listrr.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from program.indexers.trakt import get_imdbid_from_tmdb
from program.media.item import MediaItem
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.request import get, ping


Expand Down
2 changes: 1 addition & 1 deletion src/program/content/mdblist.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from program.media.item import MediaItem
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.ratelimiter import RateLimiter, RateLimitExceeded
from utils.request import get, ping

Expand Down
2 changes: 1 addition & 1 deletion src/program/content/overseerr.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from program.indexers.trakt import get_imdbid_from_tmdb
from program.media.item import MediaItem
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.request import delete, get, ping, post


Expand Down
2 changes: 1 addition & 1 deletion src/program/content/plex_watchlist.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from program.media.item import Episode, MediaItem, Movie, Season, Show
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.request import get, ping


Expand Down
2 changes: 1 addition & 1 deletion src/program/content/trakt.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from program.media.item import MediaItem
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.ratelimiter import RateLimiter
from utils.request import get, post

Expand Down
2 changes: 1 addition & 1 deletion src/program/db/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from program.settings.manager import settings_manager
from utils import data_dir_path
from utils.logger import logger
from loguru import logger

engine_options = {
"pool_size": 25, # Prom: Set to 1 when debugging sql queries
Expand Down
2 changes: 1 addition & 1 deletion src/program/db/db_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from program.media.stream import Stream, StreamBlacklistRelation, StreamRelation
from program.settings.manager import settings_manager
from utils import alembic_dir
from utils.logger import logger
from loguru import logger

from .db import alembic, db

Expand Down
2 changes: 1 addition & 1 deletion src/program/downloaders/torbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from program.media.state import States
from program.media.stream import Stream
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.request import get, post

API_URL = "https://api.torbox.app/v1/api"
Expand Down
2 changes: 1 addition & 1 deletion src/program/indexers/tmdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from typing import Generic, Literal, Optional, TypeVar

from pydantic import BaseModel
from utils.logger import logger
from loguru import logger
from utils.request import get

TMDB_READ_ACCESS_TOKEN = "eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJlNTkxMmVmOWFhM2IxNzg2Zjk3ZTE1NWY1YmQ3ZjY1MSIsInN1YiI6IjY1M2NjNWUyZTg5NGE2MDBmZjE2N2FmYyIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.xrIXsMFJpI1o1j5g2QpQcFP1X3AfRjFA5FlBFO5Naw8" # noqa: S105
Expand Down
2 changes: 1 addition & 1 deletion src/program/indexers/trakt.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from program.db.db import db
from program.media.item import Episode, MediaItem, Movie, Season, Show
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.request import get

CLIENT_ID = "0183a05ad97098d87287fe46da4ae286f434f32e8e951caad4cc147c947d79a3"
Expand Down
2 changes: 1 addition & 1 deletion src/program/libraries/symlink.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from program.db.db import db
from program.media.subtitle import Subtitle
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger

if TYPE_CHECKING:
from program.media.item import Episode, MediaItem, Movie, Show
Expand Down
21 changes: 9 additions & 12 deletions src/program/media/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@

import sqlalchemy
from RTN import parse
from sqlalchemy import Index, UniqueConstraint
from sqlalchemy import Index
from sqlalchemy.orm import Mapped, mapped_column, object_session, relationship

import utils.websockets.manager as ws_manager
from utils.sse_manager import sse_manager
from program.db.db import db
from program.media.state import States
from program.media.subtitle import Subtitle
from utils.logger import logger
from loguru import logger

from ..db.db_functions import blacklist_stream, reset_streams
from .stream import Stream
Expand Down Expand Up @@ -133,9 +133,10 @@ def __init__(self, item: dict | None) -> None:
self.subtitles = item.get("subtitles", [])

def store_state(self) -> None:
if self.last_state and self.last_state != self._determine_state():
ws_manager.send_item_update(json.dumps(self.to_dict()))
self.last_state = self._determine_state()
new_state = self._determine_state()
if self.last_state and self.last_state != new_state:
sse_manager.publish_event("item_update", {"last_state": self.last_state, "new_state": new_state, "item_id": self._id})
self.last_state = new_state

def is_stream_blacklisted(self, stream: Stream):
"""Check if a stream is blacklisted for this item."""
Expand Down Expand Up @@ -458,9 +459,7 @@ def _determine_state(self):
def store_state(self) -> None:
for season in self.seasons:
season.store_state()
if self.last_state and self.last_state != self._determine_state():
ws_manager.send_item_update(json.dumps(self.to_dict()))
self.last_state = self._determine_state()
super().store_state()

def __repr__(self):
return f"Show:{self.log_string}:{self.state.name}"
Expand Down Expand Up @@ -531,9 +530,7 @@ class Season(MediaItem):
def store_state(self) -> None:
for episode in self.episodes:
episode.store_state()
if self.last_state and self.last_state != self._determine_state():
ws_manager.send_item_update(json.dumps(self.to_dict()))
self.last_state = self._determine_state()
super().store_state()

def __init__(self, item):
self.type = "season"
Expand Down
6 changes: 3 additions & 3 deletions src/program/media/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from sqlalchemy.orm import Mapped, mapped_column, relationship

from program.db.db import db
from utils.logger import logger
from loguru import logger

if TYPE_CHECKING:
from program.media.item import MediaItem
Expand All @@ -24,7 +24,7 @@ class StreamRelation(db.Model):
Index('ix_streamrelation_parent_id', 'parent_id'),
Index('ix_streamrelation_child_id', 'child_id'),
)

class StreamBlacklistRelation(db.Model):
__tablename__ = "StreamBlacklistRelation"

Expand Down Expand Up @@ -66,6 +66,6 @@ def __init__(self, torrent: Torrent):

def __hash__(self):
return self.infohash

def __eq__(self, other):
return isinstance(other, Stream) and self.infohash == other.infohash
5 changes: 1 addition & 4 deletions src/program/program.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
from concurrent.futures import ThreadPoolExecutor, as_completed
from datetime import datetime
from queue import Empty
from typing import Iterator, List

from apscheduler.schedulers.background import BackgroundScheduler
from rich.live import Live

import utils.websockets.manager as ws_manager
from program.content import Listrr, Mdblist, Overseerr, PlexWatchlist, TraktContent
from program.downloaders import Downloader
from program.indexers.trakt import TraktIndexer
Expand All @@ -25,7 +23,7 @@
from program.updaters import Updater
from utils import data_dir_path
from utils.event_manager import EventManager
from utils.logger import create_progress_bar, log_cleaner, logger
from utils.logging import create_progress_bar, log_cleaner, logger

from .state_transition import process_event
from .symlink import Symlinker
Expand Down Expand Up @@ -170,7 +168,6 @@ def start(self):
super().start()
self.scheduler.start()
logger.success("Riven is running!")
ws_manager.send_health_update("running")
self.initialized = True

def _retry_library(self) -> None:
Expand Down
2 changes: 1 addition & 1 deletion src/program/scrapers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from program.scrapers.torrentio import Torrentio
from program.scrapers.zilean import Zilean
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger


class Scraping:
Expand Down
2 changes: 1 addition & 1 deletion src/program/scrapers/annatar.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from program.media.item import MediaItem
from program.settings.manager import settings_manager
from program.scrapers.shared import _get_stremio_identifier
from utils.logger import logger
from loguru import logger
from utils.ratelimiter import RateLimiter, RateLimitExceeded
from utils.request import get

Expand Down
2 changes: 1 addition & 1 deletion src/program/scrapers/comet.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from program.media.item import MediaItem, Show
from program.settings.manager import settings_manager
from program.scrapers.shared import _get_stremio_identifier
from utils.logger import logger
from loguru import logger
from utils.request import RateLimiter, RateLimitExceeded, get, ping


Expand Down
2 changes: 1 addition & 1 deletion src/program/scrapers/jackett.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

from program.media.item import Episode, MediaItem, Movie, Season, Show
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.ratelimiter import RateLimiter, RateLimitExceeded


Expand Down
2 changes: 1 addition & 1 deletion src/program/scrapers/knightcrawler.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from program.media.item import Episode, MediaItem
from program.scrapers.shared import _get_stremio_identifier
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.ratelimiter import RateLimiter, RateLimitExceeded
from utils.request import get, ping

Expand Down
2 changes: 1 addition & 1 deletion src/program/scrapers/mediafusion.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from program.scrapers.shared import _get_stremio_identifier
from program.settings.manager import settings_manager
from program.settings.models import AppModel
from utils.logger import logger
from loguru import logger
from utils.ratelimiter import RateLimiter, RateLimitExceeded
from utils.request import get, ping

Expand Down
2 changes: 1 addition & 1 deletion src/program/scrapers/orionoid.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from program.media.item import MediaItem
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.ratelimiter import RateLimiter, RateLimitExceeded
from utils.request import get

Expand Down
2 changes: 1 addition & 1 deletion src/program/scrapers/prowlarr.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from program.media.item import Episode, MediaItem, Movie, Season, Show
from program.settings.manager import settings_manager
from utils.logger import logger
from loguru import logger
from utils.ratelimiter import RateLimiter, RateLimitExceeded


Expand Down
2 changes: 1 addition & 1 deletion src/program/scrapers/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from program.media.stream import Stream
from program.settings.manager import settings_manager
from program.settings.versions import models
from utils.logger import logger
from loguru import logger

enable_aliases = settings_manager.settings.scraping.enable_aliases
settings_model = settings_manager.settings.ranking
Expand Down
Loading
Loading