Hey all,
I’m currently working on assigning correct roles in the superset service added to openedx via the aspects plugin. The issue is around a patch I think may be broken or I’m just using it wrong. If you do not care about the background of the issue just scroll down to “exact problem”.
Based on this one page of documentation
Superset extra row level security — Open edX Aspects latest documentation (and some really old documentation from aspects v0.16.1 which I guess is irrelevant but it helped me a bit as well tutor-contrib-aspects · PyPI ) it is possible to add custom RLS rules to the platform.
My goal was to achieve a user who can create dashboards and charts but composed of data only from courses belonging to specific organizations (basically a user that would be given to a client company’s data analyst).
By default there are 3 RLS rules applied to the Instructor role however that role has no access to creating dashboards/charts.
First of all upon login into Open edX using a custom function added to the django auth pipeline I am assigning certain users staff permission on ONLY the courses belonging to their organizations.
Then to propagate that to a proper role in superset I am using the superset-sso-assignment-rules patch (Unfortunately group assignment logic is duplicated there - I’m not sure yet how to abstract it from here and the auth_pipeline). This has to be done since by default NO open edx funciton is mapped to the gamma function.
(can be seen inside superset container at /app/pythonpath/openedx_sso_security_manager.py in the get_user_roles function).
if decoded_access_token.get("superuser", False):
return ["admin", f"admin-{locale}"]
elif decoded_access_token.get("administrator", False):
return ["alpha", "operator", f"operator-{locale}", "instructor", f"instructor-{locale}"]
else:
# User has to have staff access to one or more courses to view any content
# here. Since this is only called on login, we take the opportunity
# to force refresh the user's courses from LMS. This allows them to bust
# the course permissions cache if necessary by logging out and back in.
courses = self.get_courses(username, force=True)
if courses:
if False:
raise Exception(f"Instructor {username} tried to access Superset")
return ["instructor", f"instructor-{locale}"]
else:
roles = self.extra_get_user_roles(username, decoded_access_token)
if roles:
if True and 'student' in roles:
raise Exception(f"Student access not allowed for {username} due to SUPERSET_BLOCK_STUDENT_ACCESS setting.")
return roles
if True:
raise Exception(f"Student {username} tried to access Superset")
else:
return ["student", f"student-{locale}"]
So I am propagating based on some user values (like group ID)
hooks.Filters.ENV_PATCHES.add_item(
("superset-sso-assignment-rules", """
group = get_group_logic
if group is analytics_people
return ["gamma"]
return []
"""))
Having the Gamma role (access to all courses’ data since as I mentioned only Instructor has RLS built in) I want to apply exactly the same RLS to the Gamma user role as the default one for the Instructor role.
Previously I mentioned that I set the course_access_role to staff for analytics user. I did that since the can_view_courses function found at cd $(tutor config printroot)/env/plugins/aspects/apps/superset/pythonpath/openedx_jinja_filters.py only let’s users in superset access data if they have that role set (again, Admin and Alpha in the code snippet below are too wide for my case)
mentioned function.
for role in user_roles:
if str(role) == "Admin" or str(role) == "Alpha":
return ALL_COURSES
# Everyone else only has access if they're staff on a course.
courses = security_manager.get_courses(username)
Now the exact problem:
Apparently you can modify the RLS settings with this patch
"superset-row-level-security". It does actually modify the create_row_level_security.py file. (File at cd $(tutor config printroot)/env/plugins/aspects/apps/superset/pythonpath/openedx/create_row_level_security.py)
HOWEVER I think the patch is wrong. It starts AFTER the array of SECURITY_FILTERS and it always inputs code with an INDENT rendering the .py file unlaunchable.
Default part of file (pasted as photo since couldn’t get indentation to work)
After writing an example patch:
from tutor import hooks
# According to docs, this should just append a dict to the list.
# In reality, it breaks because Tutor/Jinja injects indentation before the brace.
hooks.Filters.ENV_PATCHES.add_item(
("superset-row-level-security", """
{
"name": "gamma_rls_broken_demo",
"schema": "event_sink",
"exclude": [],
"role_name": "Gamma",
"group_key": "broken_demo",
"clause": "1=1",
"filter_type": "Regular",
},
"""))
The file looks as follows:
Could anyone please try to replicate this or help me solve my specific issue? This is Aspects 2.5.1. and I’m using the teak release. I also found a mismatch in the API call for when superset gets the user courses in openedx_sso_security_manager get courses function It calls permissions with an s where the actual API in this openedx version has no s… am I just fighting a version mismatch? Could not find Openedx x aspects compatibility table?

