示例#1
0
文件: utils.py 项目: mitodl/mitxpro
def ensure_active_user(user):
    """
    Activates the user (if required) and generates Open edX credentials and corresponding user if
    necessary

    Args:
        user (users.models.User): The user to activate/verify as functional
    """
    from courseware.api import repair_faulty_edx_user  # circular import issues

    if not user.is_active:
        user.is_active = True
        user.save()
        log.info("User %s activated", user.email)

    # Check if the user is properly onboard with edX (has proper auth credentials)
    # and try to repair if necessary
    if User.faulty_courseware_users.filter(pk=user.id).exists():
        try:
            created_user, created_auth_token = repair_faulty_edx_user(user)
            if created_user:
                log.info("Created edX user for %s", user.email)
            if created_auth_token:
                log.info("Created edX auth token for %s", user.email)
        except HTTPError as exc:
            log.error(
                "%s (%s): Failed to repair (%s)",
                user.username,
                user.email,
                get_error_response_summary(exc.response),
            )
        except Exception:  # pylint: disable=broad-except
            log.exception("%s (%s): Failed to repair", user.username,
                          user.email)
示例#2
0
文件: api.py 项目: mitodl/mitxpro
def repair_faulty_courseware_users():
    """
    Loops through all Users that are incorrectly configured with the courseware and attempts to get
    them in the correct state.

    Returns:
        list of User: Users that were successfully repaired
    """
    now = now_in_utc()
    repaired_users = []
    for user in User.faulty_courseware_users.filter(
            created_on__lt=now -
            timedelta(minutes=COURSEWARE_REPAIR_GRACE_PERIOD_MINS)):
        try:
            # edX is our only courseware for the time being. If a different courseware is added, this
            # function will need to be updated.
            created_user, created_auth_token = repair_faulty_edx_user(user)
        except HTTPError as exc:
            log.exception(
                "Failed to repair faulty user %s (%s). %s",
                user.username,
                user.email,
                get_error_response_summary(exc.response),
            )
        except Exception:  # pylint: disable=broad-except
            log.exception("Failed to repair faulty user %s (%s)",
                          user.username, user.email)
        else:
            if created_user or created_auth_token:
                repaired_users.append(user)
    return repaired_users
示例#3
0
文件: api.py 项目: mitodl/mitxpro
def enroll_in_edx_course_runs(user, course_runs):
    """
    Enrolls a user in edx course runs

    Args:
        user (users.models.User): The user to enroll
        course_runs (iterable of CourseRun): The course runs to enroll in

    Returns:
        list of edx_api.enrollments.models.Enrollment:
            The results of enrollments via the edx API client

    Raises:
        EdxApiEnrollErrorException: Raised if the underlying edX API HTTP request fails
        UnknownEdxApiEnrollException: Raised if an unknown error was encountered during the edX API request
    """
    edx_client = get_edx_api_client(user)
    results = []
    for course_run in course_runs:
        try:
            result = edx_client.enrollments.create_student_enrollment(
                course_run.courseware_id, mode=EDX_ENROLLMENT_PRO_MODE)
            results.append(result)
        except HTTPError as exc:
            # If there is an error message and it indicates that the preferred enrollment mode was the cause of the
            # error, log an error and try to enroll the user in 'audit' mode as a failover.
            if not is_json_response(exc.response):
                raise EdxApiEnrollErrorException(user, course_run,
                                                 exc) from exc
            error_msg = exc.response.json().get("message", "")
            is_enroll_mode_error = any([
                error_text in error_msg
                for error_text in PRO_ENROLL_MODE_ERROR_TEXTS
            ])
            if not is_enroll_mode_error:
                raise EdxApiEnrollErrorException(user, course_run,
                                                 exc) from exc
            log.error(
                "Failed to enroll user in %s with '%s' mode. Attempting to enroll with '%s' mode instead. "
                "(%s)",
                course_run.courseware_id,
                EDX_ENROLLMENT_PRO_MODE,
                EDX_ENROLLMENT_AUDIT_MODE,
                get_error_response_summary(exc.response),
            )
            try:
                result = edx_client.enrollments.create_student_enrollment(
                    course_run.courseware_id, mode=EDX_ENROLLMENT_AUDIT_MODE)
            except HTTPError as inner_exc:
                raise EdxApiEnrollErrorException(user, course_run,
                                                 inner_exc) from inner_exc
            except Exception as inner_exc:  # pylint: disable=broad-except
                raise UnknownEdxApiEnrollException(user, course_run,
                                                   inner_exc) from inner_exc
            results.append(result)
        except Exception as exc:  # pylint: disable=broad-except
            raise UnknownEdxApiEnrollException(user, course_run, exc) from exc
    return results
示例#4
0
def test_get_error_response_summary(content, content_type, exp_summary_content,
                                    exp_url_in_summary):
    """
    get_error_response_summary should provide a summary of an error HTTP response object with the correct bits of
    information depending on the type of content.
    """
    status_code = 400
    url = "http://example.com"
    mock_response = MockResponse(status_code=status_code,
                                 content=content,
                                 content_type=content_type,
                                 url=url)
    summary = get_error_response_summary(mock_response)
    assert f"Response - code: {status_code}" in summary
    assert f"content: {exp_summary_content}" in summary
    assert (f"url: {url}" in summary) is exp_url_in_summary
示例#5
0
    def __init__(self, user, course_run, http_error, msg=None):
        """
        Sets exception properties and adds a default message

        Args:
            user (users.models.User): The user for which the enrollment failed
            course_run (courses.models.CourseRun): The course run for which the enrollment failed
            http_error (requests.exceptions.HTTPError): The exception from the API call which contains
                request and response data.
        """
        self.user = user
        self.course_run = course_run
        self.http_error = http_error
        if msg is None:
            # Set some default useful error message
            msg = "EdX API error enrolling user {} ({}) in course run '{}'.\n{}".format(
                self.user.username,
                self.user.email,
                self.course_run.courseware_id,
                get_error_response_summary(self.http_error.response),
            )
        super().__init__(msg)