Skip to content

Commit

Permalink
Http interface to get token from client credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
geekingfrog committed Jun 16, 2024
1 parent 7b5e250 commit a37f006
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
24 changes: 23 additions & 1 deletion lib/teiserver_web/controllers/o_auth/code_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,21 @@ defmodule TeiserverWeb.OAuth.CodeController do
end
end

def token(conn, %{"grant_type" => "client_credentials"} = params) do
case Enum.find(
["grant_type", "client_id", "client_secret"],
fn key -> not Map.has_key?(params, key) end
) do
nil ->
get_token_from_credentials(conn, params)

missing_key ->
conn |> put_status(400) |> render(:error, error_description: "missing #{missing_key}")
end
end

def token(conn, _params) do
conn |> put_status(400) |> render(:error, error_description: "invalid authorization_code")
conn |> put_status(400) |> render(:error, error_description: "invalid grant_type")
end

defp exchange_token(conn, params) do
Expand All @@ -57,4 +70,13 @@ defmodule TeiserverWeb.OAuth.CodeController do
_ -> conn |> put_status(400) |> render(:error, error_description: "invalid request")
end
end

defp get_token_from_credentials(conn, params) do
with {:ok, cred} <- OAuth.get_valid_credentials(params["client_id"], params["client_secret"]),
{:ok, token} <- OAuth.get_token_from_credentials(cred) do
conn |> put_status(200) |> render(:token, token: token)
else
_ -> conn |> put_status(400) |> render(:error, error_description: "invalid request")
end
end
end
44 changes: 44 additions & 0 deletions test/teiserver_web/controllers/o_auth/code_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ defmodule TeiserverWeb.OAuth.CodeControllerTest do
%{code: code, code_attrs: attrs}
end

defp setup_autohost(_context) do
{:ok, autohost} = Teiserver.Autohost.create_autohost(%{name: "testing_autohost"})
%{autohost: autohost}
end

defp setup_credential(%{autohost: autohost, app: app}) do
secret = "very-much-secret"
{:ok, cred} = OAuth.create_credentials(app, autohost, "cred-client-id", secret)
%{credential: cred, credential_secret: secret}
end

defp setup_token(context) do
{:ok, token} = OAuth.create_token(context[:user], context[:app])
%{token: token}
Expand Down Expand Up @@ -111,6 +122,39 @@ defmodule TeiserverWeb.OAuth.CodeControllerTest do
# so they are omitted here
end

describe "get token from client credentials" do
setup [:setup_conn, :setup_app, :setup_autohost, :setup_credential]

test "it works with the right params", %{
conn: conn,
credential: credential,
credential_secret: secret
} do
data = %{
grant_type: "client_credentials",
client_id: credential.client_id,
client_secret: secret
}

resp = post(conn, ~p"/oauth/token", data)
json_resp = json_response(resp, 200)
assert is_binary(json_resp["access_token"]), "has access_token"
assert is_integer(json_resp["expires_in"]), "has expires_in"
assert is_binary(json_resp["refresh_token"]), "has refresh_token"
assert json_resp["token_type"] == "Bearer", "bearer token type"
end

test "must provide correct secret", %{conn: conn, credential: credential} do
data = %{
grant_type: "client_credentials",
client_id: credential.client_id,
client_secret: "definitely-not-the-correct-secret"
}
resp = post(conn, ~p"/oauth/token", data)
json_resp = json_response(resp, 400)
end
end

describe "refresh token" do
setup [:setup_conn, :setup_app, :setup_token]

Expand Down

0 comments on commit a37f006

Please sign in to comment.