Skip to content

Commit c450e33

Browse files
authored
Track who created or edited script (#1838)
Adds `:created_by` and `:last_updated_by` to `Script` schema.
1 parent 0ac464f commit c450e33

File tree

8 files changed

+117
-18
lines changed

8 files changed

+117
-18
lines changed

lib/nerves_hub/accounts/remove_account.ex

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ defmodule NervesHub.Accounts.RemoveAccount do
1919
alias NervesHub.Firmwares.FirmwareDelta
2020
alias NervesHub.Firmwares.FirmwareTransfer
2121
alias NervesHub.Products.Product
22+
alias NervesHub.Scripts.Script
2223

2324
alias NervesHub.Repo
2425

@@ -40,6 +41,8 @@ defmodule NervesHub.Accounts.RemoveAccount do
4041
|> Multi.update_all(:soft_delete_devices, &soft_delete_by_org_id(Device, &1), [])
4142
|> Multi.update_all(:soft_delete_org_users, &soft_delete_by_org_id(OrgUser, &1), [])
4243
|> Multi.update_all(:soft_delete_orgs, &soft_delete_orgs(&1), [])
44+
|> Multi.update_all(:nilify_script_creations, &nilify_script_creations(&1), [])
45+
|> Multi.update_all(:nilify_script_edits, &nilify_script_edits(&1), [])
4346
|> Multi.update(:soft_delete_user, &soft_delete_user/1)
4447
|> Repo.transaction()
4548
end
@@ -109,6 +112,18 @@ defmodule NervesHub.Accounts.RemoveAccount do
109112
|> update(set: [deleted_at: ^truncated_utc_now()])
110113
end
111114

115+
defp nilify_script_creations(%{user_id: user_id}) do
116+
Script
117+
|> where(created_by_id: ^user_id)
118+
|> update(set: [created_by_id: nil])
119+
end
120+
121+
defp nilify_script_edits(%{user_id: user_id}) do
122+
Script
123+
|> where(last_updated_by_id: ^user_id)
124+
|> update(set: [last_updated_by_id: nil])
125+
end
126+
112127
defp query_by_org_id(queryable, %{org_ids: ids}) do
113128
query_by_org_id(queryable, ids)
114129
end

lib/nerves_hub/scripts.ex

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,24 +57,23 @@ defmodule NervesHub.Scripts do
5757

5858
@spec create(Product.t(), User.t(), map()) :: {:ok, Script.t()} | {:error, Changeset.t()}
5959
def create(product, user, params) do
60-
product
61-
|> Ecto.build_assoc(:scripts)
62-
|> Script.changeset(params)
60+
%Script{}
61+
|> Script.create_changeset(product, user, params)
6362
|> Repo.insert()
6463
|> case do
6564
{:ok, script} ->
6665
ProductTemplates.audit_script_created(user, product, script)
6766
{:ok, script}
6867

69-
err ->
70-
err
68+
{:error, changeset} ->
69+
{:error, changeset}
7170
end
7271
end
7372

7473
@spec update(Script.t(), User.t(), map()) :: {:ok, Script.t()} | {:error, Changeset.t()}
7574
def update(script, user, params) do
7675
script
77-
|> Script.changeset(params)
76+
|> Script.update_changeset(user, params)
7877
|> Repo.update()
7978
|> case do
8079
{:ok, script} ->
@@ -84,8 +83,8 @@ defmodule NervesHub.Scripts do
8483

8584
{:ok, script}
8685

87-
err ->
88-
err
86+
{:error, changeset} ->
87+
{:error, changeset}
8988
end
9089
end
9190
end

lib/nerves_hub/scripts/script.ex

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,39 @@ defmodule NervesHub.Scripts.Script do
33

44
import Ecto.Changeset
55

6+
alias NervesHub.Accounts.User
67
alias NervesHub.Products.Product
78

89
@type t :: %__MODULE__{}
10+
@required [:name, :text]
911

1012
schema "scripts" do
1113
belongs_to(:product, Product)
14+
belongs_to(:created_by, User, where: [deleted_at: nil])
15+
belongs_to(:last_updated_by, User, where: [deleted_at: nil])
1216

1317
field(:name, :string)
1418
field(:text, :string)
1519

1620
timestamps()
1721
end
1822

19-
def changeset(struct, params) do
23+
def create_changeset(%__MODULE__{} = struct, product, created_by, params) do
2024
struct
21-
|> cast(params, [:name, :text])
22-
|> validate_required([:name, :text])
25+
|> cast(params, @required)
26+
|> put_assoc(:product, product)
27+
|> put_assoc(:created_by, created_by)
28+
|> validate_required(@required ++ [:created_by])
2329
|> validate_length(:name, lte: 255)
30+
|> foreign_key_constraint(:created_by_id)
31+
end
32+
33+
def update_changeset(%__MODULE__{} = struct, edited_by, params \\ %{}) do
34+
struct
35+
|> cast(params, @required)
36+
|> put_change(:last_updated_by_id, edited_by.id)
37+
|> validate_required(@required)
38+
|> validate_length(:name, lte: 255)
39+
|> foreign_key_constraint(:last_updated_by_id)
2440
end
2541
end

lib/nerves_hub_web/live/support_scripts/edit.ex

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@ defmodule NervesHubWeb.Live.SupportScripts.Edit do
22
use NervesHubWeb, :updated_live_view
33

44
alias NervesHub.Scripts
5-
alias NervesHub.Scripts.Script
65

76
@impl Phoenix.LiveView
87
def mount(
98
%{"script_id" => script_id},
109
_session,
11-
%{assigns: %{product: product}} = socket
10+
%{assigns: %{org: org, product: product}} = socket
1211
) do
1312
script = Scripts.get_by_product_and_id!(product, script_id)
1413

1514
socket
16-
|> page_title("Edit Support Script - #{socket.assigns.org.name}")
15+
|> page_title("Edit Support Script - #{org.name}")
1716
|> sidebar_tab(:support_scripts)
18-
|> assign(:form, to_form(Script.changeset(script, %{})))
17+
|> assign(:form, to_form(Ecto.Changeset.change(script)))
1918
|> assign(:script, script)
2019
|> ok()
2120
end

lib/nerves_hub_web/live/support_scripts/new.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ defmodule NervesHubWeb.Live.SupportScripts.New do
99
socket
1010
|> page_title("New Support Script - #{socket.assigns.org.name}")
1111
|> sidebar_tab(:support_scripts)
12-
|> assign(:form, to_form(Script.changeset(%Script{}, %{})))
12+
|> assign(:form, to_form(Ecto.Changeset.change(%Script{})))
1313
|> ok()
1414
end
1515

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
defmodule NervesHub.Repo.Migrations.AddCreatedAndLastUpdatedByToScript do
2+
use Ecto.Migration
3+
4+
def change do
5+
alter table(:scripts) do
6+
add(:created_by_id, references(:users))
7+
add(:last_updated_by_id, references(:users))
8+
end
9+
end
10+
end

test/nerves_hub/scripts_test.exs

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
defmodule NervesHub.ScriptsTest do
2+
alias NervesHub.Accounts
23
use NervesHub.DataCase
34

45
alias NervesHub.Fixtures
56
alias NervesHub.Scripts
67

78
setup do
89
user = Fixtures.user_fixture()
10+
user2 = Fixtures.user_fixture()
911
org = Fixtures.org_fixture(user)
1012
product = Fixtures.product_fixture(user, org)
1113

12-
%{user: user, org: org, product: product}
14+
%{user: user, user2: user2, org: org, product: product}
1315
end
1416

1517
describe "creating a script" do
@@ -21,6 +23,63 @@ defmodule NervesHub.ScriptsTest do
2123
})
2224

2325
assert script.product_id == product.id
26+
assert script.created_by_id == user.id
27+
end
28+
end
29+
30+
describe "updating a script" do
31+
test "successful update", %{product: product, user: user} do
32+
{:ok, script} =
33+
Scripts.create(product, user, %{
34+
name: "MOTD",
35+
text: "NervesMOTD.print()"
36+
})
37+
38+
{:ok, script} =
39+
Scripts.update(script, user, %{name: "New Name"})
40+
41+
assert script.name == "New Name"
42+
assert script.last_updated_by_id == user.id
43+
end
44+
45+
test "other user updates script", %{
46+
product: product,
47+
user: user,
48+
user2: user2
49+
} do
50+
{:ok, script} =
51+
Scripts.create(product, user, %{
52+
name: "MOTD",
53+
text: "NervesMOTD.print()"
54+
})
55+
56+
{:ok, script} =
57+
Scripts.update(script, user, %{name: "New Name"})
58+
59+
{:ok, script} =
60+
Scripts.update(script, user2, %{text: "New text"})
61+
62+
assert script.text == "New text"
63+
assert script.last_updated_by_id == user2.id
64+
end
65+
end
66+
67+
describe "user removal" do
68+
test "user is removed - editor fields are nilified", %{product: product, user: user} do
69+
{:ok, script} =
70+
Scripts.create(product, user, %{
71+
name: "MOTD",
72+
text: "NervesMOTD.print()"
73+
})
74+
75+
{:ok, _script} =
76+
Scripts.update(script, user, %{name: "New Name"})
77+
78+
Accounts.remove_account(user.id)
79+
80+
script = Scripts.get!(script.id)
81+
assert script.created_by_id == nil
82+
assert script.last_updated_by_id == nil
2483
end
2584
end
2685
end

test/nerves_hub_web/live/support_scripts_test.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ defmodule NervesHubWeb.Live.SupportScriptsTest do
6565

6666
describe "edit" do
6767
test "requires a name and text", %{conn: conn, org: org, product: product, user: user} do
68-
{:ok, script} = Scripts.create(product, user, %{name: "MOTD", text: "NervesMOTD.print()"})
68+
{:ok, script} =
69+
Scripts.create(product, user, %{name: "MOTD", text: "NervesMOTD.print()"})
6970

7071
conn
7172
|> visit("/org/#{org.name}/#{product.name}/scripts/#{script.id}/edit")

0 commit comments

Comments
 (0)