-
Notifications
You must be signed in to change notification settings - Fork 169
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
has[Write|Read]Access does not use wildcard permissions #2353
Milestone
Comments
chrisknoll
added a commit
that referenced
this issue
Feb 27, 2024
Changed read/write permission checks to use permissions instead of roles. Permission checks are using Subject.isPermitted() which honors wildcard semantics. Altered JwtAuthRealm to filter user permissions to either * or first element of permission to check for speed. Changed permission index from JsonNode to Map<>. Serializes same way, but map semantics are simpler to navigate. Altered AuthrizationInfo to contain index of Permissions and store Wildcard perms. General cleanup of unused imports and removed unused dependencies (ie: Autowired fields were removed if no longer needed). Fixes #2353.
In lieu of feedback on this issue, I've crated PR #2355 to address these concerns. @rkboyce : can you please grab this branch and see if your global read (and other expected permission assignments) work correctly under this branch? Note; this will require the Atlas version that is currently on master. |
chrisknoll
added a commit
that referenced
this issue
Apr 23, 2024
Permission checks are using Subject.isPermitted() which honors wildcard semantics. Changed read/write permission checks to use permissions instead of roles. Removed role cache from Permission Service. Altered JwtAuthRealm to filter user permissions to either * or first element of permission to check for speed. Changed permission index from JsonNode to Map<>. Serializes same way, but map semantics are simpler to navigate. Altered AuthrizationInfo to contain index of Permissions and store Wildcard perms. General cleanup of unused imports and removed unused dependencies (ie: Autowired fields were removed if no longer needed). Fixes #2353. * Added test cases. Reordered test scoped dependencies in pom.xml. Refactored shared methods to AbstractDatabaseTest.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Expected behavior
Wildcard (
*
) permissions should be honored when checking read/write access.Actual behavior
When checking entity permissions via
hasWriteAccess
orhasReadAccess
it is checking theentitySchema
(which is a string template of permissions for the given entity) for an exact string match for the specific entity ID. This means that permission granted to the user via wildcard permissions (such as a role that grants write permission to everything via*
) is not honored.Ie: checking
cohortdefinition:1:get
against a grant ofcohortdefinitiion:*:get
will fail, when the wildcard should allow any ID to pass.Steps to reproduce behavior
This is a symptom of #2323 , in so far as the wildcard permission to
cohortdefinition:*:get
should be seen as read permission. and in that case only the specificcohortdefinition:{id}:get
is recognized as the read permission. But this is a general symptom that we're not using WildCard permissions when checking perms in some cases but we are in other (such as URL checks).Technical Considerations
As I was researching how permissions were applied, I was greatly confused by the approach taken in the code, and will try to describe it here so that the original devs (or people closer to the code) can comment and clarify.
The hasWriteAccess() is doing something particularly strange: I would have expected that in order to determine if you have write permissions, you get the set of permissions from getTemplatesForType() and just check that the user has all necessary permissions in order to determine if the user has
WRITE
access. However, the code builds a permission cache in preparePermissionCache() which does the following:in short: this will find all the roles that contain the specified permissions (from the template), and back in
getRolesHavingPermissions
it performs this work to returnRoleDTO
s that contain all the specified permissions in the template:Note: using WildCard semantics, it's possible a person may match 2 permissions for the same check (the * check and the literal {id} check), throwing off the 'fitCount' check which says we want the roles that have exactly the correct permissions.
Back in
hasWriteAccess
:This block appears to be saying : ' if the user has any role that matches any role that has the required write permissions matches any role that is assigned to the user.
This seems like a wildly round-about way to answer the question 'do you have write access'. If write access is determined by if they have the required permission, a permission grant of
*
should match all 5 of the required permissions and thus grant the user TRUE for write access.However, I may be missing some underlying concept of this logic that is not clear. For example, maybe associating back to the role-level permissions handles some corner case...or maybe it's faster to check a set of roles a user has compared to a set of permissions (although we still need to check all the permissions to find the roles these permissions belong to). It also seems to force that all permissions must be found in a single role in order to 'count', but I'm not sure why that needs to be the case here: If RoleA grants some the required WRITE perms, and RoleB grants the rest, wouldn't a person assigned to RoleA and RoleB then have write perms to the entity?
I would appreciate if @alex-odysseus and members of @OHDSI/odysseus could speak on these considerations because they were responsible for the initial implementation.
The text was updated successfully, but these errors were encountered: