Skip to content

Commit

Permalink
Basic check for scopes when refreshing
Browse files Browse the repository at this point in the history
This is incomplete but until teiserver supports more than one scope it
is not really possible to test that. It also doesn't really make sense.
  • Loading branch information
geekingfrog committed Aug 6, 2024
1 parent d0db322 commit 95ed769
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 0 deletions.
27 changes: 27 additions & 0 deletions lib/teiserver_web/controllers/o_auth/code_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ defmodule TeiserverWeb.OAuth.CodeController do
end
end

# As per https://datatracker.ietf.org/doc/html/rfc6749#section-6 this
# endpoint should accept the parameter `scope`.
# As of writing, there is only ever one scope allowed: tachyon.lobby
# so this parameter is ignored.
# If we ever expand the allowed scopes, this feature should be added
def token(conn, %{"grant_type" => "refresh_token"} = params) do
case check_required_keys(params, ["grant_type", "refresh_token", "client_id"]) do
:ok ->
Expand Down Expand Up @@ -68,6 +73,9 @@ defmodule TeiserverWeb.OAuth.CodeController do

defp refresh_token(conn, params) do
with {:ok, app} <- get_app_by_uid(params["client_id"]),
# Once we support more than one single scope, modify this function to allow
# changing the scope of the new token
{:ok, _scopes} <- check_scopes(app, params),
{:ok, token} <- OAuth.get_valid_token(params["refresh_token"]),
:ok <-
if(token.application_id == app.id,
Expand Down Expand Up @@ -137,6 +145,25 @@ defmodule TeiserverWeb.OAuth.CodeController do
end
end

defp check_scopes(app, params) do
scopes = Map.get(params, "scope", "") |> String.split() |> Enum.into(MapSet.new())
app_scopes = MapSet.new(app.scopes)

cond do
MapSet.size(scopes) == 0 ->
{:ok, app.scopes}

MapSet.subset?(scopes, app_scopes) ->
{:ok, MapSet.to_list(scopes)}

true ->
invalid_scopes = MapSet.difference(scopes, app_scopes)

{:error,
"the following scopes aren't allowed: #{inspect(MapSet.to_list(invalid_scopes))}"}
end
end

def metadata(conn, _params) do
conn |> put_status(200) |> render(:metadata)
end
Expand Down
12 changes: 12 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 @@ -299,6 +299,18 @@ defmodule TeiserverWeb.OAuth.CodeControllerTest do
resp = post(conn, ~p"/oauth/token", data)
assert %{"error" => "invalid_request"} = json_response(resp, 400)
end

test "must provide valid scope", %{conn: conn} = setup_data do
data = %{
grant_type: "refresh_token",
client_id: setup_data[:app].uid,
refresh_token: setup_data[:token].refresh_token.value,
scope: "lolscope"
}

resp = post(conn, ~p"/oauth/token", data)
assert %{"error" => "invalid_request"} = json_response(resp, 400)
end
end

describe "medatata endpoint" do
Expand Down

0 comments on commit 95ed769

Please sign in to comment.