Skip to content

Commit

Permalink
Let admins access the management pages, but filter the data by facility.
Browse files Browse the repository at this point in the history
  • Loading branch information
fcapovilla authored and bglusman committed Jan 17, 2018
1 parent 8e5fbc6 commit 9acb8d0
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 27 deletions.
14 changes: 9 additions & 5 deletions lib/open_pantry/plugs/setup_user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,15 @@ defmodule OpenPantry.Plugs.SetupUser do
end

defp user_from_token({:ok, token}, conn) do
%{"aud" => <<"User:", id :: binary >>} = Guardian.decode_and_verify!(token)
user = String.to_integer(id)
|> User.query
|> Repo.one
{conn, user}
try do
%{"aud" => <<"User:", id :: binary >>} = Guardian.decode_and_verify!(token)
user = String.to_integer(id)
|> User.query
|> Repo.one
{conn, user}
rescue
RuntimeError -> {conn, User.guest()}
end
end

defp user_from_token({:error, :no_token}, conn) do
Expand Down
16 changes: 16 additions & 0 deletions lib/open_pantry/repo.ex
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
defmodule OpenPantry.Repo do
use Ecto.Repo, otp_app: :open_pantry
use Scrivener, page_size: 10

import Ecto.Query, only: [from: 2]

alias OpenPantry.User

def filter_facility(query, conn) do
user = Guardian.Plug.current_resource(conn)
case user do
%User{role: :superadmin} ->
query
%User{role: :admin, facility_id: facility_id} when facility_id > 0 ->
from q in query, where: q.facility_id == ^facility_id
_ ->
from q in query, where: is_nil(q.facility_id)
end
end
end
2 changes: 2 additions & 0 deletions lib/open_pantry/web/controllers/facility_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ defmodule OpenPantry.Web.FacilityController do

alias OpenPantry.Facility

plug Guardian.Plug.EnsurePermissions, handler: OpenPantry.Web.AuthController, role: [:superadmin]

def index(conn, _params) do
facilities = Repo.all(Facility)
render(conn, "index.html", facilities: facilities)
Expand Down
13 changes: 9 additions & 4 deletions lib/open_pantry/web/controllers/stock_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ defmodule OpenPantry.Web.StockController do
),
preload: [:food, :meal, :offer]
)
|> Repo.filter_facility(conn)
|> Repo.all()
render(conn, "index.html", stocks: stocks)
end
Expand All @@ -39,18 +40,18 @@ defmodule OpenPantry.Web.StockController do
end

def show(conn, %{"id" => id}) do
stock = Repo.get!(Stock, id)
stock = get_stock(id, conn)
render(conn, "show.html", stock: stock)
end

def edit(conn, %{"id" => id}) do
stock = Repo.get!(Stock, id)
stock = get_stock(id, conn)
changeset = Stock.changeset(stock)
render(conn, "edit.html", stock: stock, changeset: changeset)
end

def update(conn, %{"id" => id, "stock" => stock_params}) do
stock = Repo.get!(Stock, id)
stock = get_stock(id, conn)
changeset = Stock.changeset(stock, stock_params)

case Repo.update(changeset) do
Expand All @@ -64,7 +65,7 @@ defmodule OpenPantry.Web.StockController do
end

def delete(conn, %{"id" => id}) do
stock = Repo.get!(Stock, id)
stock = get_stock(id, conn)

# Here we use delete! (with a bang) because we expect
# it to always work (and if it does not, it will raise).
Expand All @@ -74,4 +75,8 @@ defmodule OpenPantry.Web.StockController do
|> put_flash(:info, "Stock deleted successfully.")
|> redirect(to: stock_path(conn, :index))
end

defp get_stock(id, conn) do
Stock |> Repo.filter_facility(conn) |> Repo.get!(id)
end
end
14 changes: 7 additions & 7 deletions lib/open_pantry/web/controllers/user_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule OpenPantry.Web.UserController do
alias OpenPantry.User

def index(conn, _params) do
users = Repo.all(User)
users = User |> Repo.filter_facility(conn) |> Repo.all
render(conn, "index.html", users: users)
end

Expand All @@ -26,18 +26,18 @@ defmodule OpenPantry.Web.UserController do
end

def show(conn, %{"id" => id}) do
user = get_user(id)
user = get_user(id, conn)
render(conn, "show.html", user: user)
end

def edit(conn, %{"id" => id}) do
user = get_user(id)
user = get_user(id, conn)
changeset = User.changeset(user, %{})
render(conn, "edit.html", user: user, changeset: changeset)
end

def update(conn, %{"id" => id, "user" => user_params}) do
user = get_user(id)
user = get_user(id, conn)

case update_user(user, user_params) do
{:ok, user} ->
Expand All @@ -50,16 +50,16 @@ defmodule OpenPantry.Web.UserController do
end

def delete(conn, %{"id" => id}) do
user = Repo.get!(User, id)
user = get_user(id, conn)
{:ok, _user} = Repo.delete(user)

conn
|> put_flash(:info, "User deleted successfully.")
|> redirect(to: user_path(conn, :index))
end

defp get_user(id) do
User |> Repo.get!(id)
defp get_user(id, conn) do
User |> Repo.filter_facility(conn) |> Repo.get!(id)
end

defp create_user(attrs \\ %{}) do
Expand Down
43 changes: 33 additions & 10 deletions lib/open_pantry/web/controllers/user_order_controller.ex
Original file line number Diff line number Diff line change
@@ -1,33 +1,56 @@
defmodule OpenPantry.Web.UserOrderController do
use OpenPantry.Web, :controller

require Ecto.Query

alias Ecto.Query
alias OpenPantry.User
alias OpenPantry.UserOrder

def index(conn, params) do
orders =
UserOrder
|> Query.preload(:user)
|> filter_facility(conn)
|> orders_for_params(params)
|> Repo.all
conn
|> setup_channel_credentials(params)
|> render("index.html", orders: orders_for_params(params), conn: conn)
|> render("index.html", orders: orders, conn: conn)
end

def show(conn, %{"id" => id}) do
order = UserOrder.find(String.to_integer(id), [:user, :stock_distributions, :stocks, :foods, :meals, :offers] )
order =
UserOrder
|> Query.preload([:user, :stock_distributions, :stocks, :foods, :meals, :offers])
|> filter_facility(conn)
|> Repo.get!(id)
render(conn, "show.html", order: order)
end

defp orders_for_params(%{"all" => _}) do
UserOrder.all(:user)
defp orders_for_params(query, %{"all" => _}) do
query
end

defp orders_for_params(%{"ready" => _}) do
UserOrder.all(:user)
|> Enum.filter(&(&1.ready_for_pickup))
defp orders_for_params(query, %{"ready" => _}) do
query |> Query.where(ready_for_pickup: true)
end

defp orders_for_params(_) do
UserOrder.all(:user)
|> Enum.filter(&(&1.finalized && !&1.ready_for_pickup))
defp orders_for_params(query, _) do
query |> Query.where(finalized: true) |> Query.where(ready_for_pickup: false)
end

defp filter_facility(query, conn) do
user = Guardian.Plug.current_resource(conn)
case user do
%User{role: :superadmin} ->
query
%User{role: :admin, facility_id: facility_id} when facility_id > 0 ->
Query.from q in query, join: u in assoc(q, :user), where: u.facility_id == ^facility_id
_ ->
Query.from q in query, join: u in assoc(q, :user), where: is_nil(u.facility_id)
end
end

# Temporary hack while hardcoding to facility 1, but needs some kind of user token for websocket auth
defp setup_channel_credentials(conn, _params) do
Expand Down
3 changes: 2 additions & 1 deletion lib/open_pantry/web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ defmodule OpenPantry.Web.Router do

pipeline :admin_auth do
plug Guardian.Plug.EnsureAuthenticated, handler: OpenPantry.Web.AuthController
plug Guardian.Plug.EnsurePermissions, handler: OpenPantry.Web.AuthController, role: [:superadmin]
plug Guardian.Plug.EnsurePermissions, handler: OpenPantry.Web.AuthController,
one_of: [%{role: [:admin]}, %{role: [:superadmin]}]
end

pipeline :user_required do
Expand Down

0 comments on commit 9acb8d0

Please sign in to comment.