Example #1
0
 def test_get_social_auth(self):
     """
     Tests that get_social_auth returns a user's edX social auth object, and if multiple edX social auth objects
     exists, it raises an exception
     """
     assert get_social_auth(self.user) == self.user.social_auth.get(provider=EdxOrgOAuth2.name)
     UserSocialAuthFactory.create(user=self.user, uid='other name')
     with self.assertRaises(MultipleObjectsReturned):
         get_social_auth(self.user)
Example #2
0
 def test_get_social_auth(self):
     """
     Tests that get_social_auth returns a user's edX social auth object, and if multiple edX social auth objects
     exists, it raises an exception
     """
     assert get_social_auth(self.user) == self.user.social_auth.get(provider=EdxOrgOAuth2.name)
     UserSocialAuthFactory.create(user=self.user, uid='other name')
     with self.assertRaises(MultipleObjectsReturned):
         get_social_auth(self.user)
Example #3
0
    def post(self, request):
        """
        Audit enrolls the user in a course in edx
        """
        course_id = request.data.get('course_id')
        if course_id is None:
            raise ValidationError('course id missing in the request')
        # get the credentials for the current user for edX
        user_social = get_social_auth(request.user)
        try:
            utils.refresh_user_token(user_social)
        except utils.InvalidCredentialStored as exc:
            log.error(
                "Error while refreshing credentials for user %s",
                get_social_username(request.user),
            )
            return Response(
                status=exc.http_status_code,
                data={'error': str(exc)}
            )

        # create an instance of the client to query edX
        edx_client = EdxApi(user_social.extra_data, settings.EDXORG_BASE_URL)

        try:
            enrollment = edx_client.enrollments.create_audit_student_enrollment(course_id)
        except HTTPError as exc:
            if exc.response.status_code == status.HTTP_400_BAD_REQUEST:
                raise PossiblyImproperlyConfigured(
                    'Got a 400 status code from edX server while trying to create '
                    'audit enrollment. This might happen if the course is improperly '
                    'configured on MicroMasters. Course key '
                    '{course_key}, edX user "{edX_user}"'.format(
                        edX_user=get_social_username(request.user),
                        course_key=course_id,
                    )
                )
            log.error(
                "Http error from edX while creating audit enrollment for course key %s for edX user %s",
                course_id,
                get_social_username(request.user),
            )
            return Response(
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
                data={'error': str(exc)}
            )
        except Exception as exc:  # pylint: disable=broad-except
            log.exception(
                "Error creating audit enrollment for course key %s for edX user %s",
                course_id,
                get_social_username(request.user),
            )
            return Response(
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
                data={'error': str(exc)}
            )
        CachedEdxDataApi.update_cached_enrollment(request.user, enrollment, enrollment.course_id, index_user=True)
        return Response(
            data=enrollment.json
        )
Example #4
0
    def get(self, request, username, *args, **kargs):  # pylint: disable=unused-argument
        """
        Returns information needed to display the user
        dashboard for all the programs the user is enrolled in.
        """
        user = get_object_or_404(User,
                                 social_auth__uid=username,
                                 social_auth__provider=EdxOrgOAuth2.name)

        # get the credentials for the current user for edX
        edx_client = None
        if user == request.user:
            user_social = get_social_auth(request.user)
            try:
                utils.refresh_user_token(user_social)
            except utils.InvalidCredentialStored as exc:
                return Response(status=exc.http_status_code,
                                data={'error': str(exc)})
            except:  # pylint: disable=bare-except
                log.exception(
                    'Impossible to refresh user credentials in dashboard view')
            # create an instance of the client to query edX
            edx_client = EdxApi(user_social.extra_data,
                                settings.EDXORG_BASE_URL)

        try:
            program_dashboard = get_user_program_info(user, edx_client)
        except utils.InvalidCredentialStored as exc:
            log.exception(
                'Access token for user %s is fresh but invalid; forcing login.',
                user.username)
            return Response(status=exc.http_status_code,
                            data={'error': str(exc)})
        return Response(status=status.HTTP_200_OK, data=program_dashboard)
Example #5
0
    def post(self, request):
        """
        Audit enrolls the user in a course in edx
        """
        course_id = request.data.get('course_id')
        if course_id is None:
            raise ValidationError('course id missing in the request')
        # get the credentials for the current user for edX
        user_social = get_social_auth(request.user)
        try:
            utils.refresh_user_token(user_social)
        except utils.InvalidCredentialStored as exc:
            log.error(
                "Error while refreshing credentials for user %s",
                get_social_username(request.user),
            )
            return Response(
                status=exc.http_status_code,
                data={'error': str(exc)}
            )

        # create an instance of the client to query edX
        edx_client = EdxApi(user_social.extra_data, settings.EDXORG_BASE_URL)

        try:
            enrollment = edx_client.enrollments.create_audit_student_enrollment(course_id)
        except HTTPError as exc:
            if exc.response.status_code == status.HTTP_400_BAD_REQUEST:
                raise PossiblyImproperlyConfigured(
                    'Got a 400 status code from edX server while trying to create '
                    'audit enrollment. This might happen if the course is improperly '
                    'configured on MicroMasters. Course key '
                    '{course_key}, edX user "{edX_user}"'.format(
                        edX_user=get_social_username(request.user),
                        course_key=course_id,
                    )
                )
            log.error(
                "Http error from edX while creating audit enrollment for course key %s for edX user %s",
                course_id,
                get_social_username(request.user),
            )
            return Response(
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
                data={'error': str(exc)}
            )
        except Exception as exc:  # pylint: disable=broad-except
            log.exception(
                "Error creating audit enrollment for course key %s for edX user %s",
                course_id,
                get_social_username(request.user),
            )
            return Response(
                status=status.HTTP_500_INTERNAL_SERVER_ERROR,
                data={'error': str(exc)}
            )
        CachedEdxDataApi.update_cached_enrollment(request.user, enrollment, enrollment.course_id, index_user=True)
        return Response(
            data=enrollment.json
        )
Example #6
0
def refresh_user_data(user_id):
    """
    Refresh the edx cache data for a user.

    Note that this function will not raise an exception on error, instead the errors are logged.

    Args:
        user_id (int): The user id
    """
    # pylint: disable=bare-except
    try:
        user = User.objects.get(pk=user_id)
    except:
        log.exception('edX data refresh task: unable to get user "%s"',
                      user_id)
        return

    # get the credentials for the current user for edX
    try:
        user_social = get_social_auth(user)
    except:
        log.exception('user "%s" does not have edX credentials', user.username)
        return

    try:
        utils.refresh_user_token(user_social)
    except:
        save_cache_update_failure(user_id)
        log.exception("Unable to refresh token for student %s", user.username)
        return

    try:
        edx_client = EdxApi(user_social.extra_data, settings.EDXORG_BASE_URL)
    except:
        log.exception("Unable to create an edX client object for student %s",
                      user.username)
        return

    for cache_type in CachedEdxDataApi.SUPPORTED_CACHES:
        try:
            CachedEdxDataApi.update_cache_if_expired(user, edx_client,
                                                     cache_type)
        except:
            save_cache_update_failure(user_id)
            log.exception("Unable to refresh cache %s for student %s",
                          cache_type, user.username)
            continue
    def update_all_cached_grade_data(cls, user):
        """
        Updates only certificates and Current grade.
        Used before a final grade freeze.

        Args:
            user (django.contrib.auth.models.User): A user
        Returns:
            None
        """
        # get the credentials for the current user for edX
        user_social = get_social_auth(user)
        utils.refresh_user_token(user_social)
        # create an instance of the client to query edX
        edx_client = EdxApi(user_social.extra_data, settings.EDXORG_BASE_URL)
        cls.update_cached_certificates(user, edx_client)
        cls.update_cached_current_grades(user, edx_client)
Example #8
0
    def update_all_cached_grade_data(cls, user):
        """
        Updates only certificates and Current grade.
        Used before a final grade freeze.

        Args:
            user (django.contrib.auth.models.User): A user
        Returns:
            None
        """
        # get the credentials for the current user for edX
        user_social = get_social_auth(user)
        utils.refresh_user_token(user_social)
        # create an instance of the client to query edX
        edx_client = EdxApi(user_social.extra_data, settings.EDXORG_BASE_URL)
        cls.update_cached_certificates(user, edx_client)
        cls.update_cached_current_grades(user, edx_client)
Example #9
0
def refresh_user_data(user_id):
    """
    Refresh the edx cache data for a user.

    Note that this function will not raise an exception on error, instead the errors are logged.

    Args:
        user_id (int): The user id
    """
    # pylint: disable=bare-except
    try:
        user = User.objects.get(pk=user_id)
    except:
        log.exception('edX data refresh task: unable to get user "%s"', user_id)
        return

    # get the credentials for the current user for edX
    try:
        user_social = get_social_auth(user)
    except:
        log.exception('user "%s" does not have edX credentials', user.username)
        return

    try:
        utils.refresh_user_token(user_social)
    except:
        save_cache_update_failure(user_id)
        log.exception("Unable to refresh token for student %s", user.username)
        return

    try:
        edx_client = EdxApi(user_social.extra_data, settings.EDXORG_BASE_URL)
    except:
        log.exception("Unable to create an edX client object for student %s", user.username)
        return

    for cache_type in CachedEdxDataApi.SUPPORTED_CACHES:
        try:
            CachedEdxDataApi.update_cache_if_expired(user, edx_client, cache_type)
        except:
            save_cache_update_failure(user_id)
            log.exception("Unable to refresh cache %s for student %s", cache_type, user.username)
            continue
Example #10
0
def enroll_user_on_success(order):
    """
    Enroll user after they made a successful purchase.

    Args:
        order (Order): An order to be fulfilled

    Returns:
         None
    """
    user_social = get_social_auth(order.user)
    enrollments_client = EdxApi(user_social.extra_data,
                                settings.EDXORG_BASE_URL).enrollments
    existing_enrollments = enrollments_client.get_student_enrollments()

    exceptions = []
    enrollments = []
    for line in order.line_set.all():
        course_key = line.course_key
        try:
            if not existing_enrollments.is_enrolled_in(course_key):
                enrollments.append(
                    enrollments_client.create_audit_student_enrollment(
                        course_key))
        except Exception as ex:  # pylint: disable=broad-except
            log.exception(
                "Error creating audit enrollment for course key %s for user %s",
                course_key,
                get_social_username(order.user),
            )
            exceptions.append(ex)

    for enrollment in enrollments:
        CachedEdxDataApi.update_cached_enrollment(
            order.user,
            enrollment,
            enrollment.course_id,
            index_user=True,
        )

    if exceptions:
        raise EcommerceEdxApiException(exceptions)
Example #11
0
def enroll_user_on_success(order):
    """
    Enroll user after they made a successful purchase.

    Args:
        order (Order): An order to be fulfilled

    Returns:
         None
    """
    user_social = get_social_auth(order.user)
    enrollments_client = EdxApi(user_social.extra_data, settings.EDXORG_BASE_URL).enrollments
    existing_enrollments = enrollments_client.get_student_enrollments()

    exceptions = []
    enrollments = []
    for line in order.line_set.all():
        course_key = line.course_key
        try:
            if not existing_enrollments.is_enrolled_in(course_key):
                enrollments.append(enrollments_client.create_audit_student_enrollment(course_key))
        except Exception as ex:  # pylint: disable=broad-except
            log.exception(
                "Error creating audit enrollment for course key %s for user %s",
                course_key,
                get_social_username(order.user),
            )
            exceptions.append(ex)

    for enrollment in enrollments:
        CachedEdxDataApi.update_cached_enrollment(
            order.user,
            enrollment,
            enrollment.course_id,
            index_user=True,
        )

    if exceptions:
        raise EcommerceEdxApiException(exceptions)
Example #12
0
    def get(self, request, username, *args, **kargs):  # pylint: disable=unused-argument
        """
        Returns information needed to display the user
        dashboard for all the programs the user is enrolled in.
        """
        user = get_object_or_404(
            User,
            social_auth__uid=username,
            social_auth__provider=EdxOrgOAuth2.name
        )

        # get the credentials for the current user for edX
        edx_client = None
        if user == request.user:
            user_social = get_social_auth(request.user)
            try:
                utils.refresh_user_token(user_social)
            except utils.InvalidCredentialStored as exc:
                return Response(
                    status=exc.http_status_code,
                    data={'error': str(exc)}
                )
            except:  # pylint: disable=bare-except
                log.exception('Impossible to refresh user credentials in dashboard view')
            # create an instance of the client to query edX
            edx_client = EdxApi(user_social.extra_data, settings.EDXORG_BASE_URL)

        try:
            program_dashboard = get_user_program_info(user, edx_client)
        except utils.InvalidCredentialStored as exc:
            log.exception('Access token for user %s is fresh but invalid; forcing login.', user.username)
            return Response(
                status=exc.http_status_code,
                data={'error': str(exc)}
            )
        return Response(
            status=status.HTTP_200_OK,
            data=program_dashboard
        )
Example #13
0
 def get_social_auth_uid(self, user):
     """Helper method to get social_auth uid for a user"""
     return get_social_auth(user).uid
Example #14
0
 def get_social_auth_uid(self, user):
     """Helper method to get social_auth uid for a user"""
     return get_social_auth(user).uid