@@ -59,6 +59,7 @@ class ContentLibraryScope(Scope):
5959 """
6060
6161 NAMESPACE = "lib"
62+ LINKED_OBJECT_FIELD = "content_library"
6263
6364 # Link to the actual content library, if applicable. In other cases, this could be null.
6465 # Piggybacking on the existing ContentLibrary model to keep the ExtendedCasbinRule up to date
@@ -79,54 +80,9 @@ class ContentLibraryScope(Scope):
7980 )
8081
8182 @classmethod
82- def get_or_create_for_external_key (cls , scope ) -> "ContentLibraryScope" :
83- """Get or create a ContentLibraryScope for the given external key.
84-
85- The backing ContentLibrary need not exist yet (e.g. it may be created
86- later as part of an in-progress operation): the scope is created with
87- ``content_library=None`` in that case and gets linked up automatically
88- once a ContentLibrary with a matching key is saved (see link_pending_scope()
89- and the backfill signal receiver in openedx_authz/handlers.py).
90-
91- Args:
92- scope: ScopeData object with an external_key attribute containing
93- a LibraryLocatorV2-compatible string.
94-
95- Returns:
96- ContentLibraryScope: The Scope instance for the given ContentLibrary,
97- or None if the scope is a glob pattern (contains wildcard).
98- """
99- content_library = scope .get_object ()
100- if content_library is None :
101- # The library doesn't exist yet: key the row by its external_key so it can be
102- # found and linked up later by link_pending_scope().
103- row , _ = cls .objects .get_or_create (external_key = scope .external_key )
104- return row
105-
106- # Look up by the FK first (as before this change) so scopes created before the
107- # external_key field existed are reused rather than duplicated.
108- row , created = cls .objects .get_or_create (
109- content_library = content_library ,
110- defaults = {"external_key" : scope .external_key },
111- )
112- if not created and not row .external_key :
113- row .external_key = scope .external_key
114- row .save (update_fields = ["external_key" ])
115- return row
116-
117- @classmethod
118- def link_pending_scope (cls , content_library ) -> None :
119- """Link a pending ContentLibraryScope to the ContentLibrary that was just created for it.
120-
121- Called from the ContentLibrary post_save signal receiver in openedx_authz/handlers.py
122- once a library with a matching external_key shows up.
123-
124- Args:
125- content_library: The ContentLibrary instance that was just saved.
126- """
127- cls .objects .filter (
128- external_key = str (content_library .library_key ), content_library__isnull = True
129- ).update (content_library = content_library )
83+ def external_key_for_object (cls , linked_object ) -> str :
84+ """Return the canonical external_key string for a ContentLibrary instance."""
85+ return str (linked_object .library_key )
13086
13187
13288class CourseScope (Scope ):
@@ -136,6 +92,7 @@ class CourseScope(Scope):
13692 """
13793
13894 NAMESPACE = "course-v1"
95+ LINKED_OBJECT_FIELD = "course_overview"
13996
14097 # Link to the actual course, if applicable. In other cases, this could be null.
14198 # Piggybacking on the existing CourseOverview model to keep the ExtendedCasbinRule up to date
@@ -156,52 +113,6 @@ class CourseScope(Scope):
156113 )
157114
158115 @classmethod
159- def get_or_create_for_external_key (cls , scope ) -> "CourseScope" :
160- """Get or create a CourseScope for the given external key.
161-
162- The backing CourseOverview need not exist yet (e.g. during a course
163- rerun, the destination course id is known before the course is
164- cloned): the scope is created with ``course_overview=None`` in that
165- case and gets linked up automatically once a CourseOverview with a
166- matching id is saved (see link_pending_scope() and the backfill
167- signal receiver in openedx_authz/handlers.py).
168-
169- Args:
170- scope: ScopeData object with an external_key attribute containing
171- a CourseKey string.
172-
173- Returns:
174- CourseScope: The Scope instance for the given CourseOverview,
175- or None if the scope is a glob pattern (contains wildcard).
176- """
177- course_overview = scope .get_object ()
178- if course_overview is None :
179- # The course doesn't exist yet: key the row by its external_key so it can be
180- # found and linked up later by link_pending_scope().
181- row , _ = cls .objects .get_or_create (external_key = scope .external_key )
182- return row
183-
184- # Look up by the FK first (as before this change) so scopes created before the
185- # external_key field existed are reused rather than duplicated.
186- row , created = cls .objects .get_or_create (
187- course_overview = course_overview ,
188- defaults = {"external_key" : scope .external_key },
189- )
190- if not created and not row .external_key :
191- row .external_key = scope .external_key
192- row .save (update_fields = ["external_key" ])
193- return row
194-
195- @classmethod
196- def link_pending_scope (cls , course_overview ) -> None :
197- """Link a pending CourseScope to the CourseOverview that was just created for it.
198-
199- Called from the CourseOverview post_save signal receiver in openedx_authz/handlers.py
200- once a course with a matching external_key shows up.
201-
202- Args:
203- course_overview: The CourseOverview instance that was just saved.
204- """
205- cls .objects .filter (
206- external_key = str (course_overview .id ), course_overview__isnull = True
207- ).update (course_overview = course_overview )
116+ def external_key_for_object (cls , linked_object ) -> str :
117+ """Return the canonical external_key string for a CourseOverview instance."""
118+ return str (linked_object .id )
0 commit comments