Skip to content

Commit

Permalink
[ssi] presentation hybrid flow
Browse files Browse the repository at this point in the history
  • Loading branch information
patatoid committed Sep 19, 2024
1 parent 69d3b2a commit 9c590ee
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 2 deletions.
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ on:
push:
branches:
- ebsi-verify-conformance
- poc-hybrid-vp-token
workflow_run:
workflows:
- Continuous Integration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ defmodule BorutaIdentityWeb.TemplateView do
|> context(Map.delete(assigns, :scopes))
end

def context(context, %{code: code} = assigns) do

%{code: code}
|> Map.merge(context)
|> context(Map.delete(assigns, :code))
end

def context(context, %{}), do: context

defp text_from_credential_offer(credential_offer) do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@
}
}
</style>

<script>
var source = new EventSource('/openid/presentation_sse?code={{ code }}');
source.addEventListener('message', function(event) {
window.location.href = event.data
})
</script>
4 changes: 4 additions & 0 deletions apps/boruta_web/lib/boruta_web/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ defmodule BorutaWeb.Application do
children = [
BorutaWeb.Endpoint,
BorutaWeb.Repo,
%{
id: BorutaWeb.PresentationServer,
start: {BorutaWeb.PresentationServer, :start_link, []}
},
{Finch, name: FinchHttp},
{Cluster.Supervisor,
[Application.get_env(:libcluster, :topologies), [name: BorutaWeb.ClusterSupervisor]]},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ defmodule BorutaWeb.Oauth.AuthorizeController do
alias BorutaIdentity.IdentityProviders.IdentityProvider
alias BorutaIdentityWeb.Router.Helpers, as: IdentityRoutes
alias BorutaIdentityWeb.TemplateView
alias BorutaWeb.PresentationServer

def authorize(%Plug.Conn{} = conn, _params) do
current_user = conn.assigns[:current_user]
Expand Down Expand Up @@ -439,11 +440,27 @@ defmodule BorutaWeb.Oauth.AuthorizeController do

%{uri | path: Routes.token_path(conn, :direct_post, code)}
|> URI.to_string()
end)
end),
code: response.code
}
)
end

def authenticated?(conn, %{"code" => code}) do
spawn(fn ->
PresentationServer.start_presentation(code)

receive do
{:authenticated, redirect_uri} ->
chunk(conn, redirect_uri)
end
end)

conn
|> put_resp_header("content-type", "text/event-stream")
|> send_chunked(200)
end

def authorize_success(
%Plug.Conn{} = conn,
%SiopV2Response{response_mode: "direct_post"} = response
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ defmodule BorutaWeb.Oauth.TokenController do
alias Boruta.Oauth.TokenResponse
alias Boruta.Openid
alias BorutaWeb.OauthView
alias BorutaWeb.PresentationServer

def token(%Plug.Conn{} = conn, _params) do
conn |> Oauth.token(__MODULE__)
Expand Down Expand Up @@ -103,7 +104,9 @@ defmodule BorutaWeb.Oauth.TokenController do
end

@impl Boruta.Openid.DirectPostApplication
def direct_post_success(conn, callback_uri) do
def direct_post_success(conn, callback_uri, token) do
PresentationServer.authenticated(token.previous_code, token.redirect_uri)

redirect(conn, external: callback_uri)
end
end
38 changes: 38 additions & 0 deletions apps/boruta_web/lib/boruta_web/presentation_server.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
defmodule BorutaWeb.PresentationServer do
use GenServer

def start_link do
GenServer.start_link(__MODULE__, [], name: __MODULE__)
end

def init(_args) do
{:ok, presentations: %{}}
end

def start_presentation(code) do
GenServer.call({:start_presentation, code}, __MODULE__)
end

def authenticated(code, redirect_uri) do
GenServer.cast({:authenticated, code, redirect_uri}, __MODULE__)
end

def handle_call({:start_presentation, code}, pid, state) do
presentations = Map.put(
state.presentations,
code,
%{
start: :os.system_time(:microseconds),
pid: pid
}
)
{:reply, :ok, %{state| presentations: presentations}}
end

def handle_cast({:authenticated, code, redirect_uri}, state) do
presentation = state.presentations[code]
send(presentation[:pid], {:authenticated, redirect_uri})

{:noreply, Map.delete(state, code)}
end
end
1 change: 1 addition & 0 deletions apps/boruta_web/lib/boruta_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ defmodule BorutaWeb.Router do
pipe_through([:api])

post("/direct_post/:code_id", TokenController, :direct_post)
get("/presentation_sse", AuthorizeController, :authenticated?)
end

@impl Plug.ErrorHandler
Expand Down

0 comments on commit 9c590ee

Please sign in to comment.