diff --git a/lib/hostas_web/controllers/auth/token_controller.ex b/lib/hostas_web/controllers/auth/token_controller.ex index 29734d2..c0d4a5a 100644 --- a/lib/hostas_web/controllers/auth/token_controller.ex +++ b/lib/hostas_web/controllers/auth/token_controller.ex @@ -47,17 +47,33 @@ defmodule HostasWeb.Auth.TokenController do @doc """ Responds with 200 OK if the requester's `Bearing` header - contains a valid, non-expired API token + contains a valid, non-expired API token, along with a + payload with an `expires` key detailing when the key + expires. """ - def verify(_conn, _params) do - :ok + def verify(conn, _params) do + conn + |> put_status(200) + |> json(%{"expires" => conn.assigns[:token].expires}) end @doc """ Deletes the token the requester used in the `Bearing` header """ - def revoke(_conn, _params) do - :ok + def revoke(conn, %{"id" => id_param}) do + with {:parsed_id, {id, ""}} <- {:parsed_id, Integer.parse(id_param, 10)}, + {:ok, token} <- fetch_token(id, conn), + {:can_access, true} <- {:can_access, token.denizen_id == conn.assigns[:denizen].id} do + Repo.delete_all(from t in Token, where: t.id == ^token.id) + + conn + |> send_resp(200, "") + else + _ -> + conn + |> put_status(404) + |> json(%{"error" => "Token not found"}) + end end @doc """ @@ -67,4 +83,15 @@ defmodule HostasWeb.Auth.TokenController do def renew(_conn, _params) do :ok end + + defp fetch_token(id, conn) do + if id == conn.assigns[:token].id do + {:ok, conn.assigns[:token]} + else + case Repo.one(from t in Token, where: t.id == ^id) do + nil -> {:error, :token_not_found} + token -> {:ok, token} + end + end + end end diff --git a/test/hostas_web/controllers/auth/token_controller_test.exs b/test/hostas_web/controllers/auth/token_controller_test.exs index be0fecb..1a0c82e 100644 --- a/test/hostas_web/controllers/auth/token_controller_test.exs +++ b/test/hostas_web/controllers/auth/token_controller_test.exs @@ -32,7 +32,7 @@ defmodule HostasWeb.Auth.TokenControllerTest do test "fails due to non-existant denizen", %{conn: conn} do conn = post(conn, ~p"/hostapi/auth/token", %{handle: "denizen", password: "password"}) - assert json_response(conn, 404)["error"] == "No user with handle testuser" + assert json_response(conn, 404)["error"] == "No user with handle denizen" end test "fails due to missing fields", %{conn: conn} do @@ -70,7 +70,7 @@ defmodule HostasWeb.Auth.TokenControllerTest do |> put_req_header("authorization", "Bearer unknown_credential") |> get(~p"/hostapi/auth/token") - assert json_response(conn, 200)["error"] == "Token expired" + assert json_response(conn, 401)["error"] == "API key not found" end end @@ -83,7 +83,7 @@ defmodule HostasWeb.Auth.TokenControllerTest do |> put_req_header("authorization", "Bearer #{struct.token}") |> delete(~p"/hostapi/auth/token/#{struct.id}") - assert json_response(conn, 200) + assert response(conn, 200) end test "fails because it's someone else's token", %{conn: conn} do