oauth/oidc

This commit is contained in:
bluepython508
2023-11-07 19:35:03 +00:00
parent a0fc306df1
commit 54db8727b0
20 changed files with 670 additions and 3 deletions

View File

@@ -0,0 +1,90 @@
defmodule SsoBsnWeb.Oauth.AuthorizeController do
@behaviour Boruta.Oauth.AuthorizeApplication
use SsoBsnWeb, :controller
alias Boruta.Oauth.AuthorizeResponse
alias Boruta.Oauth.Error
alias Boruta.Oauth.ResourceOwner
alias SsoBsnWeb.OauthView
def oauth_module, do: Application.get_env(:sso_bsn, :oauth_module, Boruta.Oauth)
def authorize(%Plug.Conn{} = conn, _params) do
current_user = conn.assigns[:current_user]
conn = store_user_return_to(conn)
authorize_response(
conn,
current_user
)
end
defp authorize_response(conn, %_{} = current_user) do
conn
|> oauth_module().authorize(
%ResourceOwner{sub: to_string(current_user.id), username: current_user.email},
__MODULE__
)
end
defp authorize_response(conn, _params) do
redirect_to_login(conn)
end
@impl Boruta.Oauth.AuthorizeApplication
def authorize_success(
conn,
%AuthorizeResponse{} = response
) do
redirect(conn, external: AuthorizeResponse.redirect_to_url(response))
end
@impl Boruta.Oauth.AuthorizeApplication
def authorize_error(
%Plug.Conn{} = conn,
%Error{status: :unauthorized}
) do
redirect_to_login(conn)
end
def authorize_error(
conn,
%Error{format: format} = error
)
when not is_nil(format) do
conn
|> redirect(external: Error.redirect_to_url(error))
end
def authorize_error(
conn,
%Error{status: status, error: error, error_description: error_description}
) do
conn
|> put_status(status)
|> put_view(OauthView)
|> render("error.html", error: error, error_description: error_description)
end
@impl Boruta.Oauth.AuthorizeApplication
def preauthorize_success(_conn, _response), do: :ok
@impl Boruta.Oauth.AuthorizeApplication
def preauthorize_error(_conn, _response), do: :ok
defp store_user_return_to(conn) do
conn
|> put_session(
:user_return_to,
current_path(conn)
)
end
defp redirect_to_login(_conn) do
raise """
Here occurs the login process. After login, user may be redirected to
get_session(conn, :user_return_to)
"""
end
end

View File

@@ -0,0 +1,64 @@
defmodule SsoBsnWeb.Oauth.IntrospectController do
@behaviour Boruta.Oauth.IntrospectApplication
use SsoBsnWeb, :controller
alias Boruta.Oauth.Error
alias Boruta.Oauth.IntrospectResponse
alias SsoBsnWeb.OauthView
def oauth_module, do: Application.get_env(:sso_bsn, :oauth_module, Boruta.Oauth)
def introspect(%Plug.Conn{} = conn, _params) do
conn |> oauth_module().introspect(__MODULE__)
end
@impl Boruta.Oauth.IntrospectApplication
def introspect_success(conn, %IntrospectResponse{} = response) do
conn
|> put_view(OauthView)
|> introspect(response: response)
end
def introspect(%{
response: %IntrospectResponse{
active: active,
client_id: client_id,
username: username,
scope: scope,
sub: sub,
iss: iss,
exp: exp,
iat: iat
}
}) do
case active do
true ->
%{
active: true,
client_id: client_id,
username: username,
scope: scope,
sub: sub,
iss: iss,
exp: exp,
iat: iat
}
false ->
%{active: false}
end
end
@impl Boruta.Oauth.IntrospectApplication
def introspect_error(conn, %Error{
status: status,
error: error,
error_description: error_description
}) do
conn
|> put_status(status)
|> json(%{error: error, error_description: error_description})
end
end

View File

@@ -0,0 +1,31 @@
defmodule SsoBsnWeb.Oauth.RevokeController do
@behaviour Boruta.Oauth.RevokeApplication
use SsoBsnWeb, :controller
alias Boruta.Oauth.Error
alias SsoBsnWeb.OauthView
def oauth_module, do: Application.get_env(:sso_bsn, :oauth_module, Boruta.Oauth)
def revoke(%Plug.Conn{} = conn, _params) do
conn |> oauth_module().revoke(__MODULE__)
end
@impl Boruta.Oauth.RevokeApplication
def revoke_success(%Plug.Conn{} = conn) do
send_resp(conn, 200, "")
end
@impl Boruta.Oauth.RevokeApplication
def revoke_error(conn, %Error{
status: status,
error: error,
error_description: error_description
}) do
conn
|> put_status(status)
|> put_view(OauthView)
|> json(%{error: error, error_description: error_description})
end
end

View File

@@ -0,0 +1,50 @@
defmodule SsoBsnWeb.Oauth.TokenController do
@behaviour Boruta.Oauth.TokenApplication
use SsoBsnWeb, :controller
alias Boruta.Oauth.Error
alias Boruta.Oauth.TokenResponse
def oauth_module, do: Application.get_env(:sso_bsn, :oauth_module, Boruta.Oauth)
def token(%Plug.Conn{} = conn, _params) do
conn |> oauth_module().token(__MODULE__)
end
@impl Boruta.Oauth.TokenApplication
def token_success(conn, %TokenResponse{
token_type: token_type,
access_token: access_token,
expires_in: expires_in,
refresh_token: refresh_token,
id_token: id_token
}) do
conn
|> put_resp_header("pragma", "no-cache")
|> put_resp_header("cache-control", "no-store")
|> json(
%{
token_type: token_type,
access_token: access_token,
expires_in: expires_in,
refresh_token: refresh_token,
id_token: id_token
}
|> Enum.filter(
fn
{_key, nil} -> false
_ -> true
end
)
|> Enum.into(%{})
)
end
@impl Boruta.Oauth.TokenApplication
def token_error(conn, %Error{status: status, error: error, error_description: error_description}) do
conn
|> put_status(status)
|> json(%{error: error, error_description: error_description})
end
end