Skip to content

Commit

Permalink
Lock down API mutation endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
tomkonidas committed Sep 2, 2023
1 parent a8b34d4 commit a596d16
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 8 deletions.
48 changes: 48 additions & 0 deletions lib/plexus_web/api_auth_plug.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
defmodule PlexusWeb.APIAuthPlug do
@behaviour Plug

import Plug.Conn

@endpoint PlexusWeb.Endpoint
@salt "device auth"

@impl Plug
def init(opts) do
opts
end

@impl Plug
def call(conn, _opts) do
with {:ok, token} <- fetch_authorization_token(conn) do
case Phoenix.Token.verify(@endpoint, @salt, token) do
{:ok, %{device_id: _device_id, email: _email}} ->
conn

{:error, :expired} ->
conn
|> send_resp(401, "Token is expired")
|> halt()

{:error, :invalid} ->
conn
|> send_resp(401, "Invalid token")
|> halt()

{:error, :missing} ->
conn
|> send_resp(401, "Token is missing")
|> halt()
end
end
end

defp fetch_authorization_token(conn) do
case get_req_header(conn, "authorization") do
["Bearer " <> token] ->
{:ok, token}

_ ->
send_resp(conn, 401, "Authorization header is missing")
end
end
end
13 changes: 11 additions & 2 deletions lib/plexus_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ defmodule PlexusWeb.Router do
plug :accepts, ["json"]
end

pipeline :authenticated_device do
plug PlexusWeb.APIAuthPlug
end

scope "/", PlexusWeb do
pipe_through :browser

Expand All @@ -36,13 +40,18 @@ defmodule PlexusWeb.Router do
scope "/api/v1", PlexusWeb.API.V1 do
pipe_through :api

scope "/" do
pipe_through :authenticated_device

post "/apps", AppController, :create
post "/apps/:package/ratings", RatingController, :create
end

get "/apps", AppController, :index
get "/apps/:package", AppController, :show
post "/apps", AppController, :create

get "/apps/:package/ratings", RatingController, :index
get "/apps/:package/ratings/:id", RatingController, :show
post "/apps/:package/ratings", RatingController, :create

post "/devices/register", DeviceController, :register
post "/devices/verify", DeviceController, :verify
Expand Down
4 changes: 1 addition & 3 deletions test/plexus_web/controllers/api/v1/app_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ defmodule PlexusWeb.API.V1.AppControllerTest do

@invalid_attrs %{name: nil, package: nil}

setup %{conn: conn} do
{:ok, conn: put_req_header(conn, "accept", "application/json")}
end
setup [:setup_json, :setup_authenticated_device]

describe "index" do
test "lists all apps", %{conn: conn} do
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ defmodule PlexusWeb.API.V1.RatingControllerTest do
score: nil
}

setup %{conn: conn} do
{:ok, conn: put_req_header(conn, "accept", "application/json")}
end
setup [:setup_json, :setup_authenticated_device]

describe "index" do
test "lists all ratings", %{conn: conn} do
Expand Down
16 changes: 16 additions & 0 deletions test/support/conn_case.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ defmodule PlexusWeb.ConnCase do

use ExUnit.CaseTemplate

@salt "device auth"

using do
quote do
# The default endpoint for testing
Expand All @@ -35,4 +37,18 @@ defmodule PlexusWeb.ConnCase do
Plexus.DataCase.setup_sandbox(tags)
{:ok, conn: Phoenix.ConnTest.build_conn()}
end

def setup_json(context) do
{:ok, conn: Plug.Conn.put_req_header(context.conn, "accept", "application/json")}
end

def setup_authenticated_device(context) do
token =
Phoenix.Token.sign(PlexusWeb.Endpoint, @salt, %{
device_id: "device_id",
email: "user@techlore.tech"
})

{:ok, conn: Plug.Conn.put_req_header(context.conn, "authorization", "Bearer " <> token)}
end
end

0 comments on commit a596d16

Please sign in to comment.