Skip to content

Commit

Permalink
Merge pull request #371 from balena-io/avoid-deletion-with-incomplete…
Browse files Browse the repository at this point in the history
…-ids

do not operate on empty or ambiguous device and release UUIDs
  • Loading branch information
otaviojacobi authored Oct 15, 2024
2 parents d8fbe7e + 6d5d043 commit 46cb77a
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 1 deletion.
17 changes: 16 additions & 1 deletion balena/models/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,19 @@ def __set(
}
)
else:
if len(uuid_or_id_or_ids) < 6:
raise exceptions.InvalidParameter("UUID must have at least 6 characeters", None)

affected = self.__pine.get({
"resource": "device",
"options": {
"$top": 2,
"$select": "id",
"$filter": {"uuid": {"$startswith": uuid_or_id_or_ids}}}
})
if len(affected) > 1:
raise exceptions.AmbiguousDevice(uuid_or_id_or_ids)

fn(
{
"resource": "device",
Expand Down Expand Up @@ -359,6 +372,9 @@ def get(self, uuid_or_id: Union[str, int], options: AnyObject = {}) -> TypeDevic
if uuid_or_id is None:
raise exceptions.DeviceNotFound(uuid_or_id)

if uuid_or_id == '':
raise exceptions.InvalidParameter("UUID can not be empty", None)

is_potentially_full_uuid = is_full_uuid(uuid_or_id)
if is_potentially_full_uuid or is_id(uuid_or_id):
device = self.__pine.get(
Expand Down Expand Up @@ -576,7 +592,6 @@ def remove(self, uuid_or_id_or_ids: Union[str, int, List[int]]):
Args:
uuid_or_id_or_ids (Union[str, int, List[int]]): device uuid (str) or id (int) or ids (List[int])
"""

self.__set(uuid_or_id_or_ids, body=None, fn=self.__pine.delete)

def deactivate(self, uuid_or_id_or_ids: Union[str, int, List[int]]) -> None:
Expand Down
3 changes: 3 additions & 0 deletions balena/models/release.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ def get(
if commit_or_id_or_raw_version is None:
raise exceptions.ReleaseNotFound(commit_or_id_or_raw_version)

if commit_or_id_or_raw_version == '':
raise exceptions.InvalidParameter("commit_or_id_or_raw_version", None)

if is_id(commit_or_id_or_raw_version):
release = self.__pine.get(
{"resource": "release", "id": commit_or_id_or_raw_version, "options": options} # type: ignore
Expand Down
33 changes: 33 additions & 0 deletions tests/functional/models/test_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ def test_07_get(self):
with self.assertRaises(self.helper.balena_exceptions.DeviceNotFound):
self.balena.models.device.get("999999999999")

with self.assertRaises(self.helper.balena_exceptions.InvalidParameter):
self.balena.models.device.get("")

def test_08_rename(self):
self.balena.models.device.rename(TestDevice.device["uuid"], "test-device")
self.assertEqual(self.balena.models.device.get_name(TestDevice.device["uuid"]), "test-device")
Expand Down Expand Up @@ -369,9 +372,39 @@ def test_30_remove(self):
app_devices_len - 1,
)

uuid = self.balena.models.device.generate_uuid()
self.balena.models.device.register(self.app["id"], uuid)
uuid2 = uuid[:-2] + uuid[-1] + uuid[-2]

self.balena.models.device.register(self.app["id"], uuid2)

device_uuids = [device["uuid"] for device in self.balena.models.device.get_all()]
self.assertIn(uuid, device_uuids)
self.assertIn(uuid2, device_uuids)

with self.assertRaises(self.helper.balena_exceptions.DeviceNotFound):
self.balena.models.device.get(TestDevice.device["uuid"])

with self.assertRaises(self.helper.balena_exceptions.InvalidParameter):
self.balena.models.device.remove("")

with self.assertRaises(self.helper.balena_exceptions.InvalidParameter):
self.balena.models.device.remove("abc")

with self.assertRaises(self.helper.balena_exceptions.AmbiguousDevice):
self.balena.models.device.remove(uuid[0:10])

device_uuids = [device["uuid"] for device in self.balena.models.device.get_all()]
self.assertIn(uuid, device_uuids)
self.assertIn(uuid2, device_uuids)

self.balena.models.device.remove(uuid)
self.balena.models.device.remove(uuid2)

device_uuids = [device["uuid"] for device in self.balena.models.device.get_all()]
self.assertNotIn(uuid, device_uuids)
self.assertNotIn(uuid2, device_uuids)


if __name__ == "__main__":
unittest.main()
3 changes: 3 additions & 0 deletions tests/functional/models/test_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ def test_06_get_release_by_resources(self):
) # type: ignore
self.__expect_release_to_match_on_get(release, match)

with self.assertRaises(self.helper.balena_exceptions.InvalidParameter):
self.balena.models.release.get("")

def test_07_get_all_by_application(self):
app_id = self.mc_app["app"]["id"]
releases = self.balena.models.release.get_all_by_application(app_id)
Expand Down

0 comments on commit 46cb77a

Please sign in to comment.