Skip to content

Commit df11439

Browse files
committed
feat(asset_categories): scope to authority
1 parent 47bbffe commit df11439

3 files changed

Lines changed: 62 additions & 3 deletions

File tree

shard.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,15 @@ shards:
215215

216216
placeos-frontend-loader:
217217
git: https://github.com/placeos/frontend-loader.git
218-
version: 2.7.1+git.commit.ada234ef40f9c59b10c4427d85204d1fa571f342
218+
version: 2.7.1+git.commit.10d4c9de65ee4f9b41c3168fd4c089fc3b11ba9d
219219

220220
placeos-log-backend:
221221
git: https://github.com/place-labs/log-backend.git
222222
version: 0.13.0
223223

224224
placeos-models:
225225
git: https://github.com/placeos/models.git
226-
version: 9.100.0
226+
version: 9.100.1
227227

228228
placeos-resource:
229229
git: https://github.com/place-labs/resource.git
@@ -275,7 +275,7 @@ shards:
275275

276276
search-ingest:
277277
git: https://github.com/placeos/search-ingest.git
278-
version: 2.11.3+git.commit.fd285c0ea5a86ddde4132b0f06a068489e59a8ff
278+
version: 2.11.3+git.commit.6f2d42f8d93ce280ba4160112476862e4be5b1c0
279279

280280
secrets-env: # Overridden
281281
git: https://github.com/spider-gazelle/secrets-env.git

spec/controllers/asset_categories_spec.cr

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,55 @@ module PlaceOS::Api
2424
end
2525
end
2626

27+
describe "authority ownership" do
28+
it "sets the authority_id from the current authority on create" do
29+
body = Model::Generator.asset_category.to_json
30+
result = client.post(
31+
AssetCategories.base_route,
32+
body: body,
33+
headers: Spec::Authentication.headers(sys_admin: true, support: false),
34+
)
35+
result.status_code.should eq 201
36+
37+
created = Model::AssetCategory.from_trusted_json(result.body)
38+
authority = Model::Authority.find_by_domain("localhost").not_nil!
39+
created.authority_id.should eq authority.id
40+
created.destroy
41+
end
42+
43+
it "rejects updates to a category owned by another authority" do
44+
other_authority = Model::Generator.authority(domain: "https://other-asset-cat.example.com").save!
45+
asset_category = Model::Generator.asset_category(other_authority).save!
46+
47+
result = client.patch(
48+
path: "#{AssetCategories.base_route}#{asset_category.id}",
49+
body: {name: "renamed-#{random_name}"}.to_json,
50+
headers: Spec::Authentication.headers(sys_admin: true, support: false),
51+
)
52+
result.status_code.should eq 403
53+
54+
asset_category.destroy
55+
other_authority.destroy
56+
end
57+
58+
it "adopts a legacy category with no authority on update" do
59+
asset_category = Model::Generator.asset_category.save!
60+
# simulate a legacy record predating the authority_id column
61+
asset_category.update_fields(authority_id: nil)
62+
63+
result = client.patch(
64+
path: "#{AssetCategories.base_route}#{asset_category.id}",
65+
body: {name: "renamed-#{random_name}"}.to_json,
66+
headers: Spec::Authentication.headers(sys_admin: true, support: false),
67+
)
68+
result.success?.should be_true
69+
70+
authority = Model::Authority.find_by_domain("localhost").not_nil!
71+
Model::AssetCategory.find!(asset_category.id).authority_id.should eq authority.id
72+
asset_category.destroy
73+
end
74+
end
75+
2776
describe "scopes" do
2877
Spec.test_controller_scope(AssetCategories)
2978
end

src/placeos-rest-api/controllers/asset_categories.cr

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,24 @@ module PlaceOS::Api
7272
@[AC::Route::PUT("/:id", body: :asset_category)]
7373
def update(asset_category : ::PlaceOS::Model::AssetCategory) : ::PlaceOS::Model::AssetCategory
7474
current = current_asset_category
75+
authority_id = current_authority.as(::PlaceOS::Model::Authority).id
76+
77+
# A category that already belongs to another authority may not be edited.
78+
# Legacy records with no authority get adopted by the current authority.
79+
if (existing = current.authority_id) && existing != authority_id
80+
raise Error::Forbidden.new("asset category belongs to another authority")
81+
end
82+
7583
current.assign_attributes(asset_category)
84+
current.authority_id = authority_id
7685
raise Error::ModelValidation.new(current.errors) unless current.save
7786
current
7887
end
7988

8089
# add new asset category
8190
@[AC::Route::POST("/", body: :asset_category, status_code: HTTP::Status::CREATED)]
8291
def create(asset_category : ::PlaceOS::Model::AssetCategory) : ::PlaceOS::Model::AssetCategory
92+
asset_category.authority_id = current_authority.as(::PlaceOS::Model::Authority).id
8393
raise Error::ModelValidation.new(asset_category.errors) unless asset_category.save
8494
asset_category
8595
end

0 commit comments

Comments
 (0)