Skip to content

Commit

Permalink
added token introspection
Browse files Browse the repository at this point in the history
  • Loading branch information
tommasop authored and danschultzer committed Dec 26, 2024
1 parent 3544015 commit f306c6d
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 4 deletions.
48 changes: 44 additions & 4 deletions lib/assent/strategies/zitadel.ex
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,20 @@ defmodule Assent.Strategy.Zitadel do
end
end

defp jwt_authentication_params(config) do
with {:ok, token} <- gen_client_secret(config) do
headers = []

body = [
scope: "openid",
assertion: token,
grant_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
]

{:ok, headers, body}
end
end

defp process_access_token_response(
{:ok, %HTTPResponse{status: status, body: %{"access_token" => _} = token}}
)
Expand All @@ -127,20 +141,46 @@ defmodule Assent.Strategy.Zitadel do

defp process_response({:error, error}), do: {:error, error}

defp jwt_authentication_params(config) do
@doc """
Introspects a given tokein with zitadel with JWT
"""
@spec introspect_token(Config.t(), binary()) :: {:ok, map()} | {:error, term()}
def introspect_token(config, access_token) do
introspect_url = Config.get(config, :introspect_url, "/oauth/v2/introspect")

with {:ok, base_url} <- Config.__base_url__(config),
{:ok, auth_headers, params} <- jwt_introspection_params(config, access_token) do
headers = [{"content-type", "application/x-www-form-urlencoded"}] ++ auth_headers
url = Helpers.to_url(base_url, introspect_url)
body = URI.encode_query(params)

:post
|> Helpers.request(url, body, headers, config)
|> process_introspect_token_response()
end
end

defp jwt_introspection_params(config, access_token) do
with {:ok, token} <- gen_client_secret(config) do
headers = []

body = [
scope: "openid",
assertion: token,
grant_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
client_assertion: token,
client_assertion_type: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
token: access_token
]

{:ok, headers, body}
end
end

defp process_introspect_token_response(
{:ok, %HTTPResponse{status: status, body: %{"active" => _} = token}}
)
when status in [200, 201] do
{:ok, token}
end

@jwt_expiration_seconds 3600

defp gen_client_secret(config) do
Expand Down
46 changes: 46 additions & 0 deletions test/assent/strategies/zitadel_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,33 @@ defmodule Assent.Strategy.ZitadelTest do
assert {:ok, %{"access_token" => "access_token"}} == Zitadel.authenticate_api(config)
end

test "introspect_token/2", %{config: config} do
config =
Keyword.merge(config,
client_id: @client_id,
resource_id: @resource_id,
private_key: @private_key,
private_key_id: @private_key_id
)

expect_introspect_token_request(
response: %{
active: true,
client_id: @client_id,
scope: "openid email profile",
username: "[email protected]"
}
)

assert {:ok,
%{
"active" => true,
"client_id" => "3425235252@nameofproject",
"scope" => "openid email profile",
"username" => "[email protected]"
}} == Zitadel.introspect_token(config, "access_token")
end

@spec expect_api_access_token_request(Keyword.t(), function() | nil) :: :ok
defp expect_api_access_token_request(opts \\ [], assert_fn \\ nil) do
access_token = Keyword.get(opts, :access_token, "access_token")
Expand All @@ -134,6 +161,25 @@ defmodule Assent.Strategy.ZitadelTest do
)
end

@spec expect_introspect_token_request(Keyword.t(), function() | nil) :: :ok
defp expect_introspect_token_request(opts \\ [], assert_fn \\ nil) do
resp_body = Keyword.get(opts, :response)
uri = Keyword.get(opts, :uri, "/oauth/v2/introspect")
status_code = Keyword.get(opts, :status_code, 200)

TestServer.add(uri,
via: :post,
to: fn conn ->
{:ok, body, _conn} = Plug.Conn.read_body(conn, [])
params = URI.decode_query(body)

if assert_fn, do: assert_fn.(conn, params)

send_json_resp(conn, resp_body, status_code)
end
)
end

defp send_json_resp(conn, body, status_code) do
conn
|> Conn.put_resp_content_type("application/json")
Expand Down

0 comments on commit f306c6d

Please sign in to comment.