Use Repo.get_by(schema, id: id, organization_id: organization_id) instead of Repo.get + pattern match so that resources from wrong orgs return :not_found instead of :forbidden, preventing org membership discovery.
24 lines
815 B
Elixir
24 lines
815 B
Elixir
defmodule ToweropsWeb.ScopedResource do
|
|
@moduledoc """
|
|
Shared helpers for loading organization-scoped resources.
|
|
"""
|
|
|
|
alias Towerops.Repo
|
|
|
|
@spec fetch(module(), Ecto.UUID.t(), Ecto.UUID.t()) ::
|
|
{:ok, struct()} | {:error, :not_found | :forbidden}
|
|
def fetch(schema, id, organization_id) do
|
|
case Repo.get_by(schema, id: id, organization_id: organization_id) do
|
|
nil -> {:error, :not_found}
|
|
resource -> {:ok, resource}
|
|
end
|
|
end
|
|
|
|
@spec fetch_preload(module(), Ecto.UUID.t(), Ecto.UUID.t(), atom() | list() | keyword()) ::
|
|
{:ok, struct()} | {:error, :not_found | :forbidden}
|
|
def fetch_preload(schema, id, organization_id, preloads) do
|
|
with {:ok, resource} <- fetch(schema, id, organization_id) do
|
|
{:ok, Repo.preload(resource, preloads)}
|
|
end
|
|
end
|
|
end
|