Skip to content

Commit b6a09b0

Browse files
authored
Relax "Scan all packages" availability to "change_product" users (#421)
Signed-off-by: tdruez <[email protected]>
1 parent 0b2311d commit b6a09b0

File tree

3 files changed

+47
-13
lines changed

3 files changed

+47
-13
lines changed

CHANGELOG.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ Release notes
99
Inactive is_active=False products are excluded.
1010
https://github.com/aboutcode-org/dejacode/issues/388
1111

12+
- Allow Product "Scan all packages" for users with the "change_product" permission
13+
on the Product instance.
14+
Prior to this change only "superusers" could see and use this feature.
15+
https://github.com/aboutcode-org/dejacode/issues/385
16+
1217
### Version 5.4.2
1318

1419
- Migrate the LDAP testing from using mockldap to slapdtest.

product_portfolio/tests/test_views.py

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,33 @@ def test_product_portfolio_detail_edit_productcomponent_permissions(self):
10921092
response = self.client.get(url)
10931093
self.assertContains(response, delete_button)
10941094

1095+
@mock.patch("dejacode_toolkit.scancodeio.ScanCodeIO.is_configured")
1096+
def test_product_portfolio_detail_view_has_scan_all_packages(self, mock_is_configured):
1097+
mock_is_configured.return_value = True
1098+
1099+
self.client.login(username=self.basic_user.username, password="secret")
1100+
self.assertFalse(self.basic_user.dataspace.enable_package_scanning)
1101+
1102+
url = self.product1.get_absolute_url()
1103+
response = self.client.get(url)
1104+
self.assertEqual(404, response.status_code)
1105+
1106+
assign_perm("view_product", self.basic_user, self.product1)
1107+
response = self.client.get(url)
1108+
self.assertEqual(200, response.status_code)
1109+
self.assertFalse(response.context.get("has_scan_all_packages"))
1110+
1111+
self.basic_user.dataspace.enable_package_scanning = True
1112+
self.basic_user.dataspace.save()
1113+
response = self.client.get(url)
1114+
self.assertEqual(200, response.status_code)
1115+
self.assertFalse(response.context.get("has_scan_all_packages"))
1116+
1117+
assign_perm("change_product", self.basic_user, self.product1)
1118+
response = self.client.get(url)
1119+
self.assertEqual(200, response.status_code)
1120+
self.assertTrue(response.context.get("has_scan_all_packages"))
1121+
10951122
def test_product_portfolio_detail_view_display_purldb_features(self):
10961123
self.client.login(username=self.super_user.username, password="secret")
10971124
self.assertFalse(self.super_user.dataspace.enable_purldb_access)
@@ -1251,10 +1278,10 @@ def test_product_portfolio_details_view_admin_links(self, mock_is_configured):
12511278

12521279
manage_components_url = self.product1.get_manage_components_url()
12531280
manage_packages_url = self.product1.get_manage_packages_url()
1254-
expected1 = "Scan all Packages"
1281+
expected_scan_all = "Scan all Packages"
12551282

12561283
response = self.client.get(url)
1257-
self.assertContains(response, expected1, html=True)
1284+
self.assertContains(response, expected_scan_all, html=True)
12581285
self.assertContains(response, manage_components_url)
12591286
self.assertContains(response, manage_packages_url)
12601287

@@ -1271,33 +1298,33 @@ def test_product_portfolio_details_view_admin_links(self, mock_is_configured):
12711298

12721299
assign_perm("view_product", self.super_user, self.product1)
12731300
response = self.client.get(url)
1274-
self.assertNotContains(response, expected1, html=True)
1301+
self.assertNotContains(response, expected_scan_all, html=True)
12751302
self.assertNotContains(response, manage_components_url)
12761303
self.assertNotContains(response, manage_packages_url)
12771304

12781305
perms = ["change_productcomponent"]
12791306
self.super_user = add_perms(self.super_user, perms)
12801307
response = self.client.get(url)
1281-
self.assertNotContains(response, expected1, html=True)
1308+
self.assertNotContains(response, expected_scan_all, html=True)
12821309
self.assertNotContains(response, manage_components_url)
12831310
self.assertNotContains(response, manage_packages_url)
12841311

12851312
assign_perm("change_product", self.super_user, self.product1)
12861313
response = self.client.get(url)
1287-
self.assertNotContains(response, expected1, html=True)
1314+
self.assertContains(response, expected_scan_all, html=True)
12881315
self.assertContains(response, manage_components_url)
12891316
self.assertNotContains(response, manage_packages_url)
12901317

12911318
self.super_user = add_perms(self.super_user, ["change_productpackage"])
12921319
response = self.client.get(url)
1293-
self.assertNotContains(response, expected1, html=True)
1320+
self.assertContains(response, expected_scan_all, html=True)
12941321
self.assertContains(response, manage_components_url)
12951322
self.assertContains(response, manage_packages_url)
12961323

12971324
self.super_user.is_superuser = True
12981325
self.super_user.save()
12991326
response = self.client.get(url)
1300-
self.assertContains(response, expected1, html=True)
1327+
self.assertContains(response, expected_scan_all, html=True)
13011328

13021329
def test_product_portfolio_list_view_request_links(self):
13031330
self.client.login(username="nexb_user", password="secret")
@@ -1734,11 +1761,15 @@ def test_product_scan_all_packages_view(self, mock_is_configured, mock_scancodei
17341761
dataspace_uuid=self.super_user.dataspace.uuid,
17351762
)
17361763

1737-
self.super_user.is_superuser = False
1738-
self.super_user.save()
1764+
self.client.login(username=self.basic_user.username, password="secret")
17391765
response = self.client.get(scan_all_packages_url)
17401766
self.assertEqual(404, response.status_code)
17411767

1768+
assign_perm("view_product", self.basic_user, self.product1)
1769+
assign_perm("change_product", self.basic_user, self.product1)
1770+
response = self.client.get(scan_all_packages_url)
1771+
self.assertRedirects(response, self.product1.get_absolute_url())
1772+
17421773
def test_product_portfolio_product_add_view_permission_access(self):
17431774
add_url = reverse("product_portfolio:product_add")
17441775
response = self.client.get(add_url)

product_portfolio/views.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -704,9 +704,9 @@ def get_context_data(self, **kwargs):
704704
include_scancodeio_features = all(
705705
[
706706
scancodeio.is_configured(),
707-
user.is_superuser,
708707
dataspace.enable_package_scanning,
709708
context["is_user_dataspace"],
709+
context["has_change_permission"],
710710
]
711711
)
712712
context["has_scan_all_packages"] = include_scancodeio_features
@@ -1964,17 +1964,15 @@ def scan_all_packages_view(request, dataspace, name, version=""):
19641964
scancodeio = ScanCodeIO(user_dataspace)
19651965
conditions = [
19661966
scancodeio.is_configured(),
1967-
user.is_superuser,
19681967
user_dataspace.enable_package_scanning,
19691968
user_dataspace.name == dataspace,
19701969
]
19711970

19721971
if not all(conditions):
19731972
raise Http404
19741973

1975-
guarded_qs = Product.objects.get_queryset(user)
1974+
guarded_qs = Product.objects.get_queryset(user, perms="change_product")
19761975
product = get_object_or_404(guarded_qs, name=unquote_plus(name), version=unquote_plus(version))
1977-
19781976
if not product.all_packages:
19791977
raise Http404("No packages available for this product.")
19801978

0 commit comments

Comments
 (0)