Current section

Files

Jump to
indieweb lib indieweb auth scope.ex
Raw

lib/indieweb/auth/scope.ex

defmodule IndieWeb.Auth.Scope do
@moduledoc """
Handles scope information and referencing for the IndieAuth flow.
"""
@separator " "
defmodule Adapter do
@moduledoc "Provides an abstraction regarding code actions for IndieAuth."
@callback get(code :: binary(), options :: keyword()) :: binary() | nil
@callback persist(code :: binary(), scope :: binary(), options :: keyword()) :: :ok | {:error, any()}
end
@spec persist!(binary(), binary(), keyword()) :: :ok
def persist!(code, scope, options \\ [])
def persist!(code, "", options) do
persist!(code, "read", options)
end
def persist!(code, scope, options) when is_list(scope) do
persist!(code, __MODULE__.to_string(scope), options)
end
def persist!(code, scope, options) do
adapter(options).persist(code, scope, options)
end
@spec get(binary(), keyword()) :: binary() | nil
def get(code, options \\ []) do
case adapter(options).get(code, options) do
scope when is_binary(scope) -> scope |> from_string
_ -> nil
end
end
@spec from_string(binary) :: [binary]
def from_string(scope_string) when is_binary(scope_string) do
String.split(scope_string, @separator, trim: true)
end
@spec to_string([binary]) :: binary
def to_string(scopes) when is_list(scopes) do
Enum.join(scopes, @separator)
end
@spec can_upload?([binary]) :: boolean
def can_upload?(scope) when is_list(scope) do
Enum.member?(scope, "media")
end
defp adapter(options) do
options
|> Keyword.get(:adapters, [])
|> Keyword.get(:scope, IndieWeb.Auth.DefaultScopeAdapter)
end
end