Skip to content

Commit

Permalink
fix: Update url capture regex for course id
Browse files Browse the repository at this point in the history
  • Loading branch information
brobro10000 committed Dec 13, 2024
1 parent 7f80c1a commit b30df6b
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 3 deletions.
7 changes: 6 additions & 1 deletion openedx/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,14 @@
# Note: these intentionally greedily grab all chars up to the next slash includingny pluses
# DHM: I really wanted to ensure the separators were the same (+ or /) but all patts tried had
# too many inadvertent side effects :-(

COURSE_KEY_PATTERN = r'(?P<course_key_string>[^/+]+(/|\+)[^/+]+(/|\+)[^/?]+)'
COURSE_ID_PATTERN = COURSE_KEY_PATTERN.replace('course_key_string', 'course_id')
COURSE_KEY_REGEX = COURSE_KEY_PATTERN.replace('P<course_key_string>', ':')

# This constant can be extended to take into account future urls to negate with the following pattern
# (?=\/(enroll|unenroll|other_patterns)$)
POSTFIXED_PATTERNS_TO_NEGATE = r'(?=\/enroll)$'
CAPTURED_CLEAN_COURSE_ID_PATTERN = r'^(?P<clean_course_id>.*?)'

COURSE_PUBLISHED = 'published'
COURSE_UNPUBLISHED = 'unpublished'
11 changes: 9 additions & 2 deletions openedx/core/lib/request_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
from opaque_keys.edx.keys import CourseKey
from rest_framework.views import exception_handler

from openedx.core.constants import CAPTURED_CLEAN_COURSE_ID_PATTERN, POSTFIXED_PATTERNS_TO_NEGATE
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from openedx.core.lib.courses import clean_course_id

# accommodates course api urls, excluding any course api routes that do not fall under v*/courses, such as v1/blocks.
COURSE_REGEX = re.compile(fr'^(.*?/course(s)?/)(?!v[0-9]+/[^/]+){settings.COURSE_ID_PATTERN}')
CLEANED_COURSE_ID_REGEX = re.compile(f'{CAPTURED_CLEAN_COURSE_ID_PATTERN}{POSTFIXED_PATTERNS_TO_NEGATE}')

log = logging.getLogger(__name__)

Expand Down Expand Up @@ -77,14 +80,18 @@ def course_id_from_url(url):

if match is None:
return None

course_id = match.group('course_id')

if course_id is None:
return None

print(course_id, 'unclean')
cleaned_course_id = CLEANED_COURSE_ID_REGEX.match(course_id)
cleaned_course_id = cleaned_course_id.group('clean_course_id') if cleaned_course_id else course_id
print(cleaned_course_id, 'clean')

try:
return CourseKey.from_string(course_id)
return CourseKey.from_string(cleaned_course_id)
except InvalidKeyError:
return None

Expand Down
7 changes: 7 additions & 0 deletions openedx/core/lib/tests/test_request_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ def test_course_id_from_url(self):
course_id = course_id_from_url('/api/courses/v1/courses/edX/maths/2020')
self.assertCourseIdFieldsMatch(course_id=course_id, org='edX', course='maths', run='2020')

course_id = course_id_from_url('/enterprise/5d566680-12a8-4b85-89d8-d9eacbf0f9eb/course/edX+math/enroll/')
self.assertCourseIdFieldsMatch(course_id=course_id, org='edX', course='maths')

course_id = course_id_from_url('/enterprise/5d566680-12a8-4b85-89d8-d9eacbf0f9eb/course/edX+math+2020/enroll/')
self.assertCourseIdFieldsMatch(course_id=course_id, org='edX', course='maths', run='2020')
assert 1 == 2

def assertCourseIdFieldsMatch(self, course_id, org, course, run):
""" Asserts that the passed-in course id matches the specified fields"""
assert course_id.org == org
Expand Down

0 comments on commit b30df6b

Please sign in to comment.