-
Notifications
You must be signed in to change notification settings - Fork 4.2k
[FC-0099] feat: filter libraries based on user-role scopes #37564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
Thanks for the pull request, @mariajgrimaldi! This repository is currently maintained by Once you've gone through the following steps feel free to tag them in a comment and let them know that your changes are ready for engineering review. 🔘 Get product approvalIf you haven't already, check this list to see if your contribution needs to go through the product review process.
🔘 Provide contextTo help your reviewers and other members of the community understand the purpose and larger context of your changes, feel free to add as much of the following information to the PR description as you can:
🔘 Get a green buildIf one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green. Where can I find more information?If you'd like to get more details on all aspects of the review process for open source pull requests (OSPRs), check out the following resources: When can I expect my changes to be merged?Our goal is to get community contributions seen and reviewed as efficiently as possible. However, the amount of time that it takes to review and merge a PR can vary significantly based on factors such as:
💡 As a result it may take up to several weeks or months to complete a review and merge your PR. |
a4a124a to
0d1fa11
Compare
16bce41 to
4ccfba7
Compare
|
While working on this, a few questions came up that we haven’t really answered yet - at least not in such detail: Should we start using the Right now, Option 1: Use Option 2: Keep the higher-level approach (what we do now) What do you think fits better with the long-term direction of this? In this PR, a similar question comes up, since bridgekeeper can already achieve something close to what we're doing. This brings up the broader question of how much we should move away from bridgekeeper for attribute checks (or even queryset filtering) or rely more on Casbin-based definitions. I like that bridgekeeper uses the user object already in memory, while Casbin matchers need another database call to get the same data (see openedx/openedx-authz#114). What I don’t like is that bridgekeeper hasn’t been updated in a while, so it might not be reliable long-term. Maybe the real question is whether we should keep using bridgekeeper at all - which shouldn't be answered here. |
d586651 to
d89f1dc
Compare
Given the maintenance status of the Bridgekeeper project, I think we should plan on moving away from it, perhaps reimplementing the useful parts (like the query filtering) in the openedx-authz. But this will require further research and planning. For now, an hybrid approach like Option 2 is ok I think. |
I agree on all points here, I think our goal should be to move away from Bridgekeeper as soon as we can. 👍 |
openedx/core/djangoapps/content_libraries/tests/test_content_libraries.py
Show resolved
Hide resolved
36f3d17 to
9547ed4
Compare
| # Otherwise the user must be part of the library's team | ||
| # Users can access libraries within their authorized scope (via Casbin/role-based permissions) | ||
| HasPermissionInContentLibraryScope(VIEW_LIBRARY) | | ||
| # Fallback to: the user must be part of the library's team (legacy permission system) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still want this? I thought we were not going to be using the legacy permissions any more since there will be no UI to revoke them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I think should happen, though I'm not sure it should be part of this PR. It would also mean removing user.has_perm from this PR #37501, so we need to clarify when to do that. From my view, we could handle it after the integration is complete to avoid inconsistent intermediate states. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the states will diverge either way, but I'm ok with leaving this as long as we have an issue to remove it that has a list of places we need to update 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mariajgrimaldi @bmtcril, in #37501 I was maintaining the old check for prevention. But in a DEPR WG meeting they mention the concept of expand contract pattern, that it is related. For Ulmo we are only expanding (adding the new functionality withouth removing the old one), and then we can remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I think as long as we're not actually using the old permissions that's fine and gives instances the opportunity to roll back if necessary. I just want to make sure we're not in a position where we are checking old permissions that cannot be changed.
Description
This PR adds filtering for content libraries based on user permissions, using the bridgekeeper filtering functionality built on top of the new authorization framework (based on the Casbin engine). This is the more straightforward approach since it piggybacks on the current architecture.
How it works:
The implementation introduces a custom Bridgekeeper rule (
HasPermissionInContentLibraryScope) that integrates the openedx-authz authorization system with Bridgekeeper's declarative permission system. This rule enables both individual object permission checks and efficient QuerySet filtering:Database-level filtering (
query()method): Queries the authorization system to get all library scopes where the user has permission, then builds Django Q objects to filter libraries at the database level. The permission check prioritizes the new authorization framework but falls back to the content library model permissions (the existinghas_explicit_read_permission_for_libraryrule) for backward compatibility. Although it follows a backward compatibility approach, a migration script will be provided to support the new authorization framework. See [DEPR]: Libraries' Roles and Permission System #37409Individual object checks (
check()method): For checking permission on specific library instances, it extracts the scope from the object and verifies permission via openedx-authz. This method is not currently used in favor of [FC-0099] feat: add openedx-authz to library apis user_can_create_library and require_permission_for_library_key #37501Supporting information
Related documentation:
Testing instructions
Start with a clean installation and load the authorization policies:
python manage.py {lms|cms} load_policiesCreate a new content library using a user account without admin access
Create additional libraries using different user accounts (preferably with different organizations)
Go to the libraries list page
Verify that only the libraries you have permission to view are shown in the list
Deadline
Before end-of-week (hopefully)