Skip to content

Commit f08205d

Browse files
committed
Refactor into EnsureRoles
1 parent 85a4517 commit f08205d

File tree

7 files changed

+63
-45
lines changed

7 files changed

+63
-45
lines changed

lib/cadet_web/plug/check_admin.ex

Lines changed: 0 additions & 21 deletions
This file was deleted.

lib/cadet_web/plug/ensure_roles.ex

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
defmodule CadetWeb.Plug.EnsureRoles do
2+
@moduledoc """
3+
Ensures that :current_user's role is inside a list provided as option.
4+
If the user is not inside the list, HTTP 403 response will be sent.
5+
"""
6+
7+
import Plug.Conn
8+
9+
def init(opts), do: opts
10+
11+
def call(conn, %{roles: roles}) do
12+
if conn.assigns[:current_user].role in roles do
13+
conn
14+
else
15+
body =
16+
roles
17+
|> Enum.map(&to_string/1)
18+
|> Enum.join("/")
19+
conn
20+
|> put_resp_content_type("text/html")
21+
|> send_resp(:forbidden, "Not #{body}")
22+
|> halt()
23+
end
24+
end
25+
end

lib/cadet_web/router.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ defmodule CadetWeb.Router do
1818
plug(Guardian.Plug.EnsureAuthenticated)
1919
end
2020

21-
pipeline :ensure_admin do
22-
plug(CadetWeb.Plug.CheckAdmin)
21+
pipeline :ensure_admin_staff do
22+
plug(CadetWeb.Plug.EnsureRoles, %{roles: [:admin, :staff]})
2323
end
2424

2525
# Public Pages
@@ -39,7 +39,7 @@ defmodule CadetWeb.Router do
3939

4040
# Admin Pages
4141
scope "/admin", CadetWeb do
42-
pipe_through([:browser, :auth, :ensure_auth, :ensure_admin])
42+
pipe_through([:browser, :auth, :ensure_auth, :ensure_admin_staff])
4343

4444
get("/", AdminController, :index)
4545
end

lib/cadet_web/templates/layout/app.navbar.html.eex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
Playground
2121
</button>
2222

23-
<%= if is_admin?(@conn) do %>
23+
<%= if is_roles?(@conn, [:admin, :staff]) do %>
2424
<%= button "Admin", to: admin_path(@conn, :index), method: "get", class: "pt-button pt-minimal pt-icon-settings" %>
2525
<% end %>
2626

lib/cadet_web/views/view_helpers.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ defmodule CadetWeb.ViewHelpers do
88
conn.assigns[:current_user] != nil
99
end
1010

11-
def is_admin?(conn) do
11+
def is_roles?(conn, roles) do
1212
if logged_in?(conn) do
13-
conn.assigns[:current_user].role == :admin
13+
conn.assigns[:current_user].role in roles
1414
else
1515
false
1616
end

test/cadet_web/plug/check_admin_test.exs

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
defmodule CadetWeb.Plug.EnsureRolesTest do
2+
use CadetWeb.ConnCase
3+
4+
alias CadetWeb.Plug.AssignCurrentUser
5+
alias CadetWeb.Plug.EnsureRoles
6+
7+
test "init" do
8+
EnsureRoles.init(%{})
9+
# nothing to test
10+
end
11+
12+
@tag authenticate: :student
13+
test "logged in as student", %{conn: conn} do
14+
conn = AssignCurrentUser.call(conn, %{})
15+
conn = EnsureRoles.call(conn, %{roles: [:admin, :staff]})
16+
assert html_response(conn, 403) =~ "Not admin/staff"
17+
end
18+
19+
@tag authenticate: :staff
20+
test "logged in as staff", %{conn: conn} do
21+
conn = AssignCurrentUser.call(conn, %{})
22+
conn = EnsureRoles.call(conn, %{roles: [:admin, :staff]})
23+
refute conn.status # conn.status is not set yet
24+
end
25+
26+
@tag authenticate: :admin
27+
test "logged in as admin", %{conn: conn} do
28+
conn = AssignCurrentUser.call(conn, %{})
29+
conn = EnsureRoles.call(conn, %{roles: [:admin, :staff]})
30+
refute conn.status # conn.status is not set yet
31+
end
32+
end

0 commit comments

Comments
 (0)