Skip to content

Commit

Permalink
jwt_simple wrapped
Browse files Browse the repository at this point in the history
  • Loading branch information
ShreyanJain9 committed Apr 11, 2024
1 parent ae04427 commit 0d0cb55
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 57 deletions.
2 changes: 0 additions & 2 deletions lib/hipdster/auth.ex
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
defmodule Hipdster.Auth do
@moduledoc """
Authentication and session management
Should the database stuff for *users* specifically go here?
"""

def generate_session(_, _username, _pw) do
Expand All @@ -19,5 +18,4 @@ defmodule Hipdster.Auth do
_ -> false
end
end

end
44 changes: 36 additions & 8 deletions lib/hipdster/auth/jwt.ex
Original file line number Diff line number Diff line change
@@ -1,8 +1,36 @@
# defmodule Hipdster.Auth.JWT do
# defmodule Internal do
# use Rustler, otp_app: :hipdster, crate: "hipdster_auth_jwt_internal"

# # Temp to satisfy Rustler
# def add(_a, _b), do: :erlang.nif_error(:nif_not_loaded)
# end
# end
defmodule Hipdster.Auth.JWT do
defmodule Internal do
use Rustler, otp_app: :hipdster, crate: "hipdster_auth_jwt_internal"

def generate_k256_jwt(_account_did, _service_did, _subject, _key),
do: :erlang.nif_error(:nif_not_loaded)
def generate_hs256_jwt(_account_did, _subject, _hs256_key, _time_in_minutes),
do: :erlang.nif_error(:nif_not_loaded)
def verify_hs256_jwt(_jwt, _key), do: :erlang.nif_error(:nif_not_loaded)
end

import Hipdster.Helpers

@spec interservice(Hipdster.User.t(), Hipdster.Identity.did(), String.t()) :: {:ok, binary()} | {:error, String.t()}
def interservice(
%Hipdster.User{
signing_key: %Hipdster.K256.PrivateKey{
privkey: <<>> <> signing_key_bytes
},
did: user_did
},
service_did,
subject \\ ""
) do
Hipdster.Auth.JWT.Internal.generate_k256_jwt(
user_did,
service_did,
subject,
signing_key_bytes
)
end

def! interservice(user, service_did, subject)
def! interservice(user, service_did)

end
29 changes: 19 additions & 10 deletions lib/hipdster/identity.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,28 @@ defmodule Hipdster.Identity do
Stuff like resolving a handle, fetching a DID, generating JWTs, etc
"""

import Hipdster.Helpers

@typedoc """
A string representing a DID in the format `did:plc:<hex>`
"""
@type did_plc :: <<_::256>>
@typedoc """
A string representing a DID in the format `did:web:<domain>`
"""
@type did_web :: String.t()

@typedoc """
A DID as a string
"""
@type did :: did_plc() | did_web()

@typedoc """
A handle as a string
"""
@type handle :: String.t()

@spec resolve_handle(String.t()) :: {:ok, did()} | {:error, any()}
def resolve_handle(domain) do
lookup_did_by_dns(domain)
|> case do
Expand All @@ -23,19 +40,11 @@ defmodule Hipdster.Identity do
end
end

@spec is_did?({:ok, did()}) :: {:ok, did()}
def is_did?({:ok, "did:" <> _did} = arg), do: arg
@spec is_did?({:ok, any()}) :: {:error, not_a_did: any()}
def is_did?({:ok, anything_else}), do: {:error, not_a_did: anything_else}

defmacrop handle_errors(do: block) do
quote do
try do
{:ok, unquote(block)}
rescue
error -> {:error, error}
end
end
end

defp lookup_did_by_dns(domain) do
handle_errors do
[[did_record]] = :inet_res.lookup(~c"_atproto.#{domain}", :in, :txt)
Expand Down
22 changes: 22 additions & 0 deletions lib/hipdster/macros.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,26 @@ defmodule Hipdster.Helpers do
Common macros & functions that make Elixir easier
"""
# Gonna move some common stuff here soon

defmacro def!({name, _, args}) do
quote do
def (unquote {:"#{name}!", [], args}) do
case unquote({name, [], args}) do
{:ok, value} -> value
{:error, error} -> raise error
end
end
end
end

defmacro handle_errors(do: block) do
quote do
try do
{:ok, unquote(block)}
rescue
error -> {:error, error}
end
end
end

end
9 changes: 5 additions & 4 deletions lib/hipdster/service/http.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,13 +50,14 @@ defmodule Hipdster.Http do
try do
# We can handle the method
IO.puts("Got query: #{method} #{inspect(params)}")
xrpc_query(conn, method, params)
xrpc_query(conn, method, params, :unauthenticated)
catch
_, e_from_method ->
try do
# We can't handle the method - try the appview
case e_from_method do
%FunctionClauseError{} -> IO.inspect(e_from_method)
:function_clause -> IO.inspect(e_from_method)
_ -> throw(e_from_method)
end
forward_query_to_appview(IO.inspect(appview_for(conn)), conn, method, params)
Expand Down Expand Up @@ -88,7 +89,7 @@ defmodule Hipdster.Http do

{statuscode, json_resp} =
try do
xrpc_procedure(conn, method, body)
xrpc_procedure(conn, method, body, :unauthenticated)
catch
_, e ->
{500,
Expand Down Expand Up @@ -139,7 +140,7 @@ defmodule Hipdster.Http do
{statuscode, Jason.decode!(json_body)}
end

@spec xrpc_query(Plug.Conn.t(), String.t(), map()) :: {integer(), map()}
@spec xrpc_query(Plug.Conn.t(), String.t(), map(), Hipdster.User.t() | :unauthenticated) :: {integer(), map() | {:blob, Hipdster.Blob.t()}}

# As soon as we got JWTs we can do this!!!
XRPC.query _, "app.bsky.actor.getPreferences", %{} do
Expand Down Expand Up @@ -169,7 +170,7 @@ defmodule Hipdster.Http do
end
end

@spec xrpc_procedure(Plug.Conn.t(), String.t(), map()) :: {integer(), map()}
@spec xrpc_procedure(Plug.Conn.t(), String.t(), map(), Hipdster.User.t() | :unauthenticated) :: {integer(), map()}
XRPC.procedure c, "com.atproto.server.createSession", %{identifier: username, password: pw} do
{200, %{session: Hipdster.Auth.generate_session(c, username, pw)}}
end
Expand Down
4 changes: 2 additions & 2 deletions lib/hipdster/service/xrpc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ defmodule Hipdster.XRPC do

defmacro query(conn, method, params, [do: block]) do
quote do
def xrpc_query(unquote(conn), unquote(method), unquote(params)) do
def xrpc_query(unquote(conn), unquote(method), unquote(params), user) do
unquote(block)
end
end
end

defmacro procedure(conn, method, params, [do: block]) do
quote do
def xrpc_procedure(unquote(conn), unquote(method), unquote(params)) do
def xrpc_procedure(unquote(conn), unquote(method), unquote(params), user) do
unquote(block)
end
end
Expand Down
32 changes: 30 additions & 2 deletions lib/hipdster/tid.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
defmodule Hipdster.Tid do
import Bitwise

import TypeClass

defstruct [:timestamp, :clock_id]
@b32_charset "234567abcdefghijklmnopqrstuvwxyz"

Expand All @@ -9,6 +11,11 @@ defmodule Hipdster.Tid do
"""
@type unix_microseconds :: non_neg_integer()

@typedoc """
A random number in the range 0..1023
"""
@type clock_id :: 0..1023

@typedoc """
A TID is a 13-character string.
TID is short for "timestamp identifier," and the name is derived from the creation time of the record.
Expand All @@ -29,7 +36,7 @@ defmodule Hipdster.Tid do
This struct holds the timestamp in microseconds since the UNIX epoch, and the clock_id, which is a random number in the range 0..1023.
"""
@type t :: %__MODULE__{timestamp: unix_microseconds(), clock_id: non_neg_integer()}
@type t :: %__MODULE__{timestamp: unix_microseconds(), clock_id: clock_id()}


@spec from_string(String.t()) :: t() | {:error, String.t()}
Expand Down Expand Up @@ -66,7 +73,7 @@ defmodule Hipdster.Tid do
end
end

defimpl String.Chars, for: Hipdster.Tid do
defimpl String.Chars do
@spec to_string(Hipdster.Tid.t()) :: String.t()
defdelegate to_string(tid), to: Hipdster.Tid
end
Expand Down Expand Up @@ -121,4 +128,25 @@ defmodule Hipdster.Tid do
def empty do
%__MODULE__{timestamp: 0, clock_id: 0}
end

defimpl TypeClass.Property.Generator do
def generate(_), do: %Hipdster.Tid{timestamp: :rand.uniform(1000000000), clock_id: :rand.uniform(1 <<< 10)}
end

definst Witchcraft.Setoid do
@spec equivalent?(
Hipdster.Tid.t(),
Hipdster.Tid.t()
) :: boolean()
def equivalent?(tid1, tid2) do
[tid1.timestamp, tid1.clock_id] == [tid2.timestamp, tid2.clock_id]
end
end

definst Witchcraft.Ord do
import Bitwise
def compare(tid1, tid2) do
Witchcraft.Ord.compare(tid1.timestamp <<< 10 ||| tid1.clock_id, tid2.timestamp <<< 10 ||| tid2.clock_id)
end
end
end
3 changes: 3 additions & 0 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"infer": {:hex, :infer, "0.2.6", "0b8a9a08cf67c5ed1c1a29cc6bff81781cc30565bcd33959e60bd7a41056fccf", [:mix], [], "hexpm", "0e5ad1b7ba3fb2bbf32b36223add30432c11ab33a34b038ffa16a591813e2667"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"libgraph": {:hex, :libgraph, "0.16.0", "3936f3eca6ef826e08880230f806bfea13193e49bf153f93edcf0239d4fd1d07", [:mix], [], "hexpm", "41ca92240e8a4138c30a7e06466acc709b0cbb795c643e9e17174a178982d6bf"},
"makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.3", "d684f4bac8690e70b06eb52dad65d26de2eefa44cd19d64a8095e1417df7c8fd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "b78dc853d2e670ff6390b605d807263bf606da3c82be37f9d7f68635bd886fc9"},
Expand All @@ -54,6 +55,8 @@
"parse_trans": {:hex, :parse_trans, "3.4.1", "6e6aa8167cb44cc8f39441d05193be6e6f4e7c2946cb2759f015f8c56b76e5ff", [:rebar3], [], "hexpm", "620a406ce75dada827b82e453c19cf06776be266f5a67cff34e1ef2cbb60e49a"},
"plug": {:hex, :plug, "1.15.3", "712976f504418f6dff0a3e554c40d705a9bcf89a7ccef92fc6a5ef8f16a30a97", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cc4365a3c010a56af402e0809208873d113e9c38c401cabd88027ef4f5c01fd2"},
"plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"},
"propcheck": {:hex, :propcheck, "1.4.1", "c12908dbe6f572032928548089b34ff9d40672d5d70f1562e3a9e9058d226cc9", [:mix], [{:libgraph, "~> 0.13", [hex: :libgraph, repo: "hexpm", optional: false]}, {:proper, "~> 1.4", [hex: :proper, repo: "hexpm", optional: false]}], "hexpm", "e1b088f574785c3c7e864da16f39082d5599b3aaf89086d3f9be6adb54464b19"},
"proper": {:hex, :proper, "1.4.0", "89a44b8c39d28bb9b4be8e4d715d534905b325470f2e0ec5e004d12484a79434", [:rebar3], [], "hexpm", "18285842185bd33efbda97d134a5cb5a0884384db36119fee0e3cfa488568cbb"},
"quark": {:hex, :quark, "2.3.2", "066e0d431440d077684469967f54d732443ea2a48932e0916e974633e8b39c95", [:mix], [], "hexpm", "2f6423779b02afe7e3e4af3cfecfcd94572f2051664d4d8329ffa872d24b10a8"},
"recon": {:hex, :recon, "2.5.5", "c108a4c406fa301a529151a3bb53158cadc4064ec0c5f99b03ddb8c0e4281bdf", [:mix, :rebar3], [], "hexpm", "632a6f447df7ccc1a4a10bdcfce71514412b16660fe59deca0fcf0aa3c054404"},
"rustler": {:hex, :rustler, "0.32.1", "f4cf5a39f9e85d182c0a3f75fa15b5d0add6542ab0bf9ceac6b4023109ebd3fc", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:toml, "~> 0.6", [hex: :toml, repo: "hexpm", optional: false]}], "hexpm", "b96be75526784f86f6587f051bc8d6f4eaff23d6e0f88dbcfe4d5871f52946f7"},
Expand Down
Loading

0 comments on commit 0d0cb55

Please sign in to comment.