180 lines
4.4 KiB
Python
180 lines
4.4 KiB
Python
from functools import wraps
|
|
|
|
from flask import abort
|
|
|
|
from app.decorators.decorators import get_current_user_id
|
|
from app.models import (Board, Card, CheckItem, Checklist, Comment,
|
|
FileAttachment, List)
|
|
|
|
|
|
def load_board_owned(f):
|
|
"""
|
|
Loads a Board and ensures it belongs to the current user.
|
|
Injects 'board' into the route kwargs.
|
|
Aborts with 404 if not found or not owned.
|
|
"""
|
|
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
user_id = get_current_user_id()
|
|
board_id = kwargs.get("board_id")
|
|
|
|
# SECURE QUERY: Filter by ID *and* User ID in the DB
|
|
board = Board.query.filter_by(id=board_id, user_id=user_id).first()
|
|
|
|
if not board:
|
|
abort(404)
|
|
|
|
kwargs["board"] = board
|
|
return f(*args, **kwargs)
|
|
|
|
return decorated_function
|
|
|
|
|
|
def load_card_owned(f):
|
|
"""
|
|
Loads a Card and ensures its Parent Board belongs to the current user.
|
|
Injects 'card' into the route kwargs.
|
|
Aborts with 404 if not found, not owned, or soft-deleted.
|
|
"""
|
|
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
user_id = get_current_user_id()
|
|
card_id = kwargs.get("card_id")
|
|
|
|
# Join Board to check ownership and filter soft-deleted cards
|
|
card = (
|
|
Card.query.join(Board)
|
|
.filter(
|
|
Card.id == card_id, Board.user_id == user_id, Card.deleted_at.is_(None)
|
|
)
|
|
.first()
|
|
)
|
|
|
|
if not card:
|
|
abort(404)
|
|
|
|
kwargs["card"] = card
|
|
return f(*args, **kwargs)
|
|
|
|
return decorated_function
|
|
|
|
|
|
def load_list_owned(f):
|
|
"""Loads a List ensuring Parent Board ownership."""
|
|
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
user_id = get_current_user_id()
|
|
list_id = kwargs.get("list_id")
|
|
|
|
lst = (
|
|
List.query.join(Board)
|
|
.filter(List.id == list_id, Board.user_id == user_id)
|
|
.first()
|
|
)
|
|
|
|
if not lst:
|
|
abort(404)
|
|
|
|
kwargs["lst"] = lst
|
|
return f(*args, **kwargs)
|
|
|
|
return decorated_function
|
|
|
|
|
|
def load_checklist_owned(f):
|
|
"""Loads a Checklist ensuring Parent Board ownership."""
|
|
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
user_id = get_current_user_id()
|
|
checklist_id = kwargs.get("checklist_id")
|
|
|
|
checklist = (
|
|
Checklist.query.join(Card)
|
|
.join(Board)
|
|
.filter(Checklist.id == checklist_id, Board.user_id == user_id)
|
|
.first()
|
|
)
|
|
|
|
if not checklist:
|
|
abort(404)
|
|
|
|
kwargs["checklist"] = checklist
|
|
return f(*args, **kwargs)
|
|
|
|
return decorated_function
|
|
|
|
|
|
def load_check_item_owned(f):
|
|
"""Loads a CheckItem ensuring Parent Board ownership."""
|
|
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
user_id = get_current_user_id()
|
|
item_id = kwargs.get("item_id")
|
|
|
|
check_item = (
|
|
CheckItem.query.join(Checklist)
|
|
.join(Card)
|
|
.join(Board)
|
|
.filter(CheckItem.id == item_id, Board.user_id == user_id)
|
|
.first()
|
|
)
|
|
|
|
if not check_item:
|
|
abort(404)
|
|
|
|
kwargs["check_item"] = check_item
|
|
return f(*args, **kwargs)
|
|
|
|
return decorated_function
|
|
|
|
|
|
def load_comment_owned(f):
|
|
"""
|
|
Loads a Comment ensuring the Comment itself belongs to the user.
|
|
(Based on schema where Comment has user_id)
|
|
"""
|
|
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
user_id = get_current_user_id()
|
|
comment_id = kwargs.get("comment_id")
|
|
|
|
comment = Comment.query.filter_by(id=comment_id, user_id=user_id).first()
|
|
|
|
if not comment:
|
|
abort(404)
|
|
|
|
kwargs["comment"] = comment
|
|
return f(*args, **kwargs)
|
|
|
|
return decorated_function
|
|
|
|
|
|
def load_file_owned(f):
|
|
"""
|
|
Loads a FileAttachment ensuring it belongs to the user.
|
|
Aborts with 404 if not found or not owned.
|
|
"""
|
|
|
|
@wraps(f)
|
|
def decorated_function(*args, **kwargs):
|
|
user_id = get_current_user_id()
|
|
file_id = kwargs.get("file_id")
|
|
|
|
# Filter by ID and user ID
|
|
attachment = FileAttachment.query.filter_by(
|
|
id=file_id, uploaded_by=user_id
|
|
).first()
|
|
|
|
if not attachment:
|
|
abort(404)
|
|
|
|
kwargs["file"] = attachment
|
|
return f(*args, **kwargs)
|
|
|
|
return decorated_function
|