Milestone 2.
This commit is contained in:
32
app/routes/attachments.py
Normal file
32
app/routes/attachments.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
from flask import Blueprint, abort, current_app, send_from_directory
|
||||
|
||||
from app.services.vault import Vault
|
||||
|
||||
bp = Blueprint("attachments", __name__, url_prefix="/attachments")
|
||||
|
||||
|
||||
@bp.get("/<path:subpath>")
|
||||
def serve_attachment(subpath: str):
|
||||
# Resolve within the vault attachments directory
|
||||
vault_path = current_app.config.get("KB_VAULT_PATH")
|
||||
if not vault_path:
|
||||
abort(404)
|
||||
|
||||
v = Vault(vault_path)
|
||||
attachments_dir = Path(v.paths.attachments).resolve()
|
||||
requested = (attachments_dir / subpath).resolve()
|
||||
|
||||
# Prevent path traversal
|
||||
try:
|
||||
requested.relative_to(attachments_dir)
|
||||
except Exception:
|
||||
abort(403)
|
||||
|
||||
if not requested.exists() or not requested.is_file():
|
||||
abort(404)
|
||||
|
||||
return send_from_directory(attachments_dir, os.path.relpath(str(requested), str(attachments_dir)))
|
Reference in New Issue
Block a user