Skip to content

Commit d15507e

Browse files
joshkclaude
andcommitted
Report a signing key still used by an archive
`OrgKey.delete_changeset/2` declared the firmware foreign key and said so readably, but archives are signed with the same keys and were missing. Deleting a key used only by an archive raised instead of returning the error the page shows. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1 parent b2bbd82 commit d15507e

2 files changed

Lines changed: 35 additions & 0 deletions

File tree

lib/nerves_hub/accounts/org_key.ex

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,13 @@ defmodule NervesHub.Accounts.OrgKey do
6666
name: :firmwares_tenant_key_id_fkey,
6767
message: "Firmware exists which uses the Signing Key"
6868
)
69+
# Archives are signed with the same keys as firmware, and were missing here:
70+
# a key used only by an archive raised a bare foreign key violation instead
71+
# of coming back as an error the page could show.
72+
|> foreign_key_constraint(:archives,
73+
name: :archives_org_key_id_fkey,
74+
message: "Archives exist which use the Signing Key"
75+
)
6976
end
7077

7178
@doc """

test/nerves_hub/accounts/org_key_test.exs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
defmodule NervesHub.Accounts.OrgKeyTest do
22
use NervesHub.DataCase, async: true
33

4+
alias NervesHub.Accounts
45
alias NervesHub.Accounts.OrgKey
6+
alias NervesHub.Fixtures
57
alias NervesHub.Support.EspIdf
68
alias NervesHub.Support.Fwup
79

@@ -164,5 +166,31 @@ defmodule NervesHub.Accounts.OrgKeyTest do
164166

165167
assert changeset.data == org_key
166168
end
169+
170+
@tag :tmp_dir
171+
test "refuses a key that firmware uses", %{tmp_dir: tmp_dir} do
172+
user = Fixtures.user_fixture()
173+
org = Fixtures.org_fixture(user)
174+
product = Fixtures.product_fixture(user, org)
175+
org_key = Fixtures.org_key_fixture(org, user, tmp_dir)
176+
_firmware = Fixtures.firmware_fixture(org_key, product, %{dir: tmp_dir})
177+
178+
assert {:error, changeset} = Accounts.delete_org_key(org_key)
179+
assert "Firmware exists which uses the Signing Key" in errors_on(changeset).firmwares
180+
end
181+
182+
@tag :tmp_dir
183+
test "refuses a key that an archive uses", %{tmp_dir: tmp_dir} do
184+
user = Fixtures.user_fixture()
185+
org = Fixtures.org_fixture(user)
186+
product = Fixtures.product_fixture(user, org)
187+
org_key = Fixtures.org_key_fixture(org, user, tmp_dir)
188+
_archive = Fixtures.archive_fixture(org_key, product, %{dir: tmp_dir})
189+
190+
# Archives are signed with the same keys as firmware, and used to raise
191+
# here rather than coming back as an error.
192+
assert {:error, changeset} = Accounts.delete_org_key(org_key)
193+
assert "Archives exist which use the Signing Key" in errors_on(changeset).archives
194+
end
167195
end
168196
end

0 commit comments

Comments
 (0)