Skip to content

Commit

Permalink
change roles to admin, manage, and view
Browse files Browse the repository at this point in the history
and switch to varchars instead of Postgres Enums
  • Loading branch information
joshk authored and jjcarstens committed Dec 28, 2023
1 parent e63f0a2 commit ff90726
Show file tree
Hide file tree
Showing 33 changed files with 108 additions and 105 deletions.
3 changes: 2 additions & 1 deletion lib/nerves_hub/accounts/invite.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ defmodule NervesHub.Accounts.Invite do
import Ecto.Changeset

alias NervesHub.Accounts.Org
alias NervesHub.Accounts.OrgUser
alias __MODULE__

@type t :: %__MODULE__{}
Expand All @@ -14,7 +15,7 @@ defmodule NervesHub.Accounts.Invite do
field(:email, :string)
field(:token, Ecto.UUID)
field(:accepted, :boolean)
field(:role, Ecto.Enum, values: Ecto.Enum.values(NervesHub.Accounts.OrgUser, :role))
field(:role, Ecto.Enum, values: Ecto.Enum.values(OrgUser, :role))

timestamps()
end
Expand Down
2 changes: 1 addition & 1 deletion lib/nerves_hub/accounts/org_user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ defmodule NervesHub.Accounts.OrgUser do
belongs_to(:org, Org, where: [deleted_at: nil])
belongs_to(:user, User, where: [deleted_at: nil])

field(:role, Ecto.Enum, values: [:admin, :delete, :write, :read])
field(:role, Ecto.Enum, values: [:admin, :manage, :view])
field(:deleted_at, :utc_datetime)

timestamps()
Expand Down
5 changes: 2 additions & 3 deletions lib/nerves_hub/accounts/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,8 @@ defmodule NervesHub.Accounts.User do
|> preload(orgs: [:org_keys])
end

def role_or_higher(:read), do: [:read, :write, :delete, :admin]
def role_or_higher(:write), do: [:write, :delete, :admin]
def role_or_higher(:delete), do: [:delete, :admin]
def role_or_higher(:view), do: [:view, :manage, :admin]
def role_or_higher(:manage), do: [:manage, :admin]
def role_or_higher(:admin), do: [:admin]

defp password_validations(%Changeset{} = changeset) do
Expand Down
2 changes: 1 addition & 1 deletion lib/nerves_hub/products.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ defmodule NervesHub.Products do
on: p.org_id == ou.org_id,
where:
p.org_id == ^org_id and ou.user_id == ^user_id and
ou.role in ^User.role_or_higher(:read),
ou.role in ^User.role_or_higher(:view),
group_by: p.id
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ defmodule NervesHubWeb.API.CACertificateController do

action_fallback(NervesHubWeb.API.FallbackController)

plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :write] when action in [:create])
plug(:validate_role, [org: :read] when action in [:index, :show])
plug(:validate_role, [org: :manage] when action in [:create, :delete])
plug(:validate_role, [org: :view] when action in [:index, :show])

def index(%{assigns: %{org: org}} = conn, _params) do
ca_certificates = Devices.get_ca_certificates(org)
Expand Down
5 changes: 2 additions & 3 deletions lib/nerves_hub_web/controllers/api/deployment_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,8 @@ defmodule NervesHubWeb.API.DeploymentController do

action_fallback(NervesHubWeb.API.FallbackController)

plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :write] when action in [:create, :update])
plug(:validate_role, [org: :read] when action in [:index, :show])
plug(:validate_role, [org: :manage] when action in [:create, :update, :delete])
plug(:validate_role, [org: :view] when action in [:index, :show])

@whitelist_fields [:name, :org_id, :firmware_id, :conditions, :is_active]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ defmodule NervesHubWeb.API.DeviceCertificateController do

action_fallback(NervesHubWeb.API.FallbackController)

plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :write] when action in [:create])
plug(:validate_role, [org: :read] when action in [:index, :show])
plug(:validate_role, [org: :manage] when action in [:create, :delete])
plug(:validate_role, [org: :view] when action in [:index, :show])

def index(%{assigns: %{org: org}} = conn, %{"identifier" => identifier}) do
with {:ok, device} <- Devices.get_device_by_identifier(org, identifier) do
Expand Down
17 changes: 8 additions & 9 deletions lib/nerves_hub_web/controllers/api/device_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ defmodule NervesHubWeb.API.DeviceController do

action_fallback(NervesHubWeb.API.FallbackController)

plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :write] when action in [:create, :update])
plug(:validate_role, [org: :read] when action in [:index, :auth])
plug(:validate_role, [org: :manage] when action in [:create, :update, :delete])
plug(:validate_role, [org: :view] when action in [:index, :auth])

def index(%{assigns: %{org: org, product: product}} = conn, params) do
opts = %{
Expand Down Expand Up @@ -55,7 +54,7 @@ defmodule NervesHubWeb.API.DeviceController do

case Devices.get_by_identifier(identifier) do
{:ok, device} ->
if Accounts.has_org_role?(device.org, user, :read) do
if Accounts.has_org_role?(device.org, user, :view) do
conn
|> assign(:device, device)
|> render("show.json")
Expand Down Expand Up @@ -114,7 +113,7 @@ defmodule NervesHubWeb.API.DeviceController do

case Devices.get_by_identifier(identifier) do
{:ok, device} ->
if Accounts.has_org_role?(device.org, user, :write) do
if Accounts.has_org_role?(device.org, user, :manage) do
message = "user #{user.username} rebooted device #{device.identifier}"
AuditLogs.audit!(user, device, message)

Expand All @@ -140,7 +139,7 @@ defmodule NervesHubWeb.API.DeviceController do

case Devices.get_by_identifier(identifier) do
{:ok, device} ->
if Accounts.has_org_role?(device.org, user, :write) do
if Accounts.has_org_role?(device.org, user, :manage) do
Endpoint.broadcast("device_socket:#{device.id}", "disconnect", %{})

send_resp(conn, 200, "Success")
Expand All @@ -163,7 +162,7 @@ defmodule NervesHubWeb.API.DeviceController do

case Devices.get_by_identifier(identifier) do
{:ok, device} ->
if Accounts.has_org_role?(device.org, user, :write) do
if Accounts.has_org_role?(device.org, user, :manage) do
body
|> String.graphemes()
|> Enum.map(fn character ->
Expand Down Expand Up @@ -192,7 +191,7 @@ defmodule NervesHubWeb.API.DeviceController do

case Devices.get_by_identifier(identifier) do
{:ok, device} ->
if Accounts.has_org_role?(device.org, user, :write) do
if Accounts.has_org_role?(device.org, user, :manage) do
{:ok, firmware} = Firmwares.get_firmware_by_product_and_uuid(device.product, uuid)

{:ok, url} = Firmwares.get_firmware_url(firmware)
Expand Down Expand Up @@ -238,7 +237,7 @@ defmodule NervesHubWeb.API.DeviceController do

case Devices.get_by_identifier(identifier) do
{:ok, device} ->
if Accounts.has_org_role?(device.org, user, :write) do
if Accounts.has_org_role?(device.org, user, :manage) do
case Devices.clear_penalty_box(device, user) do
{:ok, _device} ->
send_resp(conn, 204, "")
Expand Down
5 changes: 2 additions & 3 deletions lib/nerves_hub_web/controllers/api/firmware_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ defmodule NervesHubWeb.API.FirmwareController do

action_fallback(NervesHubWeb.API.FallbackController)

plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :write] when action in [:create])
plug(:validate_role, [org: :read] when action in [:index, :show])
plug(:validate_role, [org: :manage] when action in [:create, :delete])
plug(:validate_role, [org: :view] when action in [:index, :show])

def index(%{assigns: %{product: product}} = conn, _params) do
firmwares = Firmwares.get_firmwares_by_product(product.id)
Expand Down
5 changes: 2 additions & 3 deletions lib/nerves_hub_web/controllers/api/key_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ defmodule NervesHubWeb.API.KeyController do

action_fallback(NervesHubWeb.API.FallbackController)

plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :write] when action in [:create])
plug(:validate_role, [org: :read] when action in [:index, :show])
plug(:validate_role, [org: :manage] when action in [:create, :delete])
plug(:validate_role, [org: :view] when action in [:index, :show])

def index(%{assigns: %{org: org}} = conn, _params) do
keys = Accounts.list_org_keys(org)
Expand Down
6 changes: 2 additions & 4 deletions lib/nerves_hub_web/controllers/api/product_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ defmodule NervesHubWeb.API.ProductController do

action_fallback(NervesHubWeb.API.FallbackController)

plug(:validate_role, [org: :read] when action in [:show])
plug(:validate_role, [org: :write] when action in [:create])
plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :admin] when action in [:update])
plug(:validate_role, [org: :admin] when action in [:create, :delete, :update])
plug(:validate_role, [org: :view] when action in [:show])

def index(%{assigns: %{user: user, org: org}} = conn, _params) do
products = Products.get_products_by_user_and_org(user, org)
Expand Down
9 changes: 4 additions & 5 deletions lib/nerves_hub_web/controllers/archive_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ defmodule NervesHubWeb.ArchiveController do
alias NervesHub.Accounts
alias NervesHub.Archives

plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :write] when action in [:new, :create])
plug(:validate_role, [org: :read] when action in [:index, :show])
plug(:validate_role, [org: :manage] when action in [:new, :create, :delete])
plug(:validate_role, [org: :view] when action in [:index, :show])

def index(conn, _params) do
%{product: product} = conn.assigns
Expand All @@ -21,7 +20,7 @@ defmodule NervesHubWeb.ArchiveController do

case Archives.get(uuid) do
{:ok, archive} ->
if Accounts.has_org_role?(archive.product.org, user, :read) do
if Accounts.has_org_role?(archive.product.org, user, :view) do
conn
|> assign(:archive, archive)
|> render("show.html")
Expand All @@ -45,7 +44,7 @@ defmodule NervesHubWeb.ArchiveController do

case Archives.get(uuid) do
{:ok, archive} ->
if Accounts.has_org_role?(archive.product.org, user, :read) do
if Accounts.has_org_role?(archive.product.org, user, :view) do
redirect(conn, external: Archives.url(archive))
else
conn
Expand Down
9 changes: 6 additions & 3 deletions lib/nerves_hub_web/controllers/deployment_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ defmodule NervesHubWeb.DeploymentController do
alias NervesHub.Devices
alias Ecto.Changeset

plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :write] when action in [:new, :create, :edit, :update, :toggle])
plug(:validate_role, [org: :read] when action in [:index, :show, :export_audit_logs])
plug(
:validate_role,
[org: :manage] when action in [:new, :create, :edit, :update, :delete, :toggle]
)

plug(:validate_role, [org: :view] when action in [:index, :show, :export_audit_logs])

def index(%{assigns: %{org: _org, product: %{id: product_id}}} = conn, _params) do
deployments = Deployments.get_deployments_by_product(product_id)
Expand Down
6 changes: 2 additions & 4 deletions lib/nerves_hub_web/controllers/device_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,14 @@ defmodule NervesHubWeb.DeviceController do
alias NervesHubWeb.DeviceLive
alias NervesHubWeb.Endpoint

plug(:validate_role, [org: :delete] when action in [:delete])

plug(
:validate_role,
[org: :write] when action in [:new, :create, :edit, :reboot, :toggle_updates]
[org: :manage] when action in [:new, :create, :edit, :delete, :reboot, :toggle_updates]
)

plug(
:validate_role,
[org: :read]
[org: :view]
when action in [:index, :console, :show, :download_certificate, :export_audit_logs]
)

Expand Down
5 changes: 2 additions & 3 deletions lib/nerves_hub_web/controllers/firmware_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ defmodule NervesHubWeb.FirmwareController do

action_fallback(NervesHubWeb.FallbackController)

plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :write] when action in [:upload, :do_upload])
plug(:validate_role, [org: :read] when action in [:index, :download])
plug(:validate_role, [org: :manage] when action in [:upload, :do_upload, :delete])
plug(:validate_role, [org: :view] when action in [:index, :download])

def index(%{assigns: %{product: %{id: product_id}}} = conn, _params) do
firmwares = Firmwares.get_firmwares_by_product(product_id)
Expand Down
5 changes: 2 additions & 3 deletions lib/nerves_hub_web/controllers/org_certificate_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ defmodule NervesHubWeb.OrgCertificateController do
alias NervesHub.Devices.CACertificate
alias NervesHub.Devices.CACertificate.CSR

plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :write] when action in [:new, :create])
plug(:validate_role, [org: :read] when action in [:index])
plug(:validate_role, [org: :manage] when action in [:new, :create, :delete])
plug(:validate_role, [org: :view] when action in [:index])

def index(%{assigns: %{org: org}} = conn, _params) do
conn
Expand Down
5 changes: 2 additions & 3 deletions lib/nerves_hub_web/controllers/org_key_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ defmodule NervesHubWeb.OrgKeyController do
alias NervesHub.Accounts
alias NervesHub.Accounts.OrgKey

plug(:validate_role, [org: :read] when action in [:index, :show])
plug(:validate_role, [org: :write] when action in [:new, :create, :update, :edit])
plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :manage] when action in [:new, :create, :update, :edit, :delete])
plug(:validate_role, [org: :view] when action in [:index, :show])

def index(%{assigns: %{org: org}} = conn, _params) do
org_keys = Accounts.list_org_keys(org)
Expand Down
5 changes: 2 additions & 3 deletions lib/nerves_hub_web/controllers/product_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ defmodule NervesHubWeb.ProductController do

action_fallback(NervesHubWeb.FallbackController)

plug(:validate_role, [org: :write] when action in [:new, :create, :update])
plug(:validate_role, [org: :read] when action in [:index])
plug(:validate_role, [org: :delete] when action in [:delete])
plug(:validate_role, [org: :manage] when action in [:new, :create, :update, :delete])
plug(:validate_role, [org: :view] when action in [:index])

def index(%{assigns: %{user: user, org: org}} = conn, _params) do
products = Products.get_products_by_user_and_org(user, org)
Expand Down
2 changes: 1 addition & 1 deletion lib/nerves_hub_web/templates/org/invite.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<span class="tooltip-text">Defines the type of access this user has in this org</span>
</label>
<div class="pos-rel">
<%= select f, :role, NervesHubWeb.OrgUserView.role_options(), selected: :read, class: "form-control" %>
<%= select(f, :role, NervesHubWeb.OrgUserView.role_options(), selected: :view, class: "form-control") %>
<div class="select-icon"></div>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion lib/nerves_hub_web/views/layout_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ defmodule NervesHubWeb.LayoutView do
href: Routes.product_path(conn, :index, conn.assigns.org.name)
}
] ++
if NervesHub.Accounts.has_org_role?(org, user, :read) do
if NervesHub.Accounts.has_org_role?(org, user, :view) do
[
%{
title: "Firmware Keys",
Expand Down
2 changes: 1 addition & 1 deletion lib/nerves_hub_web/views/org_user_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule NervesHubWeb.OrgUserView do

def role_options() do
for {key, value} <- Ecto.Enum.mappings(OrgUser, :role),
key in [:admin, :read],
key in [:admin, :manage, :view],
do: {String.capitalize(value), key}
end
end
18 changes: 18 additions & 0 deletions priv/repo/migrations/20231221105046_switch_role_to_varchar.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
defmodule NervesHub.Repo.Migrations.SwitchRoleToVarchar do
use Ecto.Migration

def change do
execute "ALTER TABLE org_users ALTER COLUMN role TYPE varchar;"
execute "ALTER TABLE product_users ALTER COLUMN role TYPE varchar;"

execute "UPDATE org_users SET role = 'admin' WHERE role = 'delete';"
execute "UPDATE org_users SET role = 'manage' WHERE role = 'write';"
execute "UPDATE org_users SET role = 'view' WHERE role = 'read';"

execute "UPDATE product_users SET role = 'admin' WHERE role = 'delete';"
execute "UPDATE product_users SET role = 'manage' WHERE role = 'write';"
execute "UPDATE product_users SET role = 'view' WHERE role = 'read';"

execute "DROP TYPE role;"
end
end
8 changes: 4 additions & 4 deletions test/nerves_hub/accounts/accounts_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ defmodule NervesHub.AccountsTest do

{:ok, %Invite{} = invite} =
Accounts.add_or_invite_to_org(
%{"email" => "[email protected]", "role" => "read"},
%{"email" => "[email protected]", "role" => "view"},
org
)

Expand All @@ -240,7 +240,7 @@ defmodule NervesHub.AccountsTest do

{:ok, %Invite{} = invite} =
Accounts.add_or_invite_to_org(
%{"email" => "[email protected]", "role" => "read"},
%{"email" => "[email protected]", "role" => "view"},
org
)

Expand All @@ -254,10 +254,10 @@ defmodule NervesHub.AccountsTest do
new_user = Fixtures.user_fixture()

assert {:ok, %OrgUser{}} =
Accounts.add_or_invite_to_org(%{"email" => new_user.email, "role" => "read"}, org)
Accounts.add_or_invite_to_org(%{"email" => new_user.email, "role" => "view"}, org)

{:error, changeset} =
Accounts.add_or_invite_to_org(%{"email" => new_user.email, "role" => "read"}, org)
Accounts.add_or_invite_to_org(%{"email" => new_user.email, "role" => "view"}, org)

assert "is already member" in errors_on(changeset).org_users
end
Expand Down
2 changes: 1 addition & 1 deletion test/nerves_hub/accounts/remove_account_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ defmodule NervesHub.Accounts.RemoveAccountTest do
org2 = Fixtures.org_fixture(user, %{name: "Test-Org2"})

{:ok, invite} =
Accounts.add_or_invite_to_org(%{"email" => "[email protected]", "role" => "read"}, org2)
Accounts.add_or_invite_to_org(%{"email" => "[email protected]", "role" => "view"}, org2)

params = %{username: "Test-User2", password: "Test-Password"}
{:ok, org_user} = Accounts.create_user_from_invite(invite, org2, params)
Expand Down
2 changes: 1 addition & 1 deletion test/nerves_hub/products/products_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ defmodule NervesHub.ProductsTest do
product: product
} do
user = Fixtures.user_fixture()
Accounts.add_org_user(org, user, %{role: :read})
Accounts.add_org_user(org, user, %{role: :view})
assert [^product] = Products.get_products_by_user_and_org(user, org)
end

Expand Down
Loading

0 comments on commit ff90726

Please sign in to comment.