def enroll(cls, user, course_key, mode="honor", check_access=False):
        """
        Enroll a user in a course. This saves immediately.

        Returns a CoursewareEnrollment object.

        `user` is a Django User object. If it hasn't been saved yet (no `.id`
               attribute), this method will automatically save it before
               adding an enrollment for it.

        `course_key` is our usual course_id string (e.g. "edX/Test101/2013_Fall)

        `mode` is a string specifying what kind of enrollment this is. The
               default is "honor", meaning honor certificate. Future options
               may include "audit", "verified_id", etc. Please don't use it
               until we have these mapped out.

        `check_access`: if True, we check that an accessible course actually
                exists for the given course_key before we enroll the student.
                The default is set to False to avoid breaking legacy code or
                code with non-standard flows (ex. beta tester invitations), but
                for any standard enrollment flow you probably want this to be True.

        Exceptions that can be raised: NonExistentCourseError,
        EnrollmentClosedError, CourseFullError, AlreadyEnrolledError.  All these
        are subclasses of CourseEnrollmentException if you want to catch all of
        them in the same way.

        It is expected that this method is called from a method which has already
        verified the user authentication.

        Also emits relevant events for analytics purposes.
        """
        # All the server-side checks for whether a user is allowed to enroll.
        try:
            course = modulestore().get_course(course_key)
        except ItemNotFoundError:
            log.warning(
                u"User %s failed to enroll in non-existent course %s",
                user.username,
                course_key.to_deprecated_string(),
            )
            raise NonExistentCourseError

        if check_access:
            if course is None:
                raise NonExistentCourseError
            if CourseEnrollment.is_enrollment_closed(user, course):
                log.warning(
                    u"User %s failed to enroll in course %s because enrollment is closed",
                    user.username,
                    course_key.to_deprecated_string()
                )
                raise EnrollmentClosedError

            if CourseEnrollment.objects.is_course_full(course):
                log.warning(
                    u"User %s failed to enroll in full course %s",
                    user.username,
                    course_key.to_deprecated_string(),
                )
                raise CourseFullError
        if CourseEnrollment.is_enrolled(user, course_key):
            log.warning(
                u"User %s attempted to enroll in %s, but they were already enrolled",
                user.username,
                course_key.to_deprecated_string()
            )
            if check_access:
                raise AlreadyEnrolledError

        # User is allowed to enroll if they've reached this point.
        enrollment = cls.get_or_create_enrollment(user, course_key)
        enrollment.update_enrollment(is_active=True, mode=mode)
        return enrollment