Skip to content

feat: split read vs write authz checks for advanced settings - #39007

Open
wgu-taylor-payne wants to merge 1 commit into
openedx:masterfrom
WGU-Open-edX:tpayne/view-advanced-settings-permission
Open

feat: split read vs write authz checks for advanced settings#39007
wgu-taylor-payne wants to merge 1 commit into
openedx:masterfrom
WGU-Open-edX:tpayne/view-advanced-settings-permission

Conversation

@wgu-taylor-payne

@wgu-taylor-payne wgu-taylor-payne commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Description

Splits the advanced settings permission check so that read access uses courses.view_advanced_settings and write access uses courses.manage_advanced_settings.

Previously, the backend used COURSES_MANAGE_ADVANCED_SETTINGS for both read and write access when authz was enabled. This PR splits the check so that GET uses COURSES_VIEW_ADVANCED_SETTINGS and PATCH uses COURSES_MANAGE_ADVANCED_SETTINGS. A corresponding frontend change is needed to check view_advanced_settings for page access (instead of only manage_advanced_settings) and render read-only mode when the user lacks the manage permission. Per the design decisions in openedx/openedx-authz#283, users with any course role should be able to see advanced settings in read-only mode.

User roles impacted: Course Editor, Course Auditor — can now view (but not edit) advanced settings when authz is enabled.

Changes:

  • common/djangoapps/student/auth.py: Import COURSES_VIEW_ADVANCED_SETTINGS, use it for access_type="read" in the authz branch
  • Tests: 4 new tests verifying editor/auditor can GET (200) but cannot PATCH (403)

Rollback: Gated behind AUTHZ_COURSE_AUTHORING_FLAG — disabling the flag reverts to legacy behavior.

Supporting information

Testing instructions

  1. Enable AUTHZ_COURSE_AUTHORING_FLAG for a course
  2. Assign a user the course_editor role on that course
  3. GET /api/contentstore/v0/advanced_settings/{course_id} → should return 200
  4. PATCH /api/contentstore/v0/advanced_settings/{course_id} → should return 403
  5. Repeat with course_auditor — same expected results
  6. Assign course_staff — both GET and PATCH should return 200

Deadline

None

AI Usage

Kiro was used as a development partner throughout this PR. I directed the implementation approach, defined scope, reviewed generated code, and made design decisions — Kiro researched the codebase, wrote the implementation and tests, ran lint/type checks, and iterated on fixes. I verified the changes manually against a local Tutor dev environment and reviewed the final diffs before submitting.

@openedx-webhooks openedx-webhooks added open-source-contribution PR author is not from Axim or 2U core contributor PR author is a Core Contributor (who may or may not have write access to this repo). labels Aug 20, 2026
@openedx-webhooks

openedx-webhooks commented Aug 20, 2026

Copy link
Copy Markdown

Thanks for the pull request, @wgu-taylor-payne!

This repository is currently maintained by @openedx/wg-maintenance-openedx-platform-oncall.

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 approval

If you haven't already, check this list to see if your contribution needs to go through the product review process.

  • If it does, you'll need to submit a product proposal for your contribution, and have it reviewed by the Product Working Group.
    • This process (including the steps you'll need to take) is documented here.
  • If it doesn't, simply proceed with the next step.
🔘 Provide context

To 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:

  • Dependencies

    This PR must be merged before / after / at the same time as ...

  • Blockers

    This PR is waiting for OEP-1234 to be accepted.

  • Timeline information

    This PR must be merged by XX date because ...

  • Partner information

    This is for a course on edx.org.

  • Supporting documentation
  • Relevant Open edX discussion forum threads
🔘 Get a green build

If one or more checks are failing, continue working on your changes until this is no longer the case and your build turns green.

Details
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:

  • The size and impact of the changes that it introduces
  • The need for product review
  • Maintenance status of the parent repository

💡 As a result it may take up to several weeks or months to complete a review and merge your PR.

@github-project-automation github-project-automation Bot moved this to Needs Triage in Contributions Aug 20, 2026
BryanttV added a commit to eduNEXT/edx-platform that referenced this pull request Aug 20, 2026
@wgu-taylor-payne
wgu-taylor-payne force-pushed the tpayne/view-advanced-settings-permission branch 3 times, most recently from 19f312d to 6173a9f Compare August 21, 2026 18:23
@wgu-taylor-payne
wgu-taylor-payne marked this pull request as ready for review August 21, 2026 18:41
@wgu-taylor-payne
wgu-taylor-payne force-pushed the tpayne/view-advanced-settings-permission branch from 6173a9f to e59713e Compare August 24, 2026 19:12

@BryanttV BryanttV left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM! I tested this on my local and it works as expected.

Comment thread cms/djangoapps/contentstore/rest_api/v0/tests/test_advanced_settings.py Outdated

@BryanttV BryanttV left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While running some other tests, I accessed the URL http://apps.local.openedx.io:2001/authoring/course/course-v1:OpenedX+DemoX+DemoCourse/settings/advanced directly as a Course Editor to see which endpoints were being called.

I found that in addition to the advanced_settings endpoint updated in the PR, the /api/contentstore/v1/proctoring_errors/course-v1:OpenedX+DemoX+DemoCourse endpoint is also called.

The second endpoint is returning a 403. Should we also update the permission validation on that endpoint so that it can retrieve the proctoring errors?

UPDATE:

Perhaps the solution would be that for the write access_type we use COURSES_MANAGE_ADVANCED_SETTINGS, and for read and feature_restricted we check against COURSES_VIEW_ADVANCED_SETTINGS?

cc @gviedma-aulasneo

)
self.assertEqual(response.status_code, 403) # noqa: PT009

def test_editor_can_view_advanced_settings(self, mock_flag):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are we testing the editor can write code branch as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, there is a test ensuring that a course editor cannot modify advanced settings (ref - see explicit exclusions).

@mphilbrick211 mphilbrick211 added the mao-onboarding Reviewing this will help onboard devs from an Axim mission-aligned organization (MAO). label Aug 26, 2026
@mphilbrick211 mphilbrick211 moved this from Needs Triage to Ready for Review in Contributions Aug 26, 2026
@mphilbrick211 mphilbrick211 moved this from Ready for Review to In Eng Review in Contributions Aug 26, 2026
@rodmgwgu

Copy link
Copy Markdown
Contributor

While running some other tests, I accessed the URL http://apps.local.openedx.io:2001/authoring/course/course-v1:OpenedX+DemoX+DemoCourse/settings/advanced directly as a Course Editor to see which endpoints were being called.

I found that in addition to the advanced_settings endpoint updated in the PR, the /api/contentstore/v1/proctoring_errors/course-v1:OpenedX+DemoX+DemoCourse endpoint is also called.

The second endpoint is returning a 403. Should we also update the permission validation on that endpoint so that it can retrieve the proctoring errors?

UPDATE:

Perhaps the solution would be that for the write access_type we use COURSES_MANAGE_ADVANCED_SETTINGS, and for read and feature_restricted we check against COURSES_VIEW_ADVANCED_SETTINGS?

cc @gviedma-aulasneo

I see that the proctoring_errors endpoint returns the following:

{
"mfe_proctored_exam_settings_url": "/course/course-v1:OpenedX+DemoX+DemoCourse/pages-and-resources/proctoring/settings",
"proctoring_errors": []
}

I'm not sure what's that used for, perhaps to show an error banner is there are any proctored errors?

Anyway, as it's a GET request, I think a COURSES_VIEW_ADVANCED_SETTINGS permission should be enough to enable it, so we do need to update that endpoint to allow that permission.

@BryanttV

Copy link
Copy Markdown
Contributor

When accessing the Advanced Settings, the Proctoring Errors endpoint is also called. This endpoint is not related to reviewing student exam attempts or anything similar. It is simply a configuration validator for the proctoring fields that live within the course's Advanced Settings. It checks the following fields:

  • proctoring_provider
  • enable_proctoring_exams
  • proctoring_escalation_email
  • create_zendesk_tickets

and generates warnings depending on the configuration. This endpoint is used by the frontend to render an alert banner if there are any errors.

The endpoint (/api/contentstore/v1/proctoring_errors/{course-id}) performs the following Legacy permission validation:

def has_studio_advanced_settings_access(user):
    """
    If DISABLE_ADVANCED_SETTINGS feature is enabled, only Django Superuser
    or Django Staff can access "Advanced Settings".

    By default, this feature is disabled.
    """
    return (
        not getattr(settings, 'DISABLE_ADVANCED_SETTINGS', False)
        or user.is_staff
        or user.is_superuser
    )

In other words, any authenticated user would have permission to query the proctoring errors if the DISABLE_ADVANCED_SETTINGS setting is set to False (the default value). Otherwise, only a user with Django Staff or Django Superuser privileges could consume it.

What I think (and I agree with Rodrigo) we should do in this case is allow users with roles that have the courses.view_advanced_settings permission to also consume this endpoint without issues, since this is a configuration error that a Course Auditor, for example, should be able to view via the alert.

cc @gviedma-aulasneo

@rodmgwgu rodmgwgu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code looks good, also tested in my local for the auditor, editor and staff roles and all worked as advertised. Thanks!

Just let's decide on what to do with the proctoring_error endpoint, should we include the change to that one here? or do it as a separate PR?

@BryanttV

Copy link
Copy Markdown
Contributor

I see that with Taylor's change (ec30500), the endpoint is now working. @rodmgwgu, does this look good to you?

I'd say we handle this in this PR, but first I'd like to get some feedback and approval from the product team.

@rodmgwgu

Copy link
Copy Markdown
Contributor

I see that with Taylor's change (ec30500), the endpoint is now working. @rodmgwgu, does this look good to you?

I'd say we handle this in this PR, but first I'd like to get some feedback and approval from the product team.

Oh that's great, yeah looks good to me, let's just get approval from product and then we should be good to go.

@wgu-taylor-payne

Copy link
Copy Markdown
Contributor Author

I see that with Taylor's change (ec30500), the endpoint is now working. @rodmgwgu, does this look good to you?
I'd say we handle this in this PR, but first I'd like to get some feedback and approval from the product team.

Oh that's great, yeah looks good to me, let's just get approval from product and then we should be good to go.

@gviedma-aulasneo approved this approach in our weekly meeting today.

Use COURSES_VIEW_ADVANCED_SETTINGS for read access and
COURSES_MANAGE_ADVANCED_SETTINGS for write access when authz is enabled.
This allows Course Editors and Auditors to view advanced settings in
read-only mode while keeping write access restricted.

The 'feature_restricted' access type also checks
COURSES_VIEW_ADVANCED_SETTINGS (not manage), so view-only roles can
reach the proctoring errors endpoint that the advanced settings page
calls on load; previously this returned 403 for editors/auditors.
@wgu-taylor-payne
wgu-taylor-payne force-pushed the tpayne/view-advanced-settings-permission branch from ec30500 to e6260b7 Compare August 27, 2026 20:17

@rodmgwgu rodmgwgu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks!

BryanttV added a commit to eduNEXT/edx-platform that referenced this pull request Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core contributor PR author is a Core Contributor (who may or may not have write access to this repo). mao-onboarding Reviewing this will help onboard devs from an Axim mission-aligned organization (MAO). open-source-contribution PR author is not from Axim or 2U

Projects

Status: In Eng Review

Development

Successfully merging this pull request may close these issues.

Add courses.view_advanced_settings enforcement in openedx-platform

6 participants