Extend the GraphQL API and socket to accept mobile session tokens alongside existing API tokens. Add OrganizationScope middleware that extracts organization_id from query args for mobile users. Add my_organizations query for mobile app org listing. Reviewed-on: graham/towerops-web#48
37 lines
1.2 KiB
Elixir
37 lines
1.2 KiB
Elixir
defmodule ToweropsWeb.GraphQL.Middleware.OrganizationScope do
|
|
@moduledoc """
|
|
Absinthe middleware that ensures organization_id is present in context.
|
|
|
|
For API token users: organization_id is already in context — passes through.
|
|
For mobile users: extracts organization_id from args, validates access, sets in context.
|
|
"""
|
|
|
|
@behaviour Absinthe.Middleware
|
|
|
|
alias Towerops.Organizations
|
|
|
|
@impl true
|
|
def call(%{context: %{organization_id: _org_id}} = resolution, _config) do
|
|
resolution
|
|
end
|
|
|
|
def call(%{context: %{user: user}, arguments: %{organization_id: org_id}} = resolution, _config)
|
|
when is_binary(org_id) do
|
|
if Organizations.user_has_access?(user.id, org_id) do
|
|
%{resolution | context: Map.put(resolution.context, :organization_id, org_id)}
|
|
else
|
|
Absinthe.Resolution.put_result(resolution, {:error, "Access denied to this organization"})
|
|
end
|
|
end
|
|
|
|
def call(%{context: %{user: _user}} = resolution, _config) do
|
|
Absinthe.Resolution.put_result(
|
|
resolution,
|
|
{:error, "organization_id argument is required for mobile authentication"}
|
|
)
|
|
end
|
|
|
|
def call(resolution, _config) do
|
|
Absinthe.Resolution.put_result(resolution, {:error, "Authentication required"})
|
|
end
|
|
end
|