Something went wrong. Try again.
An Elixir toolkit for the AT Protocol. hexdocs.pm/atex
elixir bluesky atproto decentralization
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127defmodule ExampleOAuthPlug do require Logger use Plug.Router use Plug.ErrorHandler alias Atex.OAuth alias Atex.XRPC
plug :put_secret_key_base
plug Plug.Session, store: :cookie, key: "atex-oauth", signing_salt: "signing-salt"
plug :match plug :dispatch
forward "/oauth", to: Atex.OAuth.Plug, init_opts: [ callback: {__MODULE__, :oauth_callback, []}, logout_callback: {__MODULE__, :logout_callback, []} ]
def oauth_callback(conn) do IO.inspect(conn, label: "callback from oauth!")
conn |> put_resp_header("Location", "/whoami") |> resp(307, "") |> send_resp() end
def logout_callback(conn) do conn |> put_resp_header("Location", "/") |> resp(302, "") |> send_resp() end
get "/whoami" do conn = fetch_session(conn)
case XRPC.OAuthClient.from_conn(conn) do {:ok, client} -> did = XRPC.OAuthClient.did(client) send_resp(conn, 200, "hello #{did}")
:error -> send_resp(conn, 401, "Unauthorized") end end
get "/create-post" do conn = fetch_session(conn)
with {:ok, client} <- XRPC.OAuthClient.from_conn(conn), {:ok, response, client} <- XRPC.post(client, "com.atproto.repo.createRecord", json: %{ repo: client.did, collection: "app.bsky.feed.post", rkey: Atex.TID.now() |> to_string(), record: %{ "$type": "app.bsky.feed.post", text: "Hello world from atex!", createdAt: DateTime.to_iso8601(DateTime.utc_now()) } } ) do IO.inspect(response, label: "output")
send_resp(conn, 200, response.body.uri) else :error -> send_resp(conn, 401, "Unauthorized")
{:error, :reauth} -> send_resp(conn, 401, "session expired but still in your cookie")
err -> IO.inspect(err, label: "xrpc failed") send_resp(conn, 500, "xrpc failed") end end
match _ do send_resp(conn, 404, "oops") end
def put_secret_key_base(conn, _) do put_in( conn.secret_key_base, # Don't use this in production "5ef1078e1617463a3eb3feb9b152e76587a75a6809e0485a125b6bb7ae468f086680771f700d77ff61dfdc8d8ee8a5c7848024a41cf5ad4b6eb3115f74ce6e46" ) end
# Error handler for OAuth exceptions @impl Plug.ErrorHandler def handle_errors(conn, %{kind: :error, reason: %Atex.OAuth.Error{} = error, stack: _stack}) do status = case error.reason do reason when reason in [ :missing_handle, :invalid_handle, :invalid_callback_request, :issuer_mismatch ] -> 400
_ -> 500 end
conn |> put_resp_content_type("text/plain") |> send_resp(status, error.message) end
# Fallback for other errors def handle_errors(conn, %{kind: _kind, reason: _reason, stack: _stack}) do send_resp(conn, conn.status, "Something went wrong") endend