Files
dify/api/services/dify_builder/identity.py
Charles YaoandClaude Opus 4.8 7e83264330 refactor: rename Workflow Copilot → Dify Builder
Project rename across api/ + web/: modules, symbols, routes
(/console/api/dify-builder/*), feature flag (DIFY_BUILDER_ENABLED),
Celery queue/tasks, the 7 DB tables (via migration df1b0114de40),
and regenerated contract artifacts. Behavior unchanged; 430 tests green,
ruff clean. Branch renamed feat/copilot-py-backend → dify-builder.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-23 11:18:35 -07:00

45 lines
1.7 KiB
Python

"""Actor -> account resolution and tenant-scoped app loading.
These helpers do NO authorization of their own -- they only resolve rows by
primary key (and, for ``load_app``, assert the row belongs to the calling
``Actor``'s tenant). RBAC/permission checks happen at the controller layer
before a dify_builder ``Advance`` ever reaches here; ``load_app``'s tenant guard
is a defense-in-depth "don't leak another tenant's app" check, not a
substitute for real authorization.
"""
from sqlalchemy.orm import Session
from core.dify_builder.errors import NotFoundError
from core.dify_builder.models import Actor
from models.account import Account
from models.model import App
def resolve_account(session: Session, actor: Actor) -> Account:
"""Look up the ``Account`` behind ``actor.account_id``.
Raises ``NotFoundError`` if no such account exists.
"""
account = session.get(Account, actor.account_id)
if account is None:
raise NotFoundError(f"account not found: {actor.account_id}")
return account
def load_app(session: Session, app_id: str, actor: Actor) -> App:
"""Look up the ``App`` for ``app_id``, scoped to ``actor``'s tenant.
Raises ``NotFoundError`` if the app doesn't exist, and -- to avoid
leaking an app's existence to a caller from another tenant -- also
raises ``NotFoundError`` (not a distinct permission error) when the
app belongs to a different tenant than ``actor.tenant_id``. This
mirrors the P1 usecase's non-owner-to-NotFoundError convention.
"""
app = session.get(App, app_id)
if app is None:
raise NotFoundError(f"app not found: {app_id}")
if app.tenant_id != actor.tenant_id:
raise NotFoundError(f"app not found: {app_id}")
return app