Skip to content

Commit

Permalink
Fix spec errors
Browse files Browse the repository at this point in the history
  • Loading branch information
danschultzer committed Dec 28, 2024
1 parent df1a8fd commit c3f7243
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 39 deletions.
14 changes: 9 additions & 5 deletions lib/assent/strategies/oauth.ex
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ defmodule Assent.Strategy.OAuth do
UnexpectedResponseError
}

@type session_params :: %{
oauth_token_secret: binary()
}

@type on_authorize_url :: {:ok, %{session_params: session_params(), url: binary()}} | {:error, term()}
@type on_callback :: {:ok, %{user: map(), token: map()}} | {:error, term()}

@doc """
Generate authorization URL for request phase.
Expand All @@ -71,9 +78,7 @@ defmodule Assent.Strategy.OAuth do
- `:authorization_params` - The authorization parameters, defaults to `[]`
"""
@impl true
@spec authorize_url(Config.t()) ::
{:ok, %{url: binary(), session_params: %{oauth_token_secret: binary()}}}
| {:error, term()}
@spec authorize_url(Config.t()) :: on_authorize_url()
def authorize_url(config) do
case Config.fetch(config, :redirect_uri) do
{:ok, redirect_uri} -> authorize_url(config, redirect_uri)
Expand Down Expand Up @@ -342,8 +347,7 @@ defmodule Assent.Strategy.OAuth do
`authorize_url/1`, optional
"""
@impl true
@spec callback(Config.t(), map(), atom()) ::
{:ok, %{user: map(), token: map()}} | {:error, term()}
@spec callback(Config.t(), map(), atom()) :: on_callback()
def callback(config, params, strategy \\ __MODULE__) do
with {:ok, oauth_token} <- fetch_oauth_token(params),
{:ok, oauth_verifier} <- fetch_oauth_verifier(params),
Expand Down
5 changes: 2 additions & 3 deletions lib/assent/strategies/oauth/base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -65,15 +65,14 @@ defmodule Assent.Strategy.OAuth.Base do
end
end

@spec authorize_url(Keyword.t(), module()) :: {:ok, %{url: binary()}} | {:error, term()}
@spec authorize_url(Keyword.t(), module()) :: OAuth.on_authorize_url()
def authorize_url(config, strategy) do
config
|> set_config(strategy)
|> OAuth.authorize_url()
end

@spec callback(Keyword.t(), map(), module()) ::
{:ok, %{user: map(), token: map()}} | {:error, term()}
@spec callback(Keyword.t(), map(), module()) :: OAuth.on_callback()
def callback(config, params, strategy) do
config = set_config(config, strategy)

Expand Down
9 changes: 5 additions & 4 deletions lib/assent/strategies/oauth2.ex
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ defmodule Assent.Strategy.OAuth2 do
optional(:code_challenge_method) => binary()
}

@type on_authorize_url :: {:ok, %{session_params: session_params(), url: binary()}} | {:error, term()}
@type on_callback :: {:ok, %{user: map(), token: map()}} | {:error, term()}

@doc """
Generate authorization URL for request phase.
Expand All @@ -108,8 +111,7 @@ defmodule Assent.Strategy.OAuth2 do
- `:authorization_params` - The authorization parameters, defaults to `[]`
"""
@impl true
@spec authorize_url(Config.t()) ::
{:ok, %{session_params: session_params(), url: binary()}} | {:error, term()}
@spec authorize_url(Config.t()) :: on_authorize_url()
def authorize_url(config) do
config = deprecated_state_handling(config)

Expand Down Expand Up @@ -209,8 +211,7 @@ defmodule Assent.Strategy.OAuth2 do
`authorize_url/1`, optional
"""
@impl true
@spec callback(Config.t(), map(), atom()) ::
{:ok, %{user: map(), token: map()}} | {:error, term()}
@spec callback(Config.t(), map(), atom()) :: on_callback()
def callback(config, params, strategy \\ __MODULE__) do
with {:ok, session_params} <- Config.fetch(config, :session_params),
:ok <- check_error_params(params),
Expand Down
6 changes: 2 additions & 4 deletions lib/assent/strategies/oauth2/base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,14 @@ defmodule Assent.Strategy.OAuth2.Base do
end
end

@spec authorize_url(Keyword.t(), module()) ::
{:ok, %{session_params: %{state: binary()}, url: binary()}}
@spec authorize_url(Keyword.t(), module()) :: OAuth2.on_authorize_url()
def authorize_url(config, strategy) do
config
|> set_config(strategy)
|> OAuth2.authorize_url()
end

@spec callback(Keyword.t(), map(), module()) ::
{:ok, %{user: map(), token: map()}} | {:error, term()}
@spec callback(Keyword.t(), map(), module()) :: OAuth2.on_callback()
def callback(config, params, strategy) do
config = set_config(config, strategy)

Expand Down
43 changes: 29 additions & 14 deletions lib/assent/strategies/oidc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,17 @@ defmodule Assent.Strategy.OIDC do
UnexpectedResponseError
}

@type session_params :: %{
optional(:state) => binary(),
optional(:code_verifier) => binary(),
optional(:code_challenge) => binary(),
optional(:code_challenge_method) => binary(),
optional(:nonce) => binary()
}

@type on_authorize_url :: OAuth2.on_authorize_url()
@type on_callback :: OAuth2.on_callback()

@doc """
Generates an authorization URL for request phase.
Expand All @@ -103,13 +114,7 @@ defmodule Assent.Strategy.OIDC do
See `Assent.Strategy.OAuth2.authorize_url/1` for more.
"""
@impl true
@spec authorize_url(Config.t()) ::
{:ok,
%{
session_params: %{state: binary()} | %{state: binary(), nonce: binary()},
url: binary()
}}
| {:error, term()}
@spec authorize_url(Config.t()) :: on_authorize_url()
def authorize_url(config) do
with {:ok, openid_config} <- openid_configuration(config),
{:ok, authorize_url} <-
Expand Down Expand Up @@ -225,8 +230,7 @@ defmodule Assent.Strategy.OIDC do
See `Assent.Strategy.OAuth2.callback/3` for more.
"""
@impl true
@spec callback(Config.t(), map(), atom()) ::
{:ok, %{user: map(), token: map()}} | {:error, term()}
@spec callback(Config.t(), map(), atom()) :: on_callback()
def callback(config, params, strategy \\ __MODULE__) do
with {:ok, openid_config} <- openid_configuration(config),
{:ok, method} <- fetch_client_authentication_method(openid_config, config),
Expand Down Expand Up @@ -332,12 +336,23 @@ defmodule Assent.Strategy.OIDC do
end

defp peek_header(encoded, config) do
with [header, _, _] <- String.split(encoded, "."),
{:ok, json} <- Base.url_decode64(header, padding: false) do
with {:ok, header} <- split_header(encoded),
{:ok, json} <- decode_base64_url(header) do
Config.json_library(config).decode(json)
else
{:error, error} -> {:error, error}
_any -> {:error, "The ID Token is not a valid JWT"}
end
end

defp split_header(encoded) do
case String.split(encoded, ".") do
[header, _, _] -> {:ok, header}
_ -> {:error, "The ID Token is not a valid JWT"}
end
end

defp decode_base64_url(encoded) do
case Base.url_decode64(encoded, padding: false) do
{:ok, decoded} -> {:ok, decoded}
:error -> {:error, "Invalid Base64URL"}
end
end

Expand Down
11 changes: 2 additions & 9 deletions lib/assent/strategies/oidc/base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,14 @@ defmodule Assent.Strategy.OIDC.Base do
end
end

@spec authorize_url(Keyword.t(), module()) ::
{:ok,
%{
session_params: %{state: binary()} | %{state: binary(), nonce: binary()},
url: binary()
}}
| {:error, term()}
@spec authorize_url(Keyword.t(), module()) :: OIDC.on_authorize_url()
def authorize_url(config, strategy) do
config
|> set_config(strategy)
|> OIDC.authorize_url()
end

@spec callback(Keyword.t(), map(), module()) ::
{:ok, %{user: map(), token: map()}} | {:error, term()}
@spec callback(Keyword.t(), map(), module()) :: OIDC.on_callback()
def callback(config, params, strategy) do
config = set_config(config, strategy)

Expand Down
5 changes: 5 additions & 0 deletions test/assent/strategies/oidc_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,11 @@ defmodule Assent.Strategy.OIDCTest do
{:error, "The ID Token is not a valid JWT"}
end

test "with invalid base64 header in id_token", %{config: config} do
assert OIDC.validate_id_token(config, "@invalid.payload.signature") ==
{:error, "Invalid Base64URL"}
end

test "with no `:client_secret`", %{config: config, id_token: id_token} do
config = Keyword.delete(config, :client_secret)

Expand Down

0 comments on commit c3f7243

Please sign in to comment.