예제 #1
0
파일: test_api.py 프로젝트: eliesmr4/myedx
    def test_get_enterprise_consent_url_next_provided_not_course_specific(
            self, needed_for_course_mock):
        """
        Verify that get_enterprise_consent_url correctly builds URLs.
        """
        needed_for_course_mock.return_value = True

        request_mock = mock.MagicMock(
            user=None,
            build_absolute_uri=lambda x: 'http://localhost:8000' +
            x  # Don't do it like this in prod. Ever.
        )

        course_id = 'course-v1:edX+DemoX+Demo_Course'

        expected_url = (
            '/enterprise/grant_data_sharing_permissions?course_id=course-v1%3AedX%2BDemoX%2BDemo_'
            'Course&failure_url=http%3A%2F%2Flocalhost%3A8000%2Fdashboard%3Fconsent_failed%3Dcou'
            'rse-v1%253AedX%252BDemoX%252BDemo_Course&next=http%3A%2F%2Flocalhost%3A8000%2Fdashboard'
        )

        actual_url = get_enterprise_consent_url(request_mock,
                                                course_id,
                                                return_to='dashboard',
                                                course_specific_return=False)
        self.assertEqual(actual_url, expected_url)
예제 #2
0
    def test_get_enterprise_consent_url(
            self,
            needed_for_course_mock,
            reverse_mock,
            enterprise_customer_uuid_for_request_mock,
    ):
        """
        Verify that get_enterprise_consent_url correctly builds URLs.
        """

        def fake_reverse(*args, **kwargs):
            if args[0] == 'grant_data_sharing_permissions':
                return '/enterprise/grant_data_sharing_permissions'
            return reverse(*args, **kwargs)

        enterprise_customer_uuid_for_request_mock.return_value = 'cf246b88-d5f6-4908-a522-fc307e0b0c59'
        reverse_mock.side_effect = fake_reverse
        needed_for_course_mock.return_value = True
        request_mock = mock.MagicMock(
            user=self.user,
            build_absolute_uri=lambda x: 'http://localhost:8000' + x  # Don't do it like this in prod. Ever.
        )

        course_id = 'course-v1:edX+DemoX+Demo_Course'
        return_to = 'info'

        expected_url = (
            '/enterprise/grant_data_sharing_permissions?course_id=course-v1%3AedX%2BDemoX%2BDemo_'
            'Course&failure_url=http%3A%2F%2Flocalhost%3A8000%2Fdashboard%3Fconsent_failed%3Dcou'
            'rse-v1%253AedX%252BDemoX%252BDemo_Course&enterprise_customer_uuid=cf246b88-d5f6-4908'
            '-a522-fc307e0b0c59&next=http%3A%2F%2Flocalhost%3A8000%2Fcourses%2Fcourse-v1%3AedX%2B'
            'DemoX%2BDemo_Course%2Finfo'
        )
        actual_url = get_enterprise_consent_url(request_mock, course_id, return_to=return_to)
        self.assertEqual(actual_url, expected_url)
예제 #3
0
    def test_get_enterprise_consent_url(self, needed_for_course_mock,
                                        reverse_mock):
        """
        Verify that get_enterprise_consent_url correctly builds URLs.
        """
        def fake_reverse(*args, **kwargs):
            if args[0] == 'grant_data_sharing_permissions':
                return '/enterprise/grant_data_sharing_permissions'
            return reverse(*args, **kwargs)

        reverse_mock.side_effect = fake_reverse
        needed_for_course_mock.return_value = True

        request_mock = mock.MagicMock(
            user=None,
            build_absolute_uri=lambda x: 'http://localhost:8000' +
            x  # Don't do it like this in prod. Ever.
        )

        course_id = 'course-v1:edX+DemoX+Demo_Course'
        return_to = 'info'

        expected_url = (
            '/enterprise/grant_data_sharing_permissions?course_id=course-v1%3AedX%2BDemoX%2BDemo_'
            'Course&failure_url=http%3A%2F%2Flocalhost%3A8000%2Fdashboard%3Fconsent_failed%3Dcou'
            'rse-v1%253AedX%252BDemoX%252BDemo_Course&next=http%3A%2F%2Flocalhost%3A8000%2Fcours'
            'es%2Fcourse-v1%3AedX%2BDemoX%2BDemo_Course%2Finfo')
        actual_url = get_enterprise_consent_url(request_mock,
                                                course_id,
                                                return_to=return_to)
        self.assertEqual(actual_url, expected_url)
예제 #4
0
    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)
예제 #5
0
    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(course_id.to_deprecated_string())
            # 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', course_id.to_deprecated_string())

                # If we need enterprise data sharing consent for this course, then redirect to the form.
                consent_url = get_enterprise_consent_url(request, unicode(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)
예제 #6
0
    def test_get_enterprise_consent_url(
        self,
        needed_for_course_mock,
        reverse_mock,
        enterprise_customer_uuid_for_request_mock,
    ):
        """
        Verify that get_enterprise_consent_url correctly builds URLs.
        """
        def fake_reverse(*args, **kwargs):
            if args[0] == 'grant_data_sharing_permissions':
                return '/enterprise/grant_data_sharing_permissions'
            return reverse(*args, **kwargs)

        enterprise_customer_uuid_for_request_mock.return_value = 'cf246b88-d5f6-4908-a522-fc307e0b0c59'
        reverse_mock.side_effect = fake_reverse
        needed_for_course_mock.return_value = True
        request_mock = mock.MagicMock(
            user=self.user,
            build_absolute_uri=lambda x: 'http://localhost:8000' +
            x  # Don't do it like this in prod. Ever.
        )

        course_id = 'course-v1:edX+DemoX+Demo_Course'
        return_to = 'info'

        expected_url_args = {
            'course_id': ['course-v1:edX+DemoX+Demo_Course'],
            'failure_url': [
                'http://localhost:8000/dashboard?consent_failed=course-v1%3AedX%2BDemoX%2BDemo_Course'
            ],
            'enterprise_customer_uuid':
            ['cf246b88-d5f6-4908-a522-fc307e0b0c59'],
            'next': [
                'http://localhost:8000/courses/course-v1:edX+DemoX+Demo_Course/info'
            ]
        }

        actual_url = get_enterprise_consent_url(request_mock,
                                                course_id,
                                                return_to=return_to)
        actual_url_args = parse_qs(
            actual_url.split('/enterprise/grant_data_sharing_permissions?')[1])
        self.assertEqual(actual_url_args, expected_url_args)
예제 #7
0
    def test_get_enterprise_consent_url_next_provided_not_course_specific(self, needed_for_course_mock):
        """
        Verify that get_enterprise_consent_url correctly builds URLs.
        """
        needed_for_course_mock.return_value = True

        request_mock = mock.MagicMock(
            user=None,
            build_absolute_uri=lambda x: 'http://localhost:8000' + x  # Don't do it like this in prod. Ever.
        )

        course_id = 'course-v1:edX+DemoX+Demo_Course'

        expected_url = (
            '/enterprise/grant_data_sharing_permissions?course_id=course-v1%3AedX%2BDemoX%2BDemo_'
            'Course&failure_url=http%3A%2F%2Flocalhost%3A8000%2Fdashboard%3Fconsent_failed%3Dcou'
            'rse-v1%253AedX%252BDemoX%252BDemo_Course&next=http%3A%2F%2Flocalhost%3A8000%2Fdashboard'
        )

        actual_url = get_enterprise_consent_url(request_mock, course_id, return_to='dashboard', course_specific_return=False)
        self.assertEqual(actual_url, expected_url)
예제 #8
0
파일: views.py 프로젝트: eliesmr4/myedx
    def _get_redirect_url_for_audit_enrollment(self, request, course_id):
        """
        After a user has been enrolled in a course in an audit mode, determine the appropriate location
        to which they ought to be redirected, bearing in mind enterprise data sharing consent considerations.
        """
        enterprise_learner_data = enterprise_api.get_enterprise_learner_data(
            site=request.site, user=request.user)

        if enterprise_learner_data:
            enterprise_learner = enterprise_learner_data[0]
            # If we have an enterprise learner, check to see if the current course is in the enterprise's catalog.
            is_course_in_enterprise_catalog = enterprise_api.is_course_in_enterprise_catalog(
                site=request.site,
                course_id=course_id,
                enterprise_catalog_id=enterprise_learner['enterprise_customer']
                ['catalog'])
            # If the course is in the catalog, check for an existing Enterprise enrollment
            if is_course_in_enterprise_catalog:
                client = enterprise_api.EnterpriseApiClient()
                if not client.get_enterprise_course_enrollment(
                        enterprise_learner['id'], course_id):
                    # If there's no existing Enterprise enrollment, create one.
                    client.post_enterprise_course_enrollment(
                        request.user.username, course_id, None)
                # Check if consent is required, and generate a redirect URL to the
                # consent service if so; this function returns None if consent
                # is not required or has already been granted.
                consent_url = get_enterprise_consent_url(
                    request,
                    course_id,
                    user=request.user,
                    return_to='dashboard',
                    course_specific_return=False,
                )
                # If we got a redirect URL for consent, go there.
                if consent_url:
                    return consent_url

        # If the enrollment isn't Enterprise-linked, or if consent isn't necessary, go to the Dashboard.
        return reverse('dashboard')
예제 #9
0
    def _get_redirect_url_for_audit_enrollment(self, request, course_id):
        """
        After a user has been enrolled in a course in an audit mode, determine the appropriate location
        to which they ought to be redirected, bearing in mind enterprise data sharing consent considerations.
        """
        enterprise_learner_data = enterprise_api.get_enterprise_learner_data(site=request.site, user=request.user)

        if enterprise_learner_data:
            enterprise_learner = enterprise_learner_data[0]
            # If we have an enterprise learner, check to see if the current course is in the enterprise's catalog.
            is_course_in_enterprise_catalog = enterprise_api.is_course_in_enterprise_catalog(
                site=request.site,
                course_id=course_id,
                enterprise_catalog_id=enterprise_learner['enterprise_customer']['catalog']
            )
            # If the course is in the catalog, check for an existing Enterprise enrollment
            if is_course_in_enterprise_catalog:
                client = enterprise_api.EnterpriseApiClient()
                if not client.get_enterprise_course_enrollment(enterprise_learner['id'], course_id):
                    # If there's no existing Enterprise enrollment, create one.
                    client.post_enterprise_course_enrollment(request.user.username, course_id, None)
                # Check if consent is required, and generate a redirect URL to the
                # consent service if so; this function returns None if consent
                # is not required or has already been granted.
                consent_url = get_enterprise_consent_url(
                    request,
                    course_id,
                    user=request.user,
                    return_to='dashboard',
                    course_specific_return=False,
                )
                # If we got a redirect URL for consent, go there.
                if consent_url:
                    return consent_url

        # If the enrollment isn't Enterprise-linked, or if consent isn't necessary, go to the Dashboard.
        return reverse('dashboard')