Skip to content

Release 1.142.0#3390

Merged
odlbot merged 3 commits intoreleasefrom
release-candidate
Mar 17, 2026
Merged

Release 1.142.0#3390
odlbot merged 3 commits intoreleasefrom
release-candidate

Conversation

@odlbot
Copy link
Copy Markdown
Contributor

@odlbot odlbot commented Mar 16, 2026

Carey P Gumaer

annagav

@github-actions
Copy link
Copy Markdown

OpenAPI Changes

Show/hide ## Changes for v0.yaml:
## Changes for v0.yaml:
9 changes: 0 error, 0 warning, 9 info
info	[response-required-property-added] at head/openapi/specs/v0.yaml	
	in API GET /api/v3/enrollments/
		added the required property '/items/run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_id' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v0.yaml	
	in API GET /api/v3/enrollments/
		added the required property '/items/run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_is_active' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v0.yaml	
	in API GET /api/v3/enrollments/
		added the required property '/items/run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_price' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v0.yaml	
	in API POST /api/v3/enrollments/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_id' to the response with the '201' status

info	[response-required-property-added] at head/openapi/specs/v0.yaml	
	in API POST /api/v3/enrollments/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_is_active' to the response with the '201' status

info	[response-required-property-added] at head/openapi/specs/v0.yaml	
	in API POST /api/v3/enrollments/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_price' to the response with the '201' status

info	[response-required-property-added] at head/openapi/specs/v0.yaml	
	in API GET /api/v3/enrollments/{id}/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_id' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v0.yaml	
	in API GET /api/v3/enrollments/{id}/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_is_active' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v0.yaml	
	in API GET /api/v3/enrollments/{id}/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_price' to the response with the '200' status



## Changes for v1.yaml:
9 changes: 0 error, 0 warning, 9 info
info	[response-required-property-added] at head/openapi/specs/v1.yaml	
	in API GET /api/v3/enrollments/
		added the required property '/items/run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_id' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v1.yaml	
	in API GET /api/v3/enrollments/
		added the required property '/items/run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_is_active' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v1.yaml	
	in API GET /api/v3/enrollments/
		added the required property '/items/run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_price' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v1.yaml	
	in API POST /api/v3/enrollments/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_id' to the response with the '201' status

info	[response-required-property-added] at head/openapi/specs/v1.yaml	
	in API POST /api/v3/enrollments/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_is_active' to the response with the '201' status

info	[response-required-property-added] at head/openapi/specs/v1.yaml	
	in API POST /api/v3/enrollments/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_price' to the response with the '201' status

info	[response-required-property-added] at head/openapi/specs/v1.yaml	
	in API GET /api/v3/enrollments/{id}/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_id' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v1.yaml	
	in API GET /api/v3/enrollments/{id}/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_is_active' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v1.yaml	
	in API GET /api/v3/enrollments/{id}/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_price' to the response with the '200' status



## Changes for v2.yaml:
9 changes: 0 error, 0 warning, 9 info
info	[response-required-property-added] at head/openapi/specs/v2.yaml	
	in API GET /api/v3/enrollments/
		added the required property '/items/run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_id' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v2.yaml	
	in API GET /api/v3/enrollments/
		added the required property '/items/run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_is_active' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v2.yaml	
	in API GET /api/v3/enrollments/
		added the required property '/items/run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_price' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v2.yaml	
	in API POST /api/v3/enrollments/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_id' to the response with the '201' status

info	[response-required-property-added] at head/openapi/specs/v2.yaml	
	in API POST /api/v3/enrollments/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_is_active' to the response with the '201' status

info	[response-required-property-added] at head/openapi/specs/v2.yaml	
	in API POST /api/v3/enrollments/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_price' to the response with the '201' status

info	[response-required-property-added] at head/openapi/specs/v2.yaml	
	in API GET /api/v3/enrollments/{id}/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_id' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v2.yaml	
	in API GET /api/v3/enrollments/{id}/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_is_active' to the response with the '200' status

info	[response-required-property-added] at head/openapi/specs/v2.yaml	
	in API GET /api/v3/enrollments/{id}/
		added the required property 'run/allOf[#/components/schemas/CourseRunWithCourseV3]/upgrade_product_price' to the response with the '200' status



Unexpected changes? Ensure your branch is up-to-date with main (consider rebasing).

Comment on lines +44 to +46
prefetched_products = getattr(obj, "prefetched_products", None)
if prefetched_products is not None:
return prefetched_products[0] if prefetched_products else None
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: The is_upgradable property incorrectly returns True for runs with only inactive products, causing the serializer to potentially expose inactive product data.
Severity: MEDIUM

Suggested Fix

Update the is_upgradable property in courses/models.py to check for active products specifically. When using prefetched products, use any(p.is_active for p in self.prefetched_products). For the database query fallback, use self.products.filter(is_active=True).exists(). Additionally, consider adding is_active=True to the prefetch query in courses/views/v3/__init__.py to prevent inactive products from being fetched in the first place.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: courses/serializers/v3/courses.py#L44-L46

Potential issue: The `is_upgradable` property on the `CourseRun` model can incorrectly
return `True` when a run only has inactive products. This is because the logic checks
for the existence of any product (`self.products.exists()` or
`bool(self.prefetched_products)`) without filtering for `is_active=True`. When this
occurs in an API view that uses a prefetch for all products (active and inactive), the
`CourseRunWithCourseSerializer`'s `_get_upgrade_product` method may return the first
product from the prefetched list, which could be an inactive one. This leads to the API
response incorrectly indicating that a run is upgradable and exposing details (ID,
price) of an inactive product.

Did we get this right? 👍 / 👎 to inform future reviews.

@odlbot odlbot merged commit a75f8b1 into release Mar 17, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants