Skip to content

Commit

Permalink
fix: update from palm.master (#812)
Browse files Browse the repository at this point in the history
* fix: Update the date to the max year possible in a test. (#33995)

This test broke on January 1, 2024.

* Merge pull request #34048 from open-craft/agrendalath/xblock-callback-jwt-restricted-application-check-palm

fix(palm): add `JwtRestrictedApplication` check to XBlock callback

* fix: add missing function import in certificate template (#33904) (#34171)

* fix: add missing function import in certificate template
* test: add test case to check certificates generated when GA4 is enabled

(cherry picked from commit d0a49d1)

---------

Co-authored-by: Diana Huang <dkh@edx.org>
Co-authored-by: Piotr Surowiec <piotr@surowiec.it>
Co-authored-by: Kaustav Banerjee <kaustav@opencraft.com>
  • Loading branch information
4 people authored Mar 19, 2024
1 parent 948c26e commit 3b00c8c
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 9 deletions.
16 changes: 16 additions & 0 deletions lms/djangoapps/certificates/tests/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,19 @@ def test_html_view_site_configuration_missing(self):
response,
'This should not survive being overwritten by static content',
)

@override_settings(FEATURES=FEATURES_WITH_CERTS_ENABLED, GOOGLE_ANALYTICS_4_ID='GA-abc')
@with_site_configuration(configuration={'platform_name': 'My Platform Site'})
def test_html_view_with_g4(self):
test_url = get_certificate_url(
user_id=self.user.id,
course_id=str(self.course.id),
uuid=self.cert.verify_uuid
)
self._add_course_certificates(count=1, signatory_count=2)
response = self.client.get(test_url)
self.assertContains(
response,
'awarded this My Platform Site Honor Code Certificate of Completion',
)
self.assertContains(response, 'googletagmanager')
12 changes: 10 additions & 2 deletions lms/djangoapps/courseware/block_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from edx_proctoring.api import get_attempt_status_summary
from edx_proctoring.services import ProctoringService
from edx_rest_framework_extensions.auth.jwt.authentication import JwtAuthentication
from edx_rest_framework_extensions.permissions import JwtRestrictedApplication
from edx_when.field_data import DateLookupFieldData
from eventtracking import tracker
from opaque_keys import InvalidKeyError
Expand Down Expand Up @@ -841,12 +842,19 @@ def handle_xblock_callback(request, course_id, usage_id, handler, suffix=None):
)
else:
if user_auth_tuple is not None:
request.user, _ = user_auth_tuple
# When using JWT authentication, the second element contains the JWT token. We need it to determine
# whether the application that issued the token is restricted.
request.user, request.auth = user_auth_tuple
# This is verified by the `JwtRestrictedApplication` before it decodes the token.
request.successful_authenticator = authenticator
break

# NOTE (CCB): Allow anonymous GET calls (e.g. for transcripts). Modifying this view is simpler than updating
# the XBlocks to use `handle_xblock_callback_noauth`, which is practically identical to this view.
if request.method != 'GET' and not (request.user and request.user.is_authenticated):
# Block all request types coming from restricted applications.
if (
request.method != 'GET' and not (request.user and request.user.is_authenticated)
) or JwtRestrictedApplication().has_permission(request, None): # type: ignore
return HttpResponseForbidden('Unauthenticated')

request.user.known = request.user.is_authenticated
Expand Down
22 changes: 21 additions & 1 deletion lms/djangoapps/courseware/tests/test_block_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
from lms.djangoapps.lms_xblock.field_data import LmsFieldData
from openedx.core.djangoapps.credit.api import set_credit_requirement_status, set_credit_requirements
from openedx.core.djangoapps.credit.models import CreditCourse
from openedx.core.djangoapps.oauth_dispatch.jwt import create_jwt_for_user
from openedx.core.djangoapps.oauth_dispatch.jwt import _create_jwt, create_jwt_for_user
from openedx.core.djangoapps.oauth_dispatch.tests.factories import AccessTokenFactory, ApplicationFactory
from openedx.core.lib.courses import course_image_url
from openedx.core.lib.gating import api as gating_api
Expand Down Expand Up @@ -375,6 +375,26 @@ def test_jwt_authentication(self):
response = self.client.post(dispatch_url, {}, **headers)
assert 200 == response.status_code

def test_jwt_authentication_with_restricted_application(self):
"""Test that the XBlock endpoint disallows JWT authentication with restricted applications."""

def _mock_create_restricted_jwt(*args, **kwargs):
"""Pass an additional argument to `_create_jwt` without modifying the signature of `create_jwt_for_user`."""
kwargs['is_restricted'] = True
return _create_jwt(*args, **kwargs)

with patch('openedx.core.djangoapps.oauth_dispatch.jwt._create_jwt', _mock_create_restricted_jwt):
token = create_jwt_for_user(self.mock_user)

dispatch_url = self._get_dispatch_url()
headers = {'HTTP_AUTHORIZATION': 'JWT ' + token}

response = self.client.get(dispatch_url, {}, **headers)
assert 403 == response.status_code

response = self.client.post(dispatch_url, {}, **headers)
assert 403 == response.status_code

def test_missing_position_handler(self):
"""
Test that sending POST request without or invalid position argument don't raise server error
Expand Down
6 changes: 4 additions & 2 deletions lms/templates/certificates/accomplishment-base.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<%page expression_filter="h"/>
<%namespace name='static' file='/static_content.html'/>
<%! from django.utils.translation import gettext as _%>

<%!
from django.utils.translation import gettext as _
from openedx.core.djangolib.js_utils import js_escaped_string
%>
<%
# set doc language direction
from django.utils.translation import get_language_bidi
Expand Down
5 changes: 1 addition & 4 deletions openedx/features/survey_report/tests/test_query_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@ def test_get_unique_courses_offered(self):
"""
Test that get_unique_courses_offered returns the correct number of courses.
"""
end_time = datetime.now() + timedelta(days=365)
end_time_formatted = end_time.strftime('%Y-%m-%d')
course_overview = CourseOverviewFactory.create(id=self.first_course.id, start="2019-01-01",
end=end_time_formatted)
course_overview = CourseOverviewFactory.create(id=self.first_course.id, start="2019-01-01", end="9999-01-01")
CourseEnrollmentFactory.create(user=self.user, course_id=course_overview.id)
CourseEnrollmentFactory.create(user=self.user1, course_id=course_overview.id)
CourseEnrollmentFactory.create(user=self.user2, course_id=course_overview.id)
Expand Down

0 comments on commit 3b00c8c

Please sign in to comment.