mirror of
https://github.com/mealie-recipes/mealie.git
synced 2026-05-15 22:37:32 -04:00
added runtime check for this
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import string
|
import string
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Annotated, ClassVar
|
from typing import Annotated, ClassVar, get_origin
|
||||||
|
|
||||||
from sqlalchemy import Integer
|
from sqlalchemy import Integer
|
||||||
from sqlalchemy.orm import DeclarativeBase, Mapped, declared_attr, mapped_column, synonym
|
from sqlalchemy.orm import DeclarativeBase, Mapped, declared_attr, mapped_column, synonym
|
||||||
@@ -19,9 +19,17 @@ class PrivateColumn[T]:
|
|||||||
"""
|
"""
|
||||||
Drop-in replacement for `Mapped[]` that marks a column as private.
|
Drop-in replacement for `Mapped[]` that marks a column as private.
|
||||||
Private columns cannot be used in query filter expressions.
|
Private columns cannot be used in query filter expressions.
|
||||||
|
|
||||||
|
Only valid on scalar column fields. Using it on a relationship type (e.g. `list[Model]`)
|
||||||
|
will raise a `TypeError` at class definition time.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __class_getitem__(cls, item: type) -> type:
|
def __class_getitem__(cls, item: type) -> type:
|
||||||
|
if get_origin(item) is list or item is list:
|
||||||
|
raise TypeError(
|
||||||
|
f"PrivateColumn cannot be used on relationship fields (got {item!r}). "
|
||||||
|
"Annotate the related model's scalar column directly instead."
|
||||||
|
)
|
||||||
return Mapped[Annotated[item, mapped_column(info={"private": True})]]
|
return Mapped[Annotated[item, mapped_column(info={"private": True})]]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import pytest
|
import pytest
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
|
||||||
|
from mealie.db.models._model_base import PrivateColumn
|
||||||
from mealie.db.models.recipe.recipe import RecipeModel
|
from mealie.db.models.recipe.recipe import RecipeModel
|
||||||
from mealie.db.models.users.users import LongLiveToken, User
|
from mealie.db.models.users.users import LongLiveToken, User
|
||||||
from mealie.services.query_filter.builder import (
|
from mealie.services.query_filter.builder import (
|
||||||
@@ -87,6 +88,12 @@ def test_query_filter_builder_json_uses_raw_value():
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
def test_private_column_rejects_list_type():
|
||||||
|
"""PrivateColumn[list[X]] must raise TypeError at definition time to prevent misuse on relationships."""
|
||||||
|
with pytest.raises(TypeError, match="relationship"):
|
||||||
|
PrivateColumn[list[User]]
|
||||||
|
|
||||||
|
|
||||||
def test_private_field_user_password_raises():
|
def test_private_field_user_password_raises():
|
||||||
"""Filtering on User.password (PrivateColumn) should raise ValueError."""
|
"""Filtering on User.password (PrivateColumn) should raise ValueError."""
|
||||||
with pytest.raises(ValueError, match="private field"):
|
with pytest.raises(ValueError, match="private field"):
|
||||||
|
|||||||
Reference in New Issue
Block a user