Created
August 23, 2021 18:40
-
-
Save coryodaniel/a162ebf27bf06665eba3ef3cd73d94a9 to your computer and use it in GitHub Desktop.
Kratos Sessions whoami client for elixir
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Kratos do | |
defmodule Behaviour do | |
@moduledoc """ | |
Defines function signature for secrets adapters | |
""" | |
@callback who_am_i(String.t()) :: {:ok, map()} | {:error, :unauthenticated} | |
end | |
@behaviour Kratos.Behaviour | |
def config(), do: Application.get_env(:massdriver, Kratos) | |
def adapter(), do: Keyword.get(config(), :adapter) | |
def url(), do: Keyword.get(config(), :url) | |
def who_am_i(cookie), do: adapter().who_am_i(cookie) | |
defmodule HTTPAdapter do | |
@behaviour Kratos.Behaviour | |
def who_am_i(cookie) do | |
headers = [{"Cookie", cookie}] | |
result = HTTPoison.get(Kratos.url(), headers, []) | |
with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- result, | |
{:ok, session} <- Jason.decode(body) do | |
{:ok, session} | |
else | |
{:error, %HTTPoison.Error{}} -> | |
{:error, :unauthenticated} | |
{:error, %Jason.DecodeError{}} -> | |
{:error, :unauthenticated} | |
_no_active_session -> | |
{:error, :unauthenticated} | |
end | |
end | |
end | |
defmodule MockAdapter do | |
@behaviour Kratos.Behaviour | |
def start_link() do | |
Agent.start_link(fn -> %{} end, name: __MODULE__) | |
end | |
def build_session(email) do | |
now = DateTime.utc_now() | |
expires_at = DateTime.add(now, 30 * 60, :second) | |
%{ | |
"id" => Ecto.UUID.generate(), | |
"active" => true, | |
"expires_at" => DateTime.to_iso8601(expires_at), | |
"authenticated_at" => DateTime.to_iso8601(now), | |
"issued_at" => DateTime.to_iso8601(now), | |
"identity" => %{ | |
"id" => Ecto.UUID.generate(), | |
"schema_id" => "default", | |
"schema_url" => "http://127.0.0.1:4433/schemas/default", | |
"state" => "active", | |
"state_changed_at" => DateTime.to_iso8601(now), | |
"traits" => %{ | |
"email" => email, | |
"name" => %{} | |
}, | |
"created_at" => DateTime.to_iso8601(now), | |
"updated_at" => DateTime.to_iso8601(now) | |
}, | |
"verifiable_addresses" => [ | |
%{ | |
"id" => "e5ed11bf-43d3-483e-be9c-5f9a9c46c0b3", | |
"value" => "[email protected]", | |
"verified" => false, | |
"via" => "email", | |
"status" => "sent", | |
"verified_at" => nil, | |
"created_at" => "2021-08-17T05:54:59.867799Z", | |
"updated_at" => "2021-08-17T05:54:59.867799Z" | |
} | |
] | |
} | |
end | |
@doc """ | |
Inserts a session into the Agent store. | |
## Examples | |
Given an email, a session map will be generated an inserted | |
Kratos.MockAdapter.insert_session("session_cookie=foo", "[email protected]") | |
Otherwise a map from `build_session/1` is expected | |
session = Kratos.MockAdapter.build_session("[email protected]") | |
# modify session as desired | |
Kratos.MockAdapter.insert_session("session_cookie=foo", session) | |
""" | |
def insert_session(cookie, email) when is_binary(email) do | |
session = build_session(email) | |
insert_session(cookie, session) | |
end | |
def insert_session(cookie, session = %{}) do | |
Agent.update(__MODULE__, fn map -> Map.put(map, cookie, session) end) | |
end | |
def who_am_i(cookie) do | |
session = Agent.get(__MODULE__, fn map -> Map.get(map, cookie) end) | |
case session do | |
nil -> | |
{:error, :unauthenticated} | |
session -> | |
{:ok, session} | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment