Skip to content
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

fix: RoleCache.has_role should be case-insensitive #35

Merged
merged 1 commit into from
Aug 19, 2024

Conversation

shadinaif
Copy link
Collaborator

@shadinaif shadinaif commented Aug 15, 2024

Description

RoleCache compares org in a case-sensitive manner while the value of org is assumed as case-insensitive by the database collation, and by the django admin form. This PR is to fix the issue to make RoleCache behave as the rest of the platform

Supporting information

Testing instructions

Preperation to test:

  • Assume a normal user in the platform, for example test_user
  • Assuming we have two courses in demo organization: course-v1:Demo+topic1+index1 and course-v1:demo+topic2+index2. We have the first course with organization Demo in course-overview instead of demo. This is acceptable in the platform

Before the fix:

  • The admin will not be able to grant test_user an instructor on the entire demo organization, the admin will have to grant it course by course. This is because CourseAccessRole will not allow two similar records like [user: test_user, course_id: "", role: instructor, org: demo] and [user: test_user, course_id: "", role: instructor, org: Demo]. The key constraint treats org as case-insensitive

After the fix:

  • Adding a single record like [user: test_user, course_id: "", role: instructor, org: demo], [user: test_user, course_id: "", role: instructor, org: Demo], or even [user: test_user, course_id: "", role: instructor, org: DEMO] will make test_user an instructor on all courses as expected

Deadline

Other information

  • This is an upstream issue. We'll contribute the fix to upstream once we have a code review here

@shadinaif shadinaif requested a review from OmarIthawi August 15, 2024 12:21
@shadinaif
Copy link
Collaborator Author

I'll contribute this to Upstream once we have a code review here

@shadinaif shadinaif force-pushed the shadinaif/fix-roles-cache branch 2 times, most recently from 9707186 to a738c4f Compare August 15, 2024 13:20
Copy link
Collaborator

@OmarIthawi OmarIthawi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shadinaif few minor notes regarding testing. They're important for upstream contribution.

@@ -90,7 +90,7 @@ def has_role(self, role, course_id, org):
return any(
access_role.role in self.get_roles(role) and
access_role.course_id == course_id and
access_role.org == org
access_role.org.lower() == org.lower()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clear!

Comment on lines 185 to 189
expected_has_role = (
target[0] == other_target[0] and
(target[1] or '') == (other_target[1] or '') and
target[2].lower() == other_target[2].lower()
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Such code is a bit too complicated for testing. Testing cases should have as few branches as possible.

Suggested change
expected_has_role = (
target[0] == other_target[0] and
(target[1] or '') == (other_target[1] or '') and
target[2].lower() == other_target[2].lower()
)

Comment on lines 164 to 165
(CourseStaffRole(IN_KEY), ('staff', IN_KEY, 'edX')),
(CourseStaffRole(IN_KEY), ('staff', IN_KEY, 'EDX')),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add expected_has_role to this list to avoid introducing complicated logic in testing

Suggested change
(CourseStaffRole(IN_KEY), ('staff', IN_KEY, 'edX')),
(CourseStaffRole(IN_KEY), ('staff', IN_KEY, 'EDX')),
(CourseStaffRole(IN_KEY), ('staff', IN_KEY, 'edX'), True), # Should have role
(CourseStaffRole(IN_KEY), ('staff', IN_KEY, 'EDX'), False), # Should have role despite case difference

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds reasonable, thank you!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it'll not work exactly like this because the test iterates on all records, but I'll find a way 👍🏼

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done 👍🏼

@shadinaif shadinaif force-pushed the shadinaif/fix-roles-cache branch from a738c4f to db728cf Compare August 16, 2024 11:09
@shadinaif shadinaif requested a review from OmarIthawi August 16, 2024 11:10
Copy link
Collaborator

@OmarIthawi OmarIthawi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shadinaif please note that I think the fix in the code is pretty fine, but tests are very hard to understand.

I'm just reviewing with very high quality standards i.e. upstream quality, let me know if you think we should stop and focus on making the fix locally and then worry about upstream contribution.

Comment on lines 184 to 185
for _, other_target, other_test_id in self.ROLES:
assert cache.has_role(*other_target) == (test_id == other_test_id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shadinaif I presume I'm very familiar with the issue being presented here, but the test still isn't understanble.

I think the real cause is that the original test_only_in_role function was cryptic.

In such case I would support creating a new test case e.g. test_only_in_role_case_insensitive so it doesn't have for-loop or at least it doesn't have to be so generic and becomes hard to understand.

@shadinaif shadinaif force-pushed the shadinaif/fix-roles-cache branch from db728cf to bdb520d Compare August 18, 2024 12:48
@shadinaif shadinaif requested a review from OmarIthawi August 18, 2024 13:15
@shadinaif
Copy link
Collaborator Author

shadinaif commented Aug 18, 2024

I've update the tests @OmarIthawi I believe it's clear now. Thank you!

Copy link
Collaborator

@OmarIthawi OmarIthawi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super!

@shadinaif shadinaif merged commit 9c0ce39 into open-release/palm.nelp Aug 19, 2024
40 checks passed
@shadinaif shadinaif deleted the shadinaif/fix-roles-cache branch August 19, 2024 06:32
@andrey-canon
Copy link
Collaborator

hi @OmarIthawi and @shadinaif, just asking, is this a backport? Or is there an equivalent upstream PR?

@shadinaif
Copy link
Collaborator Author

unfortunately, it's not equivalent to upstream. When I tried to create a PR, I found that the code there had changed and a cherry-pick was not possible. I'm planning to report/fix upstream by the end of this month. I'll keep updated @andrey-canon , thank you for checking 👍🏼

@OmarIthawi
Copy link
Collaborator

Thanks @shadinaif!!

@andrey-canon
Copy link
Collaborator

andrey-canon commented Sep 10, 2024

Hi @shadinaif thanks for you answer and I was asking because we have a migration file where we track all the custom commits. This file helps us to decide which commits we must include in the next release, so if the commit is not there, there is a chance that we will miss it, so could you please add the commit data into the file?
please check the section colors and change the row color

@shadinaif
Copy link
Collaborator Author

Thank you @andrey-canon . I've added it as gray and explained the reason in the sheet. The fix is needed, but this code should be discarded in the upgrade process (this is why I set it as gray). I'll follow up with you after having the fix in upstream

@andrey-canon
Copy link
Collaborator

d be discarded in the upgrade process (this is why I set it as gray). I'll follow up with you after having the fix in upstream

thanks @shadinaif

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants