def country_access_rules(self, user, ip_address, url_path): """ Check the country access rules for a given course. Applies only to courseware URLs. Args: user (User): The user making the current request. ip_address (str): The IP address from which the request originated. url_path (str): The request path. Returns: HttpResponse or None """ course_id = course_id_from_url(url_path) if course_id: redirect_url = embargo_api.redirect_if_blocked( course_id, user=user, ip_address=ip_address, url=url_path, access_point='courseware') if redirect_url: return redirect(redirect_url)
def country_access_rules(self, user, ip_address, url_path): """ Check the country access rules for a given course. Applies only to courseware URLs. Args: user (User): The user making the current request. ip_address (str): The IP address from which the request originated. url_path (str): The request path. Returns: HttpResponse or None """ course_id = course_id_from_url(url_path) if course_id: redirect_url = embargo_api.redirect_if_blocked( course_id, user=user, ip_address=ip_address, url=url_path, access_point='courseware' ) if redirect_url: return redirect(redirect_url)
def process_view(self, request, view_func, view_args, view_kwargs): # pylint: disable=unused-argument """ This function handles authentication logic for wiki urls and redirects from the "root wiki" to the "course wiki" if the user accesses the wiki from a course url """ # we care only about requests to wiki urls if not view_func.__module__.startswith('wiki.'): return # wiki pages are login required if not request.user.is_authenticated: return redirect(reverse('signin_user'), next=request.path) course_id = course_id_from_url(request.path) wiki_path = request.path.partition('/wiki/')[2] if course_id: # This is a /courses/org/name/run/wiki request course_path = "/courses/{}".format(text_type(course_id)) # HACK: django-wiki monkeypatches the reverse function to enable # urls to be rewritten reverse._transform_url = lambda url: course_path + url # pylint: disable=protected-access # Authorization Check # Let's see if user is enrolled or the course allows for public access try: course = get_course_with_access(request.user, 'load', course_id) except Http404: # course does not exist. redirect to root wiki. # clearing the referrer will cause process_response not to redirect # back to a non-existent course request.META['HTTP_REFERER'] = '' return redirect('/wiki/{}'.format(wiki_path)) if not course.allow_public_wiki_access: is_enrolled = CourseEnrollment.is_enrolled( request.user, course.id) is_staff = has_access(request.user, 'staff', course) if not (is_enrolled or is_staff): # if a user is logged in, but not authorized to see a page, # we'll redirect them to the course about page return redirect('about_course', text_type(course_id)) # If we need enterprise data sharing consent for this course, then redirect to the form. consent_url = get_enterprise_consent_url( request, text_type(course_id)) if consent_url: return redirect(consent_url) # set the course onto here so that the wiki template can show the course navigation request.course = course else: # this is a request for /wiki/... # Check to see if we don't allow top-level access to the wiki via the /wiki/xxxx/yyy/zzz URLs # this will help prevent people from writing pell-mell to the Wiki in an unstructured way if not settings.FEATURES.get('ALLOW_WIKI_ROOT_ACCESS', False): raise PermissionDenied() return self._redirect_from_referrer(request, wiki_path)
def process_view(self, request, view_func, view_args, view_kwargs): # pylint: disable=unused-argument """ This function handles authentication logic for wiki urls and redirects from the "root wiki" to the "course wiki" if the user accesses the wiki from a course url """ # we care only about requests to wiki urls if not view_func.__module__.startswith('wiki.'): return # wiki pages are login required if not request.user.is_authenticated: return redirect(reverse('signin_user'), next=request.path) course_id = course_id_from_url(request.path) wiki_path = request.path.partition('/wiki/')[2] if course_id: # This is a /courses/org/name/run/wiki request course_path = "/courses/{}".format(text_type(course_id)) # HACK: django-wiki monkeypatches the reverse function to enable # urls to be rewritten reverse._transform_url = lambda url: course_path + url # pylint: disable=protected-access # Authorization Check # Let's see if user is enrolled or the course allows for public access try: course = get_course_with_access(request.user, 'load', course_id) except Http404: # course does not exist. redirect to root wiki. # clearing the referrer will cause process_response not to redirect # back to a non-existent course request.META['HTTP_REFERER'] = '' return redirect('/wiki/{}'.format(wiki_path)) if not course.allow_public_wiki_access: is_enrolled = CourseEnrollment.is_enrolled(request.user, course.id) is_staff = has_access(request.user, 'staff', course) if not (is_enrolled or is_staff): # if a user is logged in, but not authorized to see a page, # we'll redirect them to the course about page return redirect('about_course', text_type(course_id)) # If we need enterprise data sharing consent for this course, then redirect to the form. consent_url = get_enterprise_consent_url(request, text_type(course_id)) if consent_url: return redirect(consent_url) # set the course onto here so that the wiki template can show the course navigation request.course = course else: # this is a request for /wiki/... # Check to see if we don't allow top-level access to the wiki via the /wiki/xxxx/yyy/zzz URLs # this will help prevent people from writing pell-mell to the Wiki in an unstructured way if not settings.FEATURES.get('ALLOW_WIKI_ROOT_ACCESS', False): raise PermissionDenied() return self._redirect_from_referrer(request, wiki_path)
def test_course_id_from_url(self): """ Test course_id_from_url(). """ self.assertIsNone(course_id_from_url('/login')) self.assertIsNone(course_id_from_url('/course/edX/maths/2020')) self.assertIsNone(course_id_from_url('/courses/edX/maths/')) self.assertIsNone( course_id_from_url('/api/courses/v1/blocks/edX/maths/2020')) self.assertIsNone( course_id_from_url( '/api/courses/v1/blocks/course-v1:incidental+courseid+formatting' )) self.assertIsNone( course_id_from_url( '/api/courses/v41/notcourses/course-v1:incidental+courseid+formatting' )) course_id = course_id_from_url('/courses/course-v1:edX+maths+2020') self.assertCourseIdFieldsMatch(course_id=course_id, org="edX", course='maths', run='2020') course_id = course_id_from_url('/courses/edX/maths/2020') self.assertCourseIdFieldsMatch(course_id=course_id, org='edX', course='maths', run='2020') course_id = course_id_from_url( '/api/courses/v1/courses/course-v1:edX+maths+2020') self.assertCourseIdFieldsMatch(course_id=course_id, org='edX', course='maths', run='2020') 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')
def test_course_id_from_url(self): """ Test course_id_from_url(). """ self.assertIsNone(course_id_from_url('/login')) self.assertIsNone(course_id_from_url('/course/edX/maths/2020')) self.assertIsNone(course_id_from_url('/courses/edX/maths/')) self.assertIsNone(course_id_from_url('/api/courses/v1/blocks/edX/maths/2020')) self.assertIsNone(course_id_from_url('/api/courses/v1/blocks/course-v1:incidental+courseid+formatting')) self.assertIsNone(course_id_from_url('/api/courses/v41/notcourses/course-v1:incidental+courseid+formatting')) course_id = course_id_from_url('/courses/course-v1:edX+maths+2020') self.assertCourseIdFieldsMatch(course_id=course_id, org="edX", course='maths', run='2020') course_id = course_id_from_url('/courses/edX/maths/2020') self.assertCourseIdFieldsMatch(course_id=course_id, org='edX', course='maths', run='2020') course_id = course_id_from_url('/api/courses/v1/courses/course-v1:edX+maths+2020') self.assertCourseIdFieldsMatch(course_id=course_id, org='edX', course='maths', run='2020') 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')
def _redirect_from_referrer(self, request, wiki_path): """ redirect to course wiki url if the referrer is from a course page """ course_id = course_id_from_url(request.META.get('HTTP_REFERER')) if course_id: # See if we are able to view the course. If we are, redirect to it try: get_course_overview_with_access(request.user, 'load', course_id) return redirect("/courses/{course_id}/wiki/{path}".format(course_id=text_type(course_id), path=wiki_path)) except Http404: # Even though we came from the course, we can't see it. So don't worry about it. pass
def _redirect_from_referrer(self, request, wiki_path): """ redirect to course wiki url if the referrer is from a course page """ course_id = course_id_from_url(request.META.get('HTTP_REFERER')) if course_id: # See if we are able to view the course. If we are, redirect to it try: get_course_overview_with_access(request.user, 'load', course_id) return redirect(f"/courses/{str(course_id)}/wiki/{wiki_path}") # lint-amnesty, pylint: disable=line-too-long except Http404: # Even though we came from the course, we can't see it. So don't worry about it. pass
def country_access_rules(self, request: Request) -> Optional[Response]: """ Check the country access rules for a given course. Applies only to courseware URLs. Args: request: The request to validate against the embargo rules Returns: HttpResponse or None """ course_id = course_id_from_url(request.path) if course_id: redirect_url = embargo_api.redirect_if_blocked( request, course_id, access_point='courseware') if redirect_url: return redirect(redirect_url)