Exemplo n.º 1
0
def _get_recipient_queryset(user_id, to_option, course_id, course_location):
    """
    Returns a query set of email recipients corresponding to the requested to_option category.

    `to_option` is either SEND_TO_MYSELF, SEND_TO_STAFF, or SEND_TO_ALL.

    Recipients who are in more than one category (e.g. enrolled in the course and are staff or self)
    will be properly deduped.
    """
    if to_option not in TO_OPTIONS:
        log.error("Unexpected bulk email TO_OPTION found: %s", to_option)
        raise Exception(
            "Unexpected bulk email TO_OPTION found: {0}".format(to_option))

    if to_option == SEND_TO_MYSELF:
        recipient_qset = User.objects.filter(id=user_id)
    else:
        staff_qset = CourseStaffRole(course_location).users_with_role()
        instructor_qset = CourseInstructorRole(
            course_location).users_with_role()
        recipient_qset = staff_qset | instructor_qset
        if to_option == SEND_TO_ALL:
            # We also require students to have activated their accounts to
            # provide verification that the provided email address is valid.
            enrollment_qset = User.objects.filter(
                is_active=True,
                courseenrollment__course_id=course_id,
                courseenrollment__is_active=True)
            recipient_qset = recipient_qset | enrollment_qset
        recipient_qset = recipient_qset.distinct()

    recipient_qset = recipient_qset.order_by('pk')
    return recipient_qset
    def test_enrollment_period(self):
        """
        Check that enrollment periods work.
        """
        student_email, student_password = self.ACCOUNT_INFO[0]
        instructor_email, instructor_password = self.ACCOUNT_INFO[1]

        # Make courses start in the future
        now = datetime.datetime.now(pytz.UTC)
        tomorrow = now + datetime.timedelta(days=1)
        nextday = tomorrow + datetime.timedelta(days=1)
        yesterday = now - datetime.timedelta(days=1)

        course_data = {'enrollment_start': tomorrow, 'enrollment_end': nextday}
        test_course_data = {'enrollment_start': yesterday, 'enrollment_end': tomorrow}

        # self.course's enrollment period hasn't started
        self.course = self.update_course(self.course, course_data)
        # test_course course's has
        self.test_course = self.update_course(self.test_course, test_course_data)

        # First, try with an enrolled student
        self.login(student_email, student_password)
        self.assertFalse(self.enroll(self.course))
        self.assertTrue(self.enroll(self.test_course))

        # Make the instructor staff in the self.course
        instructor_role = CourseInstructorRole(self.course.location)
        instructor_role.add_users(User.objects.get(email=instructor_email))

        self.logout()
        self.login(instructor_email, instructor_password)
        self.assertTrue(self.enroll(self.course))

        # now make the instructor global staff, but not in the instructor group
        instructor_role.remove_users(User.objects.get(email=instructor_email))
        GlobalStaff().add_users(User.objects.get(email=instructor_email))

        # unenroll and try again
        self.unenroll(self.course)
        self.assertTrue(self.enroll(self.course))
Exemplo n.º 3
0
def _has_access_to_location(user, location, access_level, course_context):
    '''
    Returns True if the given user has access_level (= staff or
    instructor) access to a location.  For now this is equivalent to
    having staff / instructor access to the course location.course.

    This means that user is in the staff_* group or instructor_* group, or is an overall admin.

    TODO (vshnayder): this needs to be changed to allow per-course_id permissions, not per-course
    (e.g. staff in 2012 is different from 2013, but maybe some people always have access)

    course is a string: the course field of the location being accessed.
    location = location
    access_level = string, either "staff" or "instructor"
    '''
    if user is None or (not user.is_authenticated()):
        debug("Deny: no user or anon user")
        return False

    if is_masquerading_as_student(user):
        return False

    if GlobalStaff().has_user(user):
        debug("Allow: user.is_staff")
        return True

    if access_level not in ('staff', 'instructor'):
        log.debug("Error in access._has_access_to_location access_level=%s unknown", access_level)
        debug("Deny: unknown access level")
        return False

    staff_access = (
        CourseStaffRole(location, course_context).has_user(user) or
        OrgStaffRole(location).has_user(user)
    )

    if staff_access and access_level == 'staff':
        debug("Allow: user has course staff access")
        return True

    instructor_access = (
        CourseInstructorRole(location, course_context).has_user(user) or
        OrgInstructorRole(location).has_user(user)
    )

    if instructor_access and access_level in ('staff', 'instructor'):
        debug("Allow: user has course instructor access")
        return True

    debug("Deny: user did not have correct access")
    return False
Exemplo n.º 4
0
    def get(self, request):
        """Displays course Enrollment and staffing course statistics"""

        if not request.user.is_staff:
            raise Http404
        data = []

        courses = self.get_courses()

        for (cdir, course) in courses.items():  # pylint: disable=unused-variable
            datum = [course.display_name, course.id]
            datum += [
                CourseEnrollment.objects.filter(course_id=course.id).count()
            ]
            datum += [
                CourseStaffRole(course.location).users_with_role().count()
            ]
            datum += [
                ','.join([
                    x.username for x in CourseInstructorRole(
                        course.location).users_with_role()
                ])
            ]
            data.append(datum)

        datatable = dict(header=[
            _('Course Name'),
            _('course_id'),
            _('# enrolled'),
            _('# staff'),
            _('instructors')
        ],
                         title=_('Enrollment information for all courses'),
                         data=data)
        context = {
            'datatable': datatable,
            'msg': self.msg,
            'djangopid': os.getpid(),
            'modeflag': {
                'staffing': 'active-section'
            },
            'mitx_version': getattr(settings, 'VERSION_STRING', ''),
        }
        return render_to_response(self.template_name, context)
Exemplo n.º 5
0
 def course(self, create, extracted, **kwargs):
     if extracted is None:
         raise ValueError(
             "Must specify a course location for a course instructor user")
     CourseInstructorRole(extracted).add_users(self)
Exemplo n.º 6
0
    def get(self, request, *args, **kwargs):
        """Shows logs of imports that happened as a result of a git import"""

        course_id = kwargs.get('course_id')

        # Set mongodb defaults even if it isn't defined in settings
        mongo_db = {
            'host': 'localhost',
            'user': '',
            'password': '',
            'db': 'xlog',
        }

        # Allow overrides
        if hasattr(settings, 'MONGODB_LOG'):
            for config_item in [
                    'host',
                    'user',
                    'password',
                    'db',
            ]:
                mongo_db[config_item] = settings.MONGODB_LOG.get(
                    config_item, mongo_db[config_item])

        mongouri = 'mongodb://{user}:{password}@{host}/{db}'.format(**mongo_db)

        error_msg = ''

        try:
            if mongo_db['user'] and mongo_db['password']:
                mdb = mongoengine.connect(mongo_db['db'], host=mongouri)
            else:
                mdb = mongoengine.connect(mongo_db['db'],
                                          host=mongo_db['host'])
        except mongoengine.connection.ConnectionError:
            logging.exception('Unable to connect to mongodb to save log, '
                              'please check MONGODB_LOG settings.')

        if course_id is None:
            # Require staff if not going to specific course
            if not request.user.is_staff:
                raise Http404
            cilset = CourseImportLog.objects.all().order_by('-created')
        else:
            try:
                course = get_course_by_id(course_id)
            except Exception:  # pylint: disable=broad-except
                cilset = None
                error_msg = _('Cannot find course {0}').format(course_id)

            # Allow only course team, instructors, and staff
            if not (request.user.is_staff or CourseInstructorRole(
                    course.location).has_user(request.user) or CourseStaffRole(
                        course.location).has_user(request.user)):
                raise Http404
            log.debug('course_id={0}'.format(course_id))
            cilset = CourseImportLog.objects.filter(
                course_id=course_id).order_by('-created')
            log.debug('cilset length={0}'.format(len(cilset)))
        mdb.disconnect()
        context = {
            'cilset': cilset,
            'course_id': course_id,
            'error_msg': error_msg
        }

        return render_to_response(self.template_name, context)