Add Content View patches for cross-domain search testing - #1374
Conversation
Wires the new pulpcore ContentView resource (patch 0062) and pulp_rpm's
six nested RPM search endpoints built on it (patch 0063) into the
Dockerfile so they can be exercised against pulp-service's pinned
pulpcore/pulp_rpm versions. Also adds a DomainOrgAuthenticationBackend so
that user.has_perm("core.view_domain", obj=domain) checks -- used by
ContentView's cross-domain distribution resolution -- reflect DomainOrg
membership for domains outside of the current request's scope, which
pulp-service's request-scoped DomainBasedPermission alone can't answer.
Verified end-to-end in the ghcr.io/pulp/hosted-pulp-dev-env:main dev
container via pulp-add-patch/pulp-restart: CRUD, all 6 search endpoints
aggregating real RPM content synced across two domains, and RBAC
exclusion of a domain a limited user lacks DomainOrg access to.
Co-authored-by: Cursor <cursoragent@cursor.com>
Reviewer's GuideAdds support for pulpcore’s new ContentView resource and pulp_rpm’s nested cross-domain RPM search endpoints to the dev/Docker environment, and introduces a DomainOrgAuthenticationBackend so ContentView’s cross-domain domain permission checks honor DomainOrg membership outside the current request scope. Sequence diagram for ContentView cross-domain core.view_domain checks via DomainOrgAuthenticationBackendsequenceDiagram
actor DjangoUser
participant ContentView
participant DomainOrgAuthenticationBackend
participant Domain
participant DomainOrg
ContentView->>DjangoUser: has_perm(core.view_domain, domain)
DjangoUser->>DomainOrgAuthenticationBackend: has_perm(user_obj, perm, obj)
DomainOrgAuthenticationBackend->>DomainOrgAuthenticationBackend: [perm != core.view_domain or obj not Domain]
DomainOrgAuthenticationBackend-->>DjangoUser: False
opt [perm == core.view_domain and obj is Domain and user_obj.is_authenticated]
DomainOrgAuthenticationBackend->>DomainOrg: objects.filter(domains__pk=obj.pk, user=user_obj)
DomainOrgAuthenticationBackend->>DomainOrgAuthenticationBackend: group_pks = user_obj.groups.values_list(pk)
DomainOrgAuthenticationBackend->>DomainOrg: objects.filter(domains__pk=obj.pk, group_id__in=group_pks)
DomainOrg->>DomainOrgAuthenticationBackend: exists()
DomainOrgAuthenticationBackend-->>DjangoUser: True/False
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- In
DomainOrgAuthenticationBackend.has_perm, consider short-circuiting for superusers (e.g.user_obj.is_superuser) so global admins are not constrained byDomainOrgassociations when resolvingcore.view_domain. - The strict
isinstance(obj, Domain)check inDomainOrgAuthenticationBackend.has_permmay block permission evaluation for proxy or subclassedDomainmodels; if those are possible, loosening this check (e.g. by type attribute or usingDomain._meta.concrete_model) would make the backend more robust.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `DomainOrgAuthenticationBackend.has_perm`, consider short-circuiting for superusers (e.g. `user_obj.is_superuser`) so global admins are not constrained by `DomainOrg` associations when resolving `core.view_domain`.
- The strict `isinstance(obj, Domain)` check in `DomainOrgAuthenticationBackend.has_perm` may block permission evaluation for proxy or subclassed `Domain` models; if those are possible, loosening this check (e.g. by type attribute or using `Domain._meta.concrete_model`) would make the backend more robust.
## Individual Comments
### Comment 1
<location path="pulp_service/pulp_service/tests/unit/test_domain_org_authentication_backend.py" line_range="68-75" />
<code_context>
+
+ assert backend.has_perm(None, "core.view_domain", obj=domain) is False
+
+ @patch("pulp_service.app.authorization.DomainOrg.objects")
+ def test_direct_user_association_grants(self, mock_domain_org):
+ mock_domain_org.filter.return_value.exists.return_value = True
+ backend = DomainOrgAuthenticationBackend()
+ user = _make_authenticated_user()
+ domain = _make_domain()
+
+ assert backend.has_perm(user, "core.view_domain", obj=domain) is True
+ mock_domain_org.filter.assert_called_once()
+
</code_context>
<issue_to_address>
**suggestion (testing):** Strengthen assertions to verify the ORM filter is constructed with the expected user/domain constraints
Currently this only checks that `DomainOrg.objects.filter` is called once. To better verify the permission logic, assert the exact arguments passed to `filter` (e.g., includes the domain PK and `user`, and omits `group_id__in` when `group_pks` is empty). This will ensure future changes don’t alter these constraints while still calling `filter`.
Suggested implementation:
```python
assert backend.has_perm(user, "core.view_domain", obj=domain) is True
mock_domain_org.filter.assert_called_once()
args, kwargs = mock_domain_org.filter.call_args
# No positional args should be used in the filter call
assert args == ()
# Ensure the filter is constrained by the domain and user
assert kwargs.get("domain_id") == domain.pk
assert kwargs.get("user") == user
# When there are no groups, group-based constraints should not be added
assert "group_id__in" not in kwargs
```
If the actual implementation of `DomainOrgAuthenticationBackend` uses different keyword names (e.g. `domain` instead of `domain_id`, or `user_id` instead of `user`), adjust the `kwargs.get(...)` keys accordingly so they match the real ORM filter signature while keeping the assertion that `group_id__in` is absent.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| @patch("pulp_service.app.authorization.DomainOrg.objects") | ||
| def test_direct_user_association_grants(self, mock_domain_org): | ||
| mock_domain_org.filter.return_value.exists.return_value = True | ||
| backend = DomainOrgAuthenticationBackend() | ||
| user = _make_authenticated_user() | ||
| domain = _make_domain() | ||
|
|
||
| assert backend.has_perm(user, "core.view_domain", obj=domain) is True |
There was a problem hiding this comment.
suggestion (testing): Strengthen assertions to verify the ORM filter is constructed with the expected user/domain constraints
Currently this only checks that DomainOrg.objects.filter is called once. To better verify the permission logic, assert the exact arguments passed to filter (e.g., includes the domain PK and user, and omits group_id__in when group_pks is empty). This will ensure future changes don’t alter these constraints while still calling filter.
Suggested implementation:
assert backend.has_perm(user, "core.view_domain", obj=domain) is True
mock_domain_org.filter.assert_called_once()
args, kwargs = mock_domain_org.filter.call_args
# No positional args should be used in the filter call
assert args == ()
# Ensure the filter is constrained by the domain and user
assert kwargs.get("domain_id") == domain.pk
assert kwargs.get("user") == user
# When there are no groups, group-based constraints should not be added
assert "group_id__in" not in kwargsIf the actual implementation of DomainOrgAuthenticationBackend uses different keyword names (e.g. domain instead of domain_id, or user_id instead of user), adjust the kwargs.get(...) keys accordingly so they match the real ORM filter signature while keeping the assertion that group_id__in is absent.
|
/retest |
Wires the new pulpcore ContentView resource (patch 0062) and pulp_rpm's six nested RPM search endpoints built on it (patch 0063) into the Dockerfile so they can be exercised against pulp-service's pinned pulpcore/pulp_rpm versions. Also adds a DomainOrgAuthenticationBackend so that user.has_perm("core.view_domain", obj=domain) checks -- used by ContentView's cross-domain distribution resolution -- reflect DomainOrg membership for domains outside of the current request's scope, which pulp-service's request-scoped DomainBasedPermission alone can't answer.
Verified end-to-end in the ghcr.io/pulp/hosted-pulp-dev-env:main dev container via pulp-add-patch/pulp-restart: CRUD, all 6 search endpoints aggregating real RPM content synced across two domains, and RBAC exclusion of a domain a limited user lacks DomainOrg access to.
Summary by Sourcery
Integrate new pulpcore ContentView resource and RPM cross-domain search endpoints into the hosted Pulp environment, and ensure domain-level RBAC works for cross-domain access checks.
New Features:
Enhancements:
Build:
Documentation:
Tests: