Conversation
|
Thanks for the pull request, @rodmgwgu! 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. DetailsWhere 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. |
6750d1c to
4a43021
Compare
2b4993d to
49effcb
Compare
a333b13 to
35fbefa
Compare
Adds the schema discovery, compilation, validation, rendering and loading pipeline, the load_authz_schema management command, schema models and migration, and supporting tests. Part 3 of the stack.
4861927 to
3956e81
Compare
Closes #410
Problem
Authorization schema definitions need to be discovered, compiled, validated, rendered, and loaded into the database, with a management command and persistence models to support it.
Approach
Implements the full pipeline and supporting code:
openedx_authz/engine/schema/— discovery, compilation, validation, loading, pipeline, types, exceptionsopenedx_authz/engine/renderer.py— schema renderingopenedx_authz/management/commands/load_authz_schema.py— management commandopenedx_authz/models/schema.py+ migration0011_authz_schema_definitions.pyMANIFEST.in/setup.pypackaging updates for the YAML data filesopenedx_authz/tests/schema/Manual testing instructions
Run in a tutor dev environment with this repo mounted. Every command below is shown for
cms;lmsworks identically.Apply the new migration first:
1. Dry run reports the change without writing
Expect
Rows to add (132),Rows to remove (0), and definition sections for 17 categories, 48 permissions, 11 roles, and 132 role-permission grants. Confirm nothing was written:2. Apply, then confirm it is idempotent
The first run prints
132 row(s) added, 0 removed. The second printsAuthz schema unchanged; nothing would be written.— no duplicate rows, no churn (ADR 0018 §2).3. Enforcement is unchanged relative to
authz.policyThe schema files render exactly the 132
prows thatauthz.policydefines, so a deployment that already ranload_policiessees no behavior change. Assign yourself a role and spot-check both a granted and a non-granted permission:At the prompt (format:
subject action scope):4. Provenance is recorded and queryable (ADR 0025)
Both print
['openedx-authz'], sinceopenedx-authzis the contributing distribution for the shipped schema.5. A role extension changes an existing role without copying it (ADR 0023)
Create an override directory inside an importable package — this is the same YAML a Tutor patch will supply once the plugin lands:
Expect exactly one row added (
courses.export_course), one removed (courses.manage_tags),~ course_editorand~ course_staffunder role definition changes, and the two matching grant changes. Apply it and verify the result:Then confirm enforcement followed, via
./manage.py cms enforcementwith a user holdingcourse_editor:courses.export_courseis now ALLOWED andcourses.manage_tagsis DENIED.Clean up and re-apply the base schema to restore the original state:
6. Removing an assigned role is blocked without
--force(ADR 0018 §6)Assign a static role to a test user through the Admin Console or the assignment API, then remove that role from the schema (comment it out of
openedx_authz/authz/schema/course_roles.yaml) and apply:Expect a
CommandErrornaming the role and the assigned subject, ending with "Re-run with force to remove them together with their assignments", and no change to the database: the role, itsprows, and the assignment are all still present and the user still enforces as allowed.Re-run with the flag:
The role, its
prows, its assignment, and its definition rows are gone, the user is now denied, and one audit record exists per removed assignment:Restore
course_roles.yaml, re-apply, and re-create the assignment if you want the environment back as it was.7. Pre-existing policy rows are adopted, unmanaged rows are left alone (ADR 0025 §6)
On a database where
load_policieshas already run but the schema has never been applied,load_authz_schemaadds 0 rows and still creates all the definition and source records — the existing rows are adopted rather than rewritten. Aprow that no schema declares stays in place and enforceable:Rows to removemust stay at 0, and thelegacy_thingrow must still be in the policy after a full apply.8. An invalid schema stops deployment before any write
Introduce an error in a schema file — for example point a role at a permission that does not exist, or give a permission a
Namespacein CamelCase — and run the command. It exits with aCommandError, the log lists every validation error with its source file, and the database is untouched. Remove the error and confirm the command succeeds again.Automated coverage
openedx_authz/tests/schema/(216 tests) covers the discover → load → validate → compile → render → plan/apply path.openedx_authz/tests/integration/test_schema_apply.py(13 tests) exercises the real Casbin enforcer and ORM, includingenforce()assertions for permission removal, force-removal, adoption, and failure rollback. The integration module is excluded from the default pytest run and needs an edx-platform environment:tutor dev run cms pytest -p no:randomly --create-db --ds=cms.envs.test \ /mnt/openedx-authz/openedx_authz/tests/integration/test_schema_apply.pyRollback plan
Revert this PR to remove the pipeline; the schema YAML files (PR 2) and ADR (PR 1) remain but are inert without this code. The new migration is additive; roll back by reverting and running the reverse migration if applied.
Retro compatibility
At this point, existing loading of authz.policy works as previously, so there is no change on the existing functionality.
The new policy loading is not executed automatically, only manually by calling the new load_authz_schema management command.
No authorization behavior changed.
Follow up work required
After this lands, the following is required to complete the schema functionality:
AI Usage
Kiro was used to assist on feature planning and implementation. Implementation was done step by step with human guidance and validation, based on the ADRs.
Stack (3/3):
rod/authz-schema-files)Merge checklist: