コード例 #1
0
ファイル: tasks.py プロジェクト: mf1389004071/edx-platform
def sync_cohort_with_mode(course_id, user_id, verified_cohort_name):
    """
    If the learner's mode does not match their assigned cohort, move the learner into the correct cohort.
    It is assumed that this task is only initiated for courses that are using the
    Automatic Verified Track Cohorting MVP feature. It is also assumed that before
    initiating this task, verification has been done to ensure that the course is
    cohorted and has an appropriately named "verified" cohort.
    """
    course_key = CourseKey.from_string(course_id)
    user = User.objects.get(id=user_id)
    enrollment = CourseEnrollment.get_enrollment(user, course_key)
    # Note that this will enroll the user in the default cohort on initial enrollment.
    # That's good because it will force creation of the default cohort if necessary.
    current_cohort = get_cohort(user, course_key)
    verified_cohort = get_cohort_by_name(course_key, verified_cohort_name)

    if enrollment.mode == CourseMode.VERIFIED and (current_cohort.id != verified_cohort.id):
        LOGGER.info(
            "MOVING_TO_VERIFIED: Moving user '%s' to the verified cohort for course '%s'", user.username, course_id
        )
        add_user_to_cohort(verified_cohort, user.username)
    elif enrollment.mode != CourseMode.VERIFIED and current_cohort.id == verified_cohort.id:
        LOGGER.info(
            "MOVING_TO_DEFAULT: Moving user '%s' to the default cohort for course '%s'", user.username, course_id
        )
        default_cohort = get_cohort_by_name(course_key, DEFAULT_COHORT_NAME)
        add_user_to_cohort(default_cohort, user.username)
    else:
        LOGGER.info(
            "NO_ACTION_NECESSARY: No action necessary for user '%s' in course '%s' and enrollment mode '%s'",
            user.username, course_id, enrollment.mode
        )
コード例 #2
0
ファイル: tasks.py プロジェクト: bryanlandia/edx-platform
def sync_cohort_with_mode(self, course_id, user_id, verified_cohort_name, default_cohort_name):
    """
    If the learner's mode does not match their assigned cohort, move the learner into the correct cohort.
    It is assumed that this task is only initiated for courses that are using the
    Automatic Verified Track Cohorting MVP feature. It is also assumed that before
    initiating this task, verification has been done to ensure that the course is
    cohorted and has an appropriately named "verified" cohort.
    """
    course_key = CourseKey.from_string(course_id)
    user = User.objects.get(id=user_id)
    try:
        enrollment = CourseEnrollment.get_enrollment(user, course_key)
        # Note that this will enroll the user in the default cohort on initial enrollment.
        # That's good because it will force creation of the default cohort if necessary.
        try:
            current_cohort = get_cohort(user, course_key)
        except IntegrityError as integrity_error:
            # It is quite common that get_cohort will throw an IntegrityError. This happens
            # when 2 celery workers are both handling enrollment change events for the same user
            # (for example, if the enrollment mode goes from None -> Audit -> Honor); if the user
            # was not previously in a cohort, calling get_cohort will result in a cohort assignment.
            LOGGER.info(
                "HANDLING_INTEGRITY_ERROR: IntegrityError encountered for course '%s' and user '%s': %s",
                course_id, user.id, unicode(integrity_error)
            )
            current_cohort = get_cohort(user, course_key)

        verified_cohort = get_cohort_by_name(course_key, verified_cohort_name)

        if enrollment.mode == CourseMode.VERIFIED and (current_cohort.id != verified_cohort.id):
            LOGGER.info(
                "MOVING_TO_VERIFIED: Moving user '%s' to the verified cohort '%s' for course '%s'",
                user.id, verified_cohort.name, course_id
            )
            add_user_to_cohort(verified_cohort, user.username)
        elif enrollment.mode != CourseMode.VERIFIED and current_cohort.id == verified_cohort.id:
            default_cohort = get_cohort_by_name(course_key, default_cohort_name)
            LOGGER.info(
                "MOVING_TO_DEFAULT: Moving user '%s' to the default cohort '%s' for course '%s'",
                user.id, default_cohort.name, course_id
            )
            add_user_to_cohort(default_cohort, user.username)
        else:
            LOGGER.info(
                "NO_ACTION_NECESSARY: No action necessary for user '%s' in course '%s' and enrollment mode '%s'. "
                "The user is already in cohort '%s'.",
                user.id, course_id, enrollment.mode, current_cohort.name
            )
    except Exception as exc:
        LOGGER.warning(
            "SYNC_COHORT_WITH_MODE_RETRY: Exception encountered for course '%s' and user '%s': %s",
            course_id, user.id, unicode(exc)
        )
        raise self.retry(exc=exc)
コード例 #3
0
    def test_post_cohortmembership_fix(self):
        """
        Test that changes made *after* migration, but *before* turning on new code are handled properly
        """
        # First, we're going to simulate some problem states that can arise during this window
        config_course_cohorts(self.course1, is_cohorted=True, auto_cohorts=["Course1AutoGroup1", "Course1AutoGroup2"])

        # Get the cohorts from the courses, which will cause auto cohorts to be created
        cohort_handler(self.request, unicode(self.course1.id))
        course_1_auto_cohort_1 = get_cohort_by_name(self.course1.id, "Course1AutoGroup1")
        course_1_auto_cohort_2 = get_cohort_by_name(self.course1.id, "Course1AutoGroup2")

        # When migrations were first run, the users were assigned to CohortMemberships correctly
        membership1 = CohortMembership(
            course_id=course_1_auto_cohort_1.course_id,
            user=self.user1,
            course_user_group=course_1_auto_cohort_1
        )
        membership1.save()
        membership2 = CohortMembership(
            course_id=course_1_auto_cohort_1.course_id,
            user=self.user2,
            course_user_group=course_1_auto_cohort_1
        )
        membership2.save()

        # But before CohortMembership code was turned on, some changes were made:
        course_1_auto_cohort_2.users.add(self.user1)  # user1 is now in 2 cohorts in the same course!
        course_1_auto_cohort_2.users.add(self.user2)
        course_1_auto_cohort_1.users.remove(self.user2)  # and user2 was moved, but no one told CohortMembership!

        # run the post-CohortMembership command, dry-run
        call_command('post_cohort_membership_fix')

        # Verify nothing was changed in dry-run mode.
        self.assertEqual(self.user1.course_groups.count(), 2)  # CourseUserGroup has 2 entries for user1

        self.assertEqual(CohortMembership.objects.get(user=self.user2).course_user_group.name, 'Course1AutoGroup1')
        user2_cohorts = list(self.user2.course_groups.values_list('name', flat=True))
        self.assertEqual(user2_cohorts, ['Course1AutoGroup2'])  # CourseUserGroup and CohortMembership disagree

        # run the post-CohortMembership command, and commit it
        call_command('post_cohort_membership_fix', commit='commit')

        # verify that both databases agree about the (corrected) state of the memberships
        self.assertEqual(self.user1.course_groups.count(), 1)
        self.assertEqual(CohortMembership.objects.filter(user=self.user1).count(), 1)

        self.assertEqual(self.user2.course_groups.count(), 1)
        self.assertEqual(CohortMembership.objects.filter(user=self.user2).count(), 1)
        self.assertEqual(CohortMembership.objects.get(user=self.user2).course_user_group.name, 'Course1AutoGroup2')
        user2_cohorts = list(self.user2.course_groups.values_list('name', flat=True))
        self.assertEqual(user2_cohorts, ['Course1AutoGroup2'])
コード例 #4
0
    def test_users_with_multiple_cohorts_cleanup(self):
        """
        Test that user which have been added in multiple cohorts of a course,
        can get cohorts without error after running cohorts cleanup command
        """
        # set two auto_cohort_groups for both courses
        config_course_cohorts(
            self.course1, [], cohorted=True, auto_cohort_groups=["Course1AutoGroup1", "Course1AutoGroup2"]
        )
        config_course_cohorts(
            self.course2, [], cohorted=True, auto_cohort_groups=["Course2AutoGroup1", "Course2AutoGroup2"]
        )

        # get the cohorts from the courses, which will cause auto cohorts to be created
        cohort_handler(self.request, unicode(self.course1.id))
        cohort_handler(self.request, unicode(self.course2.id))
        course_1_auto_cohort_1 = get_cohort_by_name(self.course1.id, "Course1AutoGroup1")
        course_1_auto_cohort_2 = get_cohort_by_name(self.course1.id, "Course1AutoGroup2")
        course_2_auto_cohort_1 = get_cohort_by_name(self.course2.id, "Course2AutoGroup1")

        # forcefully add user1 in two auto cohorts
        course_1_auto_cohort_1.users.add(self.user1)
        course_1_auto_cohort_2.users.add(self.user1)
        # forcefully add user2 in auto cohorts of both courses
        course_1_auto_cohort_1.users.add(self.user2)
        course_2_auto_cohort_1.users.add(self.user2)

        # now check that when user1 goes on discussion page and tries to get
        # cohorts 'MultipleObjectsReturned' exception is returned
        with self.assertRaises(MultipleObjectsReturned):
            get_cohort(self.user1, self.course1.id)
        # also check that user 2 can go on discussion page of both courses
        # without any exception
        get_cohort(self.user2, self.course1.id)
        get_cohort(self.user2, self.course2.id)

        # call command to remove users added in multiple cohorts of a course
        # are removed from all cohort groups
        call_command('remove_users_from_multiple_cohorts')

        # check that only user1 (with multiple cohorts) is removed from cohorts
        # and user2 is still in auto cohorts of both course after running
        # 'remove_users_from_multiple_cohorts' management command
        self.assertEqual(self.user1.course_groups.count(), 0)
        self.assertEqual(self.user2.course_groups.count(), 2)
        user2_cohorts = list(self.user2.course_groups.values_list('name', flat=True))
        self.assertEqual(user2_cohorts, ['Course1AutoGroup1', 'Course2AutoGroup1'])

        # now check that user1 can get cohorts in which he is added
        response = cohort_handler(self.request, unicode(self.course1.id))
        self.assertEqual(response.status_code, 200)
    def test_workgroups_users_post_with_cohort_backfill(self, store):
        self._create_course(store)
        """
        This test asserts a case where a workgroup was created before the existence of a cohorted discussion
        """
        data = {
            'name': self.test_workgroup_name,
            'project': self.test_project.id
        }
        response = self.do_post(self.test_workgroups_uri, data)
        self.assertEqual(response.status_code, 201)
        test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id']))
        users_uri = '{}users/'.format(test_uri)
        data = {"id": self.test_user.id}
        response = self.do_post(users_uri, data)
        self.assertEqual(response.status_code, 201)
        response = self.do_get(test_uri)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['users'][0]['id'], self.test_user.id)

        cohort_name = Workgroup.cohort_name_for_workgroup(
            self.test_project.id,
            response.data['id'],
            self.test_workgroup_name
        )

        # now let's remove existing cohort users
        cohort = get_cohort_by_name(self.test_course.id, cohort_name)
        self.assertTrue(is_user_in_cohort(cohort, self.test_user.id))

        remove_user_from_cohort(cohort, self.test_user.username)
        self.assertFalse(is_user_in_cohort(cohort, self.test_user.id))

        # delete cohort
        delete_empty_cohort(self.test_course.id, cohort_name)
        self.assertEqual(0, len(get_course_cohort_names(self.test_course.id)))

        # add a 2nd user and make sure a discussion cohort was created and users were backfilled
        test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id']))
        users_uri = '{}users/'.format(test_uri)
        data = {"id": self.test_user2.id}
        response = self.do_post(users_uri, data)
        self.assertEqual(response.status_code, 201)

        # now inspect cohort and assert that things are as we anticipate (i.e. both users are in there)
        cohort = get_cohort_by_name(self.test_course.id, cohort_name)
        self.assertIsNotNone(cohort)
        self.assertTrue(is_user_in_cohort(cohort, self.test_user.id))
        self.assertTrue(is_user_in_cohort(cohort, self.test_user2.id))
コード例 #6
0
ファイル: test_workgroups.py プロジェクト: kotky/edx-platform
    def test_workgroups_users_post(self):
        data = {
            'name': self.test_workgroup_name,
            'project': self.test_project.id
        }
        response = self.do_post(self.test_workgroups_uri, data)
        self.assertEqual(response.status_code, 201)
        test_uri = '{}{}/'.format(self.test_workgroups_uri, str(response.data['id']))
        users_uri = '{}users/'.format(test_uri)
        data = {"id": self.test_user.id}
        response = self.do_post(users_uri, data)
        self.assertEqual(response.status_code, 201)
        response = self.do_get(test_uri)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data['users'][0]['id'], self.test_user.id)

        # make sure a discussion cohort was created
        cohort_name = Workgroup.cohort_name_for_workgroup(
            self.test_project.id,
            response.data['id'],
            self.test_workgroup_name
        )
        cohort = get_cohort_by_name(self.test_course.id, cohort_name)
        self.assertIsNotNone(cohort)
        self.assertTrue(is_user_in_cohort(cohort, self.test_user.id))
コード例 #7
0
ファイル: test_workgroups.py プロジェクト: kotky/edx-platform
    def test_workgroups_list_post(self):
        data = {
            'name': self.test_workgroup_name,
            'project': self.test_project.id
        }
        response = self.do_post(self.test_workgroups_uri, data)
        self.assertEqual(response.status_code, 201)
        self.assertGreater(response.data['id'], 0)
        confirm_uri = '{}{}{}/'.format(
            self.test_server_prefix,
            self.test_workgroups_uri,
            str(response.data['id'])
        )
        self.assertEqual(response.data['url'], confirm_uri)
        self.assertGreater(response.data['id'], 0)
        self.assertEqual(response.data['name'], self.test_workgroup_name)
        self.assertEqual(response.data['project'], self.test_project.id)
        self.assertIsNotNone(response.data['users'])
        self.assertIsNotNone(response.data['groups'])
        self.assertIsNotNone(response.data['submissions'])
        self.assertIsNotNone(response.data['workgroup_reviews'])
        self.assertIsNotNone(response.data['peer_reviews'])
        self.assertIsNotNone(response.data['created'])
        self.assertIsNotNone(response.data['modified'])

        # make sure a discussion cohort was created
        cohort_name = Workgroup.cohort_name_for_workgroup(
            self.test_project.id,
            response.data['id'],
            self.test_workgroup_name
        )
        cohort = get_cohort_by_name(self.test_course.id, cohort_name)
        self.assertIsNotNone(cohort)
コード例 #8
0
ファイル: tasks.py プロジェクト: edx/edx-platform
def sync_cohort_with_mode(self, course_id, user_id, verified_cohort_name, default_cohort_name):
    """
    If the learner's mode does not match their assigned cohort, move the learner into the correct cohort.
    It is assumed that this task is only initiated for courses that are using the
    Automatic Verified Track Cohorting MVP feature. It is also assumed that before
    initiating this task, verification has been done to ensure that the course is
    cohorted and has an appropriately named "verified" cohort.
    """
    course_key = CourseKey.from_string(course_id)
    user = User.objects.get(id=user_id)
    try:
        enrollment = CourseEnrollment.get_enrollment(user, course_key)
        # Note that this will enroll the user in the default cohort on initial enrollment.
        # That's good because it will force creation of the default cohort if necessary.
        current_cohort = get_cohort(user, course_key)

        verified_cohort = get_cohort_by_name(course_key, verified_cohort_name)

        acceptable_modes = {CourseMode.VERIFIED, CourseMode.CREDIT_MODE}
        if enrollment.mode in acceptable_modes and (current_cohort.id != verified_cohort.id):
            LOGGER.info(
                u"MOVING_TO_VERIFIED: Moving user '%s' to the verified cohort '%s' for course '%s'",
                user.id, verified_cohort.name, course_id
            )
            add_user_to_cohort(verified_cohort, user.username)
        elif enrollment.mode not in acceptable_modes and current_cohort.id == verified_cohort.id:
            default_cohort = get_cohort_by_name(course_key, default_cohort_name)
            LOGGER.info(
                u"MOVING_TO_DEFAULT: Moving user '%s' to the default cohort '%s' for course '%s'",
                user.id, default_cohort.name, course_id
            )
            add_user_to_cohort(default_cohort, user.username)
        else:
            LOGGER.info(
                u"NO_ACTION_NECESSARY: No action necessary for user '%s' in course '%s' and enrollment mode '%s'. "
                u"The user is already in cohort '%s'.",
                user.id, course_id, enrollment.mode, current_cohort.name
            )
    except Exception as exc:
        LOGGER.warning(
            u"SYNC_COHORT_WITH_MODE_RETRY: Exception encountered for course '%s' and user '%s': %s",
            course_id, user.id, six.text_type(exc)
        )
        raise self.retry(exc=exc)
コード例 #9
0
ファイル: views.py プロジェクト: digitalsatori/edx-platform
    def post(self, request):
        serializer = BulkEnrollmentSerializer(data=request.data)
        if serializer.is_valid():
            # Setting the content type to be form data makes Django Rest Framework v3.6.3 treat all passed JSON data as
            # POST parameters. This is necessary because this request is forwarded on to the student_update_enrollment
            # view, which requires all of the parameters to be passed in via POST parameters.
            metadata = request._request.META  # pylint: disable=protected-access
            metadata['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'

            response_dict = {
                'auto_enroll': serializer.data.get('auto_enroll'),
                'email_students': serializer.data.get('email_students'),
                'action': serializer.data.get('action'),
                'courses': {}
            }
            for course_id, cohort_name in itertools.izip_longest(serializer.data.get('courses'),
                                                                 serializer.data.get('cohorts', [])):
                response = students_update_enrollment(self.request, course_id=course_id)
                response_content = json.loads(response.content)

                if cohort_name:
                    try:
                        course_key = CourseKey.from_string(course_id)
                        cohort = get_cohort_by_name(course_key=course_key, name=cohort_name)
                    except (CourseUserGroup.DoesNotExist, InvalidKeyError) as exc:
                        return Response(exc.message, status=status.HTTP_400_BAD_REQUEST)

                    for user_data in response_content['results']:
                        if "after" in user_data and (
                            user_data["after"].get("enrollment", False) is True or
                            user_data["after"].get("allowed", False) is True
                        ):
                            user_id = user_data['identifier']
                            try:
                                _user_obj, previous_cohort, _pre_assigned = add_user_to_cohort(cohort, user_id)
                            except ValueError:
                                # User already present in cohort
                                previous_cohort = cohort_name

                            if previous_cohort:
                                user_data['before']['cohort'] = previous_cohort
                            else:
                                user_data['before']['cohort'] = None
                            user_data['after']['cohort'] = cohort_name

                response_dict['courses'][course_id] = response_content
            return Response(data=response_dict, status=status.HTTP_200_OK)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
コード例 #10
0
ファイル: views.py プロジェクト: azizur77/api-integration
    def _enroll_user(self, data, errors):
        """Enroll user in a course and add him to a cohort."""
        user = data.get('user_object')
        email = user.email
        roles = data.get('roles', {})
        ignore_roles = data.get('ignore_roles', [])
        permissions = data.get('permissions', {})
        status = data.get('status', '').lower()
        course = data.get('course')
        course_key = data.get('course_key')

        # Enroll in course.
        try:
            CourseEnrollment.enroll(user, course_key)
        except IntegrityError:
            # If the enrollment already exists, it's possible we weren't able to add to the cohort yet,
            # so ignore the error and continue.
            pass

        cohort = get_cohort_by_name(course_key,
                                    CourseUserGroup.default_cohort_name)

        try:
            CohortMembership.objects.create(course_user_group=cohort,
                                            user=user)
        except IntegrityError:
            # This situation can occur if user is already present in the course or if his enrollment was removed
            # manually from Django Admin. We can ignore this error.
            pass

        # Assign role and permission in course.
        try:
            if status != "participant":
                # Add role.
                role = roles[status]
                if role not in ignore_roles:
                    _manage_role(course, user, role, 'allow')

                # Add permission for role.
                permission = permissions[role]
                permission_groups = Group.objects.get(
                    groupprofile__name=permission)
                permission_groups.user_set.add(user.id)
        except Exception as exc:
            self._add_error(errors, str(exc.message),
                            _("Setting Participant's Status"), email)
コード例 #11
0
ファイル: utils.py プロジェクト: openfun/fun-apps
def register_user_verified_cohort(user, order):
    """
    Once a user has been verified, add it to a cohort.

    The cohort to which the user should be added is given by the VERIFIED_COHORTS setting.
    settings.VERIFIED_COHORTS is a list of (r"<course id regex>", "<cohort name>") tuples. Regular expressions
    are matched agains the course ID. If at least one regular expression matches, registered users from this
    course are added to the cohort with the highest priority. Cohorts are sorted by decreasing priority.

    If a course is associated to a cohort that doesn't exist or an empty cohort name, then the user is not
    added to any cohort. Thus, to disable this feature for a specific course, set:

        VERIFIED_COHORTS = [
            ...
            (r"<course id>", None),
            ...
        ]

    To enable this feature for a particular course, but not for all others, write:

        VERIFIED_COHORTS = [
            (r"<course id>", "cohort name"),
            (r".*", None),
        ]

    To disable this feature globally, set:

        VERIFIED_COHORTS = []
    """
    course = get_course(order)
    verified_cohort_name = None
    for course_id_regex, cohort_name in getattr(settings, "VERIFIED_COHORTS",
                                                []):
        if re.match(course_id_regex, course.key):
            verified_cohort_name = cohort_name
            break
    cohort = None
    if verified_cohort_name:
        course_key = CourseKey.from_string(course.key)
        try:
            cohort = get_cohort_by_name(course_key, verified_cohort_name)
        except CourseUserGroup.DoesNotExist:
            pass
    if cohort:
        # This will also trigger the edx.cohort.user_add_requested event
        add_user_to_cohort(cohort, user.email)
コード例 #12
0
ファイル: models.py プロジェクト: zhiyuanbuqiID/edx-platform
    def ensure_valid_cohort(cls, cohort_name, course_id):
        """
        Ensures cohort_name is a valid cohort for course_id.

        Returns the cohort if valid, raises an error otherwise.
        """
        if cohort_name is None:
            raise ValueError(
                "Cannot create a CohortTarget without specifying a cohort_name."
            )
        try:
            cohort = get_cohort_by_name(name=cohort_name, course_key=course_id)
        except CourseUserGroup.DoesNotExist:
            raise ValueError(
                "Cohort {cohort} does not exist in course {course_id}".format(
                    cohort=cohort_name, course_id=course_id))
        return cohort
コード例 #13
0
ファイル: models.py プロジェクト: Lektorium-LLC/edx-platform
    def ensure_valid_cohort(cls, cohort_name, course_id):
        """
        Ensures cohort_name is a valid cohort for course_id.

        Returns the cohort if valid, raises an error otherwise.
        """
        if cohort_name is None:
            raise ValueError("Cannot create a CohortTarget without specifying a cohort_name.")
        try:
            cohort = get_cohort_by_name(name=cohort_name, course_key=course_id)
        except CourseUserGroup.DoesNotExist:
            raise ValueError(
                "Cohort {cohort} does not exist in course {course_id}".format(
                    cohort=cohort_name,
                    course_id=course_id
                )
            )
        return cohort
コード例 #14
0
    def post(self, request):
        """
        Enrolls the list of users in a verified course mode.
        """
        # Get the users, Course ID, and Mode from the request.

        users = request.data.get('users', [])

        if len(users) == 0:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Users must be specified to create a new enrollment."}
            )

        course_id = request.data.get('course_details', {}).get('course_id')

        if not course_id:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Course ID must be specified to create a new enrollment."}
            )

        try:
            course_key = CourseKey.from_string(course_id)
        except InvalidKeyError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)}
            )

        # use verified course mode by default
        mode = request.data.get('mode', CourseMode.VERIFIED)

        bad_users = []
        list_users = []
        for username in users:
            try:
                user = User.objects.get(username=username)
                list_users.append(user)
            except ObjectDoesNotExist:
                bad_users.append(username)

        if len(bad_users) > 0:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={'message': u'Users: {} does not exist.'.format(', '.join(bad_users))}
            )

        for user in list_users:
            embargo_response = embargo_api.get_embargo_response(request, course_key, user)

            if embargo_response:
                return embargo_response

        current_username = None
        try:
            is_active = request.data.get('is_active')
            # Check if the requested activation status is None or a Boolean
            if is_active is not None and not isinstance(is_active, bool):
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={'message': u"'{value}' is an invalid enrollment activation status.".format(value=is_active)}
                )

            enrollment_attributes = request.data.get('enrollment_attributes')
            errors = False
            already_paid = []  # list of users with verified enrollment
            not_enrolled = []  # list of not enrolled yet or unenrolled users
            for username in users:
                current_username = username
                enrollment = api.get_enrollment(username, unicode(course_key))
                if not enrollment:
                    not_enrolled.append(username)
                elif enrollment['is_active'] is not True:
                    not_enrolled.append(username)
                elif enrollment['mode'] == CourseMode.VERIFIED:
                    already_paid.append(username)
            msg_paid = u""
            msg_not_enrolled = u""
            if len(already_paid) > 0:
                msg_paid = u'Users: {} already paid for course.'.format(', '.join(already_paid))
                errors = True
            if len(not_enrolled) > 0:
                msg_not_enrolled = u'Users: {} not enrolled for course.'.format(', '.join(not_enrolled))
                errors = True
            if errors:
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={"message": (u"'{course_id}'\n:{msg_paid}\n{msg_not_enrolled}").format(
                        course_id=course_id,
                        msg_paid=msg_paid,
                        msg_not_enrolled=msg_not_enrolled
                    ),
                    })

            # update for cohorts
            cohort_exists = is_cohort_exists(course_key, VERIFIED)
            if not cohort_exists:
                cohort = add_cohort(course_key, VERIFIED, 'manual')
            else:
                cohort = get_cohort_by_name(course_key, VERIFIED)

            for username in users:
                current_username = username
                api.update_enrollment(username, unicode(course_key), mode=mode, is_active=is_active)
                user = User.objects.get(username=username)
                course_cohorts = CourseUserGroup.objects.filter(
                    course_id=cohort.course_id,
                    users__id=user.id,
                    group_type=CourseUserGroup.COHORT
                )

                add_user_into_verified_cohort(course_cohorts, cohort, user)

            email_opt_in = request.data.get('email_opt_in', None)
            if email_opt_in is not None:
                org = course_key.org
                for username in users:
                    update_email_opt_in(username, org, email_opt_in)

            return Response(
                status=status.HTTP_200_OK,
                data={
                    "message": u"Success for course '{course_id}'.".format(course_id=course_id)
                })
        except CourseModeNotFoundError as error:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"The course mode '{mode}' is not available for course '{course_id}'."
                    ).format(mode="verified", course_id=course_id),
                    "course_details": error.data
                })
        except CourseEnrollmentExistsError as error:
            return Response(data=error.enrollment)
        except CourseEnrollmentError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"An error occurred while creating the new course enrollment for user "
                        u"'{username}' in course '{course_id}'"
                    ).format(username=current_username, course_id=course_id)
                }
            )
コード例 #15
0
ファイル: data.py プロジェクト: urfu-online/itoo-api
def to_paid_track(userlike_str,
                  course_id,
                  verified_cohort_name="verified",
                  default_cohort_name="default",
                  mode_slug="verified"):
    course_key = CourseKey.from_string(course_id)
    user = User.objects.get(email=userlike_str)
    course = get_course_by_id(course_key)
    acceptable_modes = ('verified', 'professional')

    def _check_user():
        """
        Различные проверки пользовательского аккаунта
        :return: bool
        """
        return user.is_active

    def _check_verified_course_mode():
        course_modes = CourseMode.objects.filter(
            course_id=course_key, mode_slug__in=acceptable_modes)
        return course_modes

    def _set_user_mode():
        available_verified_modes = _check_verified_course_mode()
        for mode in available_verified_modes:
            if mode.mode_slug == mode_slug:
                update_enrollment(user.username, course_id, mode_slug)
                return True
        return False

        #
        # if not mode:
        #     mode = available_verified_modes[0]
        #
        # if mode in available_verified_modes:
        #     update_enrollment(user.username, course_id, mode)
        # elif mode not in available_verified_modes:
        #     raise CourseModeNotFoundError

    def _get_verified_cohort():
        if not is_course_cohorted(course_key):
            logger.error(u"COURSE_NOT_COHORTED: Course '%s' is not cohorted",
                         course_id)
            set_course_cohorted(course_key, cohorted)

        existing_manual_cohorts = get_course_cohorts(
            course, assignment_type=CourseCohort.MANUAL)
        logger.info(u"Cohorts on course '%s' '%s'", course_id,
                    existing_manual_cohorts)

        return existing_manual_cohorts[0]
        # if verified_cohort_name:  # алгоритм с одной платной когортой
        #     if not verified_cohort_name in existing_manual_cohorts:
        #         # Создадём когорту и группу контента
        #         cohort = CourseCohort.create(cohort_name=verified_cohort_name, course_id=course_key,
        #                                      assignment_type=CourseCohort.MANUAL)
        #         return cohort
        # else:
        #     """
        #     Место для алгоритма с привязкой когорты к треку и многими треками
        #     """
        #     pass

    def _set_user_cohort():
        cohort = _get_verified_cohort()
        try:
            add_user_to_cohort(cohort, user.username)
        except:
            pass

    def _verify_user():
        if not SoftwareSecurePhotoVerification.user_is_verified(user):
            obj = SoftwareSecurePhotoVerification(
                user=user, photo_id_key="dummy_photo_id_key")
            obj.status = 'approved'
            obj.submitted_at = datetime.datetime.now()
            obj.reviewing_user = User.objects.get(username='******')
            obj.save()

    enrollment = None
    try:
        enrollment = CourseEnrollment.get_enrollment(user, course_key)
    except CourseEnrollmentError:
        return "user is not enrolled"

    if enrollment:
        return str(_set_user_mode()), str(_set_user_cohort()), str(
            _verify_user())

        # def _check_enrollment(self, user, course_key):
        #     enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(user, course_key)
        #
        #     if enrollment_mode is not None and is_active:
        #         all_modes = CourseMode.modes_for_course_dict(course_key, include_expired=True)
        #         course_mode = all_modes.get(enrollment_mode)
        #         has_paid = (course_mode and course_mode.min_price > 0)
        #
        #     return (has_paid, bool(is_active))

        # try:
        enrollment = CourseEnrollment.get_enrollment(user, course_key)
        # Note that this will enroll the user in the default cohort on initial enrollment.
        # That's good because it will force creation of the default cohort if necessary.
        current_cohort = get_cohort(user, course_key)
        verified_cohort = get_cohort_by_name(course_key, verified_cohort_name)
コード例 #16
0
    def post(self, request):
        """
        Enrolls the list of users in a verified course mode.
        """
        # Get the users, Course ID, and Mode from the request.

        users = request.DATA.get('users', [])

        if len(users) == 0:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Users must be specified to create a new enrollment."}
            )

        course_id = request.DATA.get('course_details', {}).get('course_id')

        if not course_id:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Course ID must be specified to create a new enrollment."}
            )

        try:
            course_key = CourseKey.from_string(course_id)
        except InvalidKeyError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)}
            )

        # use verified course mode by default
        mode = request.DATA.get('mode', CourseMode.VERIFIED)

        bad_users = []
        list_users = []
        for username in users:
            try:
                user = User.objects.get(username=username)
                list_users.append(user)
            except ObjectDoesNotExist:
                bad_users.append(username)

        if len(bad_users) > 0:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={'message': u'Users: {} does not exist.'.format(', '.join(bad_users))}
            )

        for user in list_users:
            embargo_response = embargo_api.get_embargo_response(request, course_key, user)

            if embargo_response:
                return embargo_response

        current_username = None
        try:
            is_active = request.DATA.get('is_active')
            # Check if the requested activation status is None or a Boolean
            if is_active is not None and not isinstance(is_active, bool):
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={'message': u"'{value}' is an invalid enrollment activation status.".format(value=is_active)}
                )

            enrollment_attributes = request.DATA.get('enrollment_attributes')
            errors = False
            already_paid = []  # list of users with verified enrollment
            not_enrolled = []  # list of not enrolled yet or unenrolled users
            for username in users:
                current_username = username
                enrollment = api.get_enrollment(username, unicode(course_key))
                if not enrollment:
                    not_enrolled.append(username)
                elif enrollment['is_active'] is not True:
                    not_enrolled.append(username)
                elif enrollment['mode'] == CourseMode.VERIFIED:
                    already_paid.append(username)
            msg_paid = u""
            msg_not_enrolled = u""
            if len(already_paid) > 0:
                msg_paid = u'Users: {} already paid for course.'.format(', '.join(already_paid))
                errors = True
            if len(not_enrolled) > 0:
                msg_not_enrolled = u'Users: {} not enrolled for course.'.format(', '.join(not_enrolled))
                errors = True
            if errors:
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={"message": (u"'{course_id}'\n:{msg_paid}\n{msg_not_enrolled}").format(
                        course_id=course_id,
                        msg_paid=msg_paid,
                        msg_not_enrolled=msg_not_enrolled
                    ),
                    })

            # update for cohorts
            cohort_exists = is_cohort_exists(course_key, VERIFIED)
            if not cohort_exists:
                cohort = add_cohort(course_key, VERIFIED, 'manual')
            else:
                cohort = get_cohort_by_name(course_key, VERIFIED)

            for username in users:
                current_username = username
                api.update_enrollment(username, unicode(course_key), mode=mode, is_active=is_active)
                user = User.objects.get(username=username)
                course_cohorts = CourseUserGroup.objects.filter(
                    course_id=cohort.course_id,
                    users__id=user.id,
                    group_type=CourseUserGroup.COHORT
                )

                add_user_into_verified_cohort(course_cohorts, cohort, user)

            email_opt_in = request.DATA.get('email_opt_in', None)
            if email_opt_in is not None:
                org = course_key.org
                for username in users:
                    update_email_opt_in(username, org, email_opt_in)

            return Response(
                status=status.HTTP_200_OK,
                data={
                    "message": u"Success for course '{course_id}'.".format(course_id=course_id)
                })
        except CourseModeNotFoundError as error:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"The course mode '{mode}' is not available for course '{course_id}'."
                    ).format(mode="verified", course_id=course_id),
                    "course_details": error.data
                })
        except CourseNotFoundError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
                }
            )
        except CourseEnrollmentExistsError as error:
            return Response(data=error.enrollment)
        except CourseEnrollmentError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"An error occurred while creating the new course enrollment for user "
                        u"'{username}' in course '{course_id}'"
                    ).format(username=current_username, course_id=course_id)
                }
            )
コード例 #17
0
ファイル: views.py プロジェクト: raccoongang/edx-platform
    def post(self, request):
        """Enrolls the currently logged-in user in a course.

        Server-to-server calls may deactivate or modify the mode of existing enrollments. All other requests
        go through `add_enrollment()`, which allows creation of new and reactivation of old enrollments.
        """
        # Get the User, Course ID, and Mode from the request.

        username = request.data.get('user', request.user.username)
        course_id = request.data.get('course_details', {}).get('course_id')

        if not course_id:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Course ID must be specified to create a new enrollment."}
            )

        try:
            course_id = CourseKey.from_string(course_id)
        except InvalidKeyError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
                }
            )

        mode = request.data.get('mode')

        has_api_key_permissions = self.has_api_key_permissions(request)

        # Check that the user specified is either the same user, or this is a server-to-server request.
        if not username:
            username = request.user.username
        if username != request.user.username and not has_api_key_permissions:
            # Return a 404 instead of a 403 (Unauthorized). If one user is looking up
            # other users, do not let them deduce the existence of an enrollment.
            return Response(status=status.HTTP_404_NOT_FOUND)

        if mode not in (CourseMode.AUDIT, CourseMode.HONOR, None) and not has_api_key_permissions:
            return Response(
                status=status.HTTP_403_FORBIDDEN,
                data={
                    "message": u"User does not have permission to create enrollment with mode [{mode}].".format(
                        mode=mode
                    )
                }
            )

        try:
            # Lookup the user, instead of using request.user, since request.user may not match the username POSTed.
            user = User.objects.get(username=username)
        except ObjectDoesNotExist:
            return Response(
                status=status.HTTP_406_NOT_ACCEPTABLE,
                data={
                    'message': u'The user {} does not exist.'.format(username)
                }
            )

        embargo_response = embargo_api.get_embargo_response(request, course_id, user)

        if embargo_response:
            return embargo_response

        try:
            is_active = request.data.get('is_active')
            # Check if the requested activation status is None or a Boolean
            if is_active is not None and not isinstance(is_active, bool):
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={
                        'message': (u"'{value}' is an invalid enrollment activation status.").format(value=is_active)
                    }
                )

            explicit_linked_enterprise = request.data.get('linked_enterprise_customer')
            if explicit_linked_enterprise and has_api_key_permissions and enterprise_enabled():
                enterprise_api_client = EnterpriseApiServiceClient()
                consent_client = ConsentApiServiceClient()
                try:
                    enterprise_api_client.post_enterprise_course_enrollment(username, unicode(course_id), None)
                except EnterpriseApiException as error:
                    log.exception("An unexpected error occurred while creating the new EnterpriseCourseEnrollment "
                                  "for user [%s] in course run [%s]", username, course_id)
                    raise CourseEnrollmentError(text_type(error))
                kwargs = {
                    'username': username,
                    'course_id': unicode(course_id),
                    'enterprise_customer_uuid': explicit_linked_enterprise,
                }
                consent_client.provide_consent(**kwargs)

            enrollment_attributes = request.data.get('enrollment_attributes')
            enrollment = api.get_enrollment(username, unicode(course_id))
            mode_changed = enrollment and mode is not None and enrollment['mode'] != mode
            active_changed = enrollment and is_active is not None and enrollment['is_active'] != is_active
            missing_attrs = []
            if enrollment_attributes:
                actual_attrs = [
                    u"{namespace}:{name}".format(**attr)
                    for attr in enrollment_attributes
                ]
                missing_attrs = set(REQUIRED_ATTRIBUTES.get(mode, [])) - set(actual_attrs)
            if has_api_key_permissions and (mode_changed or active_changed):
                if mode_changed and active_changed and not is_active:
                    # if the requester wanted to deactivate but specified the wrong mode, fail
                    # the request (on the assumption that the requester had outdated information
                    # about the currently active enrollment).
                    msg = u"Enrollment mode mismatch: active mode={}, requested mode={}. Won't deactivate.".format(
                        enrollment["mode"], mode
                    )
                    log.warning(msg)
                    return Response(status=status.HTTP_400_BAD_REQUEST, data={"message": msg})

                if len(missing_attrs) > 0:
                    msg = u"Missing enrollment attributes: requested mode={} required attributes={}".format(
                        mode, REQUIRED_ATTRIBUTES.get(mode)
                    )
                    log.warning(msg)
                    return Response(status=status.HTTP_400_BAD_REQUEST, data={"message": msg})

                response = api.update_enrollment(
                    username,
                    unicode(course_id),
                    mode=mode,
                    is_active=is_active,
                    enrollment_attributes=enrollment_attributes,
                    # If we are updating enrollment by authorized api caller, we should allow expired modes
                    include_expired=has_api_key_permissions
                )
            else:
                # Will reactivate inactive enrollments.
                response = api.add_enrollment(
                    username,
                    unicode(course_id),
                    mode=mode,
                    is_active=is_active,
                    enrollment_attributes=enrollment_attributes
                )

            cohort_name = request.data.get('cohort')
            if cohort_name is not None:
                cohort = get_cohort_by_name(course_id, cohort_name)
                try:
                    add_user_to_cohort(cohort, user)
                except ValueError:
                    # user already in cohort, probably because they were un-enrolled and re-enrolled
                    log.exception('Cohort re-addition')
            email_opt_in = request.data.get('email_opt_in', None)
            if email_opt_in is not None:
                org = course_id.org
                update_email_opt_in(request.user, org, email_opt_in)

            log.info('The user [%s] has already been enrolled in course run [%s].', username, course_id)
            return Response(response)
        except CourseModeNotFoundError as error:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"The [{mode}] course mode is expired or otherwise unavailable for course run [{course_id}]."
                    ).format(mode=mode, course_id=course_id),
                    "course_details": error.data
                })
        except CourseNotFoundError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
                }
            )
        except CourseEnrollmentExistsError as error:
            log.warning('An enrollment already exists for user [%s] in course run [%s].', username, course_id)
            return Response(data=error.enrollment)
        except CourseEnrollmentError:
            log.exception("An error occurred while creating the new course enrollment for user "
                          "[%s] in course run [%s]", username, course_id)
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"An error occurred while creating the new course enrollment for user "
                        u"'{username}' in course '{course_id}'"
                    ).format(username=username, course_id=course_id)
                }
            )
        except CourseUserGroup.DoesNotExist:
            log.exception('Missing cohort [%s] in course run [%s]', cohort_name, course_id)
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": "An error occured while adding to cohort [%s]" % cohort_name
                })
        finally:
            # Assumes that the ecommerce service uses an API key to authenticate.
            if has_api_key_permissions:
                current_enrollment = api.get_enrollment(username, unicode(course_id))
                audit_log(
                    'enrollment_change_requested',
                    course_id=unicode(course_id),
                    requested_mode=mode,
                    actual_mode=current_enrollment['mode'] if current_enrollment else None,
                    requested_activation=is_active,
                    actual_activation=current_enrollment['is_active'] if current_enrollment else None,
                    user_id=user.id
                )
コード例 #18
0
ファイル: views.py プロジェクト: askoric/edx-platform
    def users(self, request, pk):
        """
        Add a User to a Workgroup
        """
        if request.method == "GET":
            users = User.objects.filter(workgroups=pk)
            response_data = []
            if users:
                for user in users:
                    serializer = UserSerializer(user)
                    response_data.append(serializer.data)  # pylint: disable=E1101
            return Response(response_data, status=status.HTTP_200_OK)
        elif request.method == "POST":
            user_id = request.DATA.get("id")
            try:
                user = User.objects.get(id=user_id)
            except ObjectDoesNotExist:
                message = "User {} does not exist".format(user_id)
                return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)

            workgroup = self.get_object()

            # Ensure the user is not already assigned to a project for this course
            existing_projects = Project.objects.filter(course_id=workgroup.project.course_id).filter(
                workgroups__users__id=user.id
            )
            if len(existing_projects):
                message = "User {} already assigned to a project for this course".format(user_id)
                return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)

            try:
                workgroup.add_user(user)
            except ValidationError as e:
                return Response({"detail": unicode(e)}, status.HTTP_400_BAD_REQUEST)

            workgroup.save()

            # add user to the workgroup cohort, create it if it doesn't exist (for cases where there is a legacy
            # workgroup)
            course_descriptor, course_key, course_content = _get_course(
                self.request, user, workgroup.project.course_id
            )  # pylint: disable=W0612
            try:
                cohort = get_cohort_by_name(course_key, workgroup.cohort_name)
                add_user_to_cohort(cohort, user.username)
            except ObjectDoesNotExist:
                # This use case handles cases where a workgroup might have been created before
                # the notion of a cohorted discussion. So we need to backfill in the data
                assignment_type = request.DATA.get("assignment_type", CourseCohort.RANDOM)
                if assignment_type not in dict(CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys():
                    message = "Not a valid assignment type, '{}'".format(assignment_type)
                    return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)
                cohort = add_cohort(course_key, workgroup.cohort_name, assignment_type)
                for workgroup_user in workgroup.users.all():
                    add_user_to_cohort(cohort, workgroup_user.username)
            return Response({}, status=status.HTTP_201_CREATED)
        else:
            user_id = request.DATA.get("id")
            try:
                user = User.objects.get(id=user_id)
            except ObjectDoesNotExist:
                message = "User {} does not exist".format(user_id)
                return Response({"detail": message}, status.HTTP_400_BAD_REQUEST)
            workgroup = self.get_object()
            course_descriptor, course_key, course_content = _get_course(
                self.request, user, workgroup.project.course_id
            )  # pylint: disable=W0612
            cohort = get_cohort_by_name(course_key, workgroup.cohort_name)
            workgroup.remove_user(user)
            remove_user_from_cohort(cohort, user.username)
            return Response({}, status=status.HTTP_204_NO_CONTENT)
コード例 #19
0
    def test_post_cohortmembership_fix(self):
        """
        Test that changes made *after* migration, but *before* turning on new code are handled properly
        """
        # First, we're going to simulate some problem states that can arise during this window
        config_course_cohorts(
            self.course1,
            is_cohorted=True,
            auto_cohorts=["Course1AutoGroup1", "Course1AutoGroup2"])

        # Get the cohorts from the courses, which will cause auto cohorts to be created
        cohort_handler(self.request, unicode(self.course1.id))
        course_1_auto_cohort_1 = get_cohort_by_name(self.course1.id,
                                                    "Course1AutoGroup1")
        course_1_auto_cohort_2 = get_cohort_by_name(self.course1.id,
                                                    "Course1AutoGroup2")

        # When migrations were first run, the users were assigned to CohortMemberships correctly
        membership1 = CohortMembership(
            course_id=course_1_auto_cohort_1.course_id,
            user=self.user1,
            course_user_group=course_1_auto_cohort_1)
        membership1.save()
        membership2 = CohortMembership(
            course_id=course_1_auto_cohort_1.course_id,
            user=self.user2,
            course_user_group=course_1_auto_cohort_1)
        membership2.save()

        # But before CohortMembership code was turned on, some changes were made:
        course_1_auto_cohort_2.users.add(
            self.user1)  # user1 is now in 2 cohorts in the same course!
        course_1_auto_cohort_2.users.add(self.user2)
        course_1_auto_cohort_1.users.remove(
            self.user2
        )  # and user2 was moved, but no one told CohortMembership!

        # run the post-CohortMembership command, dry-run
        call_command('post_cohort_membership_fix')

        # Verify nothing was changed in dry-run mode.
        self.assertEqual(self.user1.course_groups.count(),
                         2)  # CourseUserGroup has 2 entries for user1

        self.assertEqual(
            CohortMembership.objects.get(
                user=self.user2).course_user_group.name, 'Course1AutoGroup1')
        user2_cohorts = list(
            self.user2.course_groups.values_list('name', flat=True))
        self.assertEqual(user2_cohorts,
                         ['Course1AutoGroup2'
                          ])  # CourseUserGroup and CohortMembership disagree

        # run the post-CohortMembership command, and commit it
        call_command('post_cohort_membership_fix', commit='commit')

        # verify that both databases agree about the (corrected) state of the memberships
        self.assertEqual(self.user1.course_groups.count(), 1)
        self.assertEqual(
            CohortMembership.objects.filter(user=self.user1).count(), 1)

        self.assertEqual(self.user2.course_groups.count(), 1)
        self.assertEqual(
            CohortMembership.objects.filter(user=self.user2).count(), 1)
        self.assertEqual(
            CohortMembership.objects.get(
                user=self.user2).course_user_group.name, 'Course1AutoGroup2')
        user2_cohorts = list(
            self.user2.course_groups.values_list('name', flat=True))
        self.assertEqual(user2_cohorts, ['Course1AutoGroup2'])
コード例 #20
0
    def post(self, request):
        username = request.DATA.get('username')
        try:
            user = User.objects.get(username=username)
        except ObjectDoesNotExist:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"User {username} does not exist".format(username=username)}
            )

        course_id = request.DATA.get('course_id')
        if not course_id:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Course ID must be specified to create a new enrollment."}
            )

        try:
            course_key = CourseKey.from_string(course_id)
        except InvalidKeyError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
                }
            )
        course_is_cohorted = is_course_cohorted(course_key)
        if not course_is_cohorted:
            return Response(
                status=status.HTTP_200_OK,
                data={"message": u"Course {course_id} is not cohorted.".format(course_id=course_id)}
            )

        action = request.DATA.get('action')
        if action not in [u'add', u'delete']:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Available actions are 'add' and 'delete'."}
            )

        cohort_exists = is_cohort_exists(course_key, VERIFIED)
        if not cohort_exists:
            if action == u'add':
                cohort = add_cohort(course_key, VERIFIED, 'manual')
            else:
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"There aren't cohort verified for {course_id}".format(course_id=course_id)}
                )
        else:
            cohort = get_cohort_by_name(course_key, VERIFIED)

        enrollment = CourseEnrollment.objects.get(
            user__username=username, course_id=course_key
        )
        if not enrollment or not enrollment.is_active:
            if action == u'add':
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={"message": u"User {username} not enrolled or unenrolled in course {course_id}.".format(
                        username=username,
                        course_id=course_id
                    )}
                )
            if action == u'delete':
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"User {username} not enrolled or unenrolled in course {course_id}.".format(
                        username=username,
                        course_id=course_id
                    )}
                )

        course_cohorts = CourseUserGroup.objects.filter(
            course_id=course_key,
            users__id=user.id,
            group_type=CourseUserGroup.COHORT
        )

        # remove user from verified cohort
        if action == u'delete':
            if not course_cohorts.exists() or course_cohorts[0].name != cohort.name:
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"User {username} already was removed from cohort {cohort_name}".format(
                        username=username,
                        cohort_name=cohort.name
                    )}
                )
            else:
                cohort.users.remove(user)
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"User {username} removed from cohort {cohort_name}".format(
                        username=username,
                        cohort_name=cohort.name
                    )}
                )

        if course_cohorts.exists():
            if course_cohorts[0] == cohort:
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"User {username} already present in cohort {cohort_name}".format(
                        username=username,
                        cohort_name=cohort.name
                    )}
                )

        add_user_into_verified_cohort(course_cohorts, cohort, user)

        return Response(
            status=status.HTTP_200_OK,
            data={"message": u"User {username} added to cohort {cohort_name}".format(
                username=user.username,
                cohort_name=cohort.name
            )}
        )
コード例 #21
0
    def handle(self, *args, **options):

        self.stdout.write('### Checking CourseUserGroup group types\n')
        error = False
        for course_group in CourseUserGroup.objects.all():
            if course_group.group_type != CourseUserGroup.COHORT:
                if options['fix']:
                    self.stdout.write(
                        'Fixed: CourseUserGroup with an invalid group_type found: {} (type: {})\n'
                        .format(course_group.name, course_group.group_type))
                    course_group.group_type = CourseUserGroup.COHORT
                    course_group.save()
                else:
                    error = True
                    self.stdout.write(
                        'CourseUserGroup with an invalid group_type found: {} (type: {})\n'
                        .format(course_group.name, course_group.group_type))

        if not error:
            self.stdout.write('Ok.\n')

        self.stdout.write('\n### Checking user cohorts\n')
        error = False
        users = User.objects.all()
        _courses = modulestore().get_courses()
        courses = [c for c in _courses if isinstance(c, CourseDescriptor)]
        # for each course, check if users are in atleast and only 1 cohort
        for course in courses:
            for user in users:
                if not CourseEnrollment.is_enrolled(user, course.id):
                    continue
                try:
                    CourseUserGroup.objects.get(course_id=course.id,
                                                users__id=user.id)
                except CourseUserGroup.DoesNotExist:
                    if options['fix']:
                        # create a "default_cohort" is it doesn't already exist
                        try:
                            default_cohort = get_cohort_by_name(
                                course.id, CourseUserGroup.default_cohort_name)
                        except CourseUserGroup.DoesNotExist:
                            default_cohort = add_cohort(
                                course.id, CourseUserGroup.default_cohort_name,
                                CourseCohort.RANDOM)
                            self.stdout.write(
                                'Default cohort "{}" created for course "{}"'.
                                format(default_cohort.name,
                                       course.display_name))
                        add_user_to_cohort(default_cohort, user.username)
                        self.stdout.write(
                            'Fixed: User "{}" is not in a cohort in course "{}". Added in "{}" cohort\n'
                            .format(user.username, course.display_name,
                                    default_cohort.name))
                    else:
                        error = True
                        self.stdout.write(
                            'User "{}" is not in a cohort in course "{}".\n'.
                            format(user.username, course.display_name))
                except MultipleObjectsReturned:
                    self.stdout.write(
                        'User "{}" is in multiple cohorts in course "{}".\n'.
                        format(user.username, course.display_name))
                    if options['fix']:
                        user_cohorts = CourseUserGroup.objects.filter(
                            course_id=course.id, users__id=user.id).all()
                        for cohort in user_cohorts[1:]:
                            remove_user_from_cohort(cohort, user.username)
                            self.stdout.write(
                                "User '{}' has been removed from cohort '{}' in course '{}'.\n"
                                .format(user.username, cohort.name,
                                        course.display_name))
                        self.stdout.write(
                            "User '{}' is now only in cohort '{}' in course '{}'.\n"
                            .format(
                                # pylint: disable=undefined-loop-variable
                                user.username,
                                cohort.name,
                                course.display_name))
                    else:
                        error = True

        if not error:
            self.stdout.write('Ok.\n')

        self.stdout.write(
            '\nTo fix issues, run the script with the "--fix" option.\n')
コード例 #22
0
    def handle(self, *args, **options):

        self.stdout.write('### Checking CourseUserGroup group types\n')
        error = False
        for course_group in CourseUserGroup.objects.all():
            if course_group.group_type != CourseUserGroup.COHORT:
                if options['fix']:
                    self.stdout.write(
                        'Fixed: CourseUserGroup with an invalid group_type found: {} (type: {})\n'.format(
                            course_group.name, course_group.group_type)
                    )
                    course_group.group_type = CourseUserGroup.COHORT
                    course_group.save()
                else:
                    error = True
                    self.stdout.write(
                        'CourseUserGroup with an invalid group_type found: {} (type: {})\n'.format(
                            course_group.name, course_group.group_type)
                    )

        if not error:
            self.stdout.write('Ok.\n')

        self.stdout.write('\n### Checking user cohorts\n')
        error = False
        users = User.objects.all()
        _courses = modulestore().get_courses()
        courses = [c for c in _courses if isinstance(c, CourseDescriptor)]
        # for each course, check if users are in atleast and only 1 cohort
        for course in courses:
            for user in users:
                if not CourseEnrollment.is_enrolled(user, course.id):
                    continue
                try:
                    CourseUserGroup.objects.get(course_id=course.id,
                                                users__id=user.id)
                except CourseUserGroup.DoesNotExist:
                    if options['fix']:
                        # create a "default_cohort" is it doesn't already exist
                        try:
                            default_cohort = get_cohort_by_name(course.id, CourseUserGroup.default_cohort_name)
                        except CourseUserGroup.DoesNotExist:
                            default_cohort = add_cohort(
                                course.id, CourseUserGroup.default_cohort_name, CourseCohort.RANDOM
                            )
                            self.stdout.write(
                                'Default cohort "{}" created for course "{}"'.format(
                                    default_cohort.name, course.display_name
                                )
                            )
                        add_user_to_cohort(default_cohort, user.username)
                        self.stdout.write(
                            'Fixed: User "{}" is not in a cohort in course "{}". Added in "{}" cohort\n'.format(
                                user.username, course.display_name, default_cohort.name)
                        )
                    else:
                        error = True
                        self.stdout.write(
                            'User "{}" is not in a cohort in course "{}".\n'.format(
                                user.username, course.display_name)
                        )
                except MultipleObjectsReturned:
                    self.stdout.write(
                        'User "{}" is in multiple cohorts in course "{}".\n'.format(
                            user.username, course.display_name)
                    )
                    if options['fix']:
                        user_cohorts = CourseUserGroup.objects.filter(course_id=course.id,
                                                                      users__id=user.id).all()
                        for cohort in user_cohorts[1:]:
                            remove_user_from_cohort(cohort, user.username)
                            self.stdout.write(
                                "User '{}' has been removed from cohort '{}' in course '{}'.\n".format(
                                    user.username, cohort.name, course.display_name
                                )
                            )
                        self.stdout.write(
                            "User '{}' is now only in cohort '{}' in course '{}'.\n".format(
                                # pylint: disable=undefined-loop-variable
                                user.username, cohort.name, course.display_name
                            )
                        )
                    else:
                        error = True

        if not error:
            self.stdout.write('Ok.\n')

        self.stdout.write('\nTo fix issues, run the script with the "--fix" option.\n')
コード例 #23
0
 def get_cohort_id(self, data, suffix=''):
     verified_cohort = get_cohort_by_name(self.course_id,
                                          data.get('selection'))
     self.selected_cohort_id = str(verified_cohort.id)
     return verified_cohort.id
コード例 #24
0
    def users(self, request, pk):
        """
        Add a User to a Workgroup
        """
        if request.method == 'GET':
            users = User.objects.filter(workgroups=pk)
            response_data = []
            if users:
                for user in users:
                    serializer = UserSerializer(user,
                                                context={'request': request})
                    response_data.append(serializer.data)  # pylint: disable=E1101
            return Response(response_data, status=status.HTTP_200_OK)
        elif request.method == 'POST':
            user_id = request.data.get('id')
            try:
                user = User.objects.get(id=user_id)
            except ObjectDoesNotExist:
                message = 'User {} does not exist'.format(user_id)
                return Response({"detail": message},
                                status.HTTP_400_BAD_REQUEST)

            workgroup = self.get_object()

            # Ensure the user is not already assigned to a project for this course
            existing_projects = Project.objects.filter(
                course_id=workgroup.project.course_id).filter(
                    workgroups__users__id=user.id)
            if len(existing_projects):
                message = 'User {} already assigned to a project for this course'.format(
                    user_id)
                return Response({"detail": message},
                                status.HTTP_400_BAD_REQUEST)

            try:
                workgroup.add_user(user)
            except ValidationError as e:
                return Response({"detail": unicode(e)},
                                status.HTTP_400_BAD_REQUEST)

            workgroup.save()

            # add user to the workgroup cohort, create it if it doesn't exist (for cases where there is a legacy
            # workgroup)
            course_key = get_course_key(workgroup.project.course_id)
            try:
                cohort = get_cohort_by_name(course_key, workgroup.cohort_name)
                add_user_to_cohort(cohort, user.username)
            except ObjectDoesNotExist:
                # This use case handles cases where a workgroup might have been created before
                # the notion of a cohorted discussion. So we need to backfill in the data
                assignment_type = request.data.get('assignment_type',
                                                   CourseCohort.RANDOM)
                if assignment_type not in dict(
                        CourseCohort.ASSIGNMENT_TYPE_CHOICES).keys():
                    message = "Not a valid assignment type, '{}'".format(
                        assignment_type)
                    return Response({"detail": message},
                                    status.HTTP_400_BAD_REQUEST)
                workgroup = self.get_object()
                cohort = add_cohort(course_key, workgroup.cohort_name,
                                    assignment_type)
                for workgroup_user in workgroup.users.all():
                    add_user_to_cohort(cohort, workgroup_user.username)
            return Response({}, status=status.HTTP_201_CREATED)
        else:
            user_id = request.data.get('id')
            try:
                user = User.objects.get(id=user_id)
            except ObjectDoesNotExist:
                message = 'User {} does not exist'.format(user_id)
                return Response({"detail": message},
                                status.HTTP_400_BAD_REQUEST)
            workgroup = self.get_object()
            course_key = get_course_key(workgroup.project.course_id)
            cohort = get_cohort_by_name(course_key, workgroup.cohort_name)
            workgroup.remove_user(user)
            remove_user_from_cohort(cohort, user.username)
            return Response({}, status=status.HTTP_204_NO_CONTENT)
コード例 #25
0
    def post(self, request):
        """Enrolls the currently logged-in user in a course.

        Server-to-server calls may deactivate or modify the mode of existing enrollments. All other requests
        go through `add_enrollment()`, which allows creation of new and reactivation of old enrollments.
        """
        # Get the User, Course ID, and Mode from the request.

        username = request.data.get('user', request.user.username)
        course_id = request.data.get('course_details', {}).get('course_id')

        if not course_id:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Course ID must be specified to create a new enrollment."}
            )

        try:
            course_id = CourseKey.from_string(course_id)
        except InvalidKeyError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
                }
            )

        mode = request.data.get('mode')

        has_api_key_permissions = self.has_api_key_permissions(request)

        # Check that the user specified is either the same user, or this is a server-to-server request.
        if not username:
            username = request.user.username
        if username != request.user.username and not has_api_key_permissions:
            # Return a 404 instead of a 403 (Unauthorized). If one user is looking up
            # other users, do not let them deduce the existence of an enrollment.
            return Response(status=status.HTTP_404_NOT_FOUND)

        try:
            # Lookup the user, instead of using request.user, since request.user may not match the username POSTed.
            user = User.objects.get(username=username)
        except ObjectDoesNotExist:
            return Response(
                status=status.HTTP_406_NOT_ACCEPTABLE,
                data={
                    'message': u'The user {} does not exist.'.format(username)
                }
            )

        can_vip_enroll = False
        if settings.FEATURES.get('ENABLE_MEMBERSHIP_INTEGRATION'):
            from membership.models import VIPCourseEnrollment
            can_vip_enroll = VIPCourseEnrollment.can_vip_enroll(user, course_id)
        
        is_ecommerce_request = mode not in (CourseMode.AUDIT, CourseMode.HONOR, None)
        if is_ecommerce_request and not has_api_key_permissions and not can_vip_enroll:
            return Response(
                status=status.HTTP_403_FORBIDDEN,
                data={
                    "message": u"User does not have permission to create enrollment with mode [{mode}].".format(
                        mode=mode
                    )
                }
            )

        embargo_response = embargo_api.get_embargo_response(request, course_id, user)

        if embargo_response:
            return embargo_response

        try:
            is_active = request.data.get('is_active')
            # Check if the requested activation status is None or a Boolean
            if is_active is not None and not isinstance(is_active, bool):
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={
                        'message': (u"'{value}' is an invalid enrollment activation status.").format(value=is_active)
                    }
                )

            explicit_linked_enterprise = request.data.get('linked_enterprise_customer')
            if explicit_linked_enterprise and has_api_key_permissions and enterprise_enabled():
                enterprise_api_client = EnterpriseApiServiceClient()
                consent_client = ConsentApiServiceClient()
                try:
                    enterprise_api_client.post_enterprise_course_enrollment(username, unicode(course_id), None)
                except EnterpriseApiException as error:
                    log.exception("An unexpected error occurred while creating the new EnterpriseCourseEnrollment "
                                  "for user [%s] in course run [%s]", username, course_id)
                    raise CourseEnrollmentError(text_type(error))
                kwargs = {
                    'username': username,
                    'course_id': unicode(course_id),
                    'enterprise_customer_uuid': explicit_linked_enterprise,
                }
                consent_client.provide_consent(**kwargs)

            enrollment_attributes = request.data.get('enrollment_attributes')
            enrollment = api.get_enrollment(username, unicode(course_id))
            mode_changed = enrollment and mode is not None and enrollment['mode'] != mode
            active_changed = enrollment and is_active is not None and enrollment['is_active'] != is_active
            missing_attrs = []
            audit_with_order = False
            if enrollment_attributes:
                actual_attrs = [
                    u"{namespace}:{name}".format(**attr)
                    for attr in enrollment_attributes
                ]
                missing_attrs = set(REQUIRED_ATTRIBUTES.get(mode, [])) - set(actual_attrs)
                audit_with_order = mode == 'audit' and 'order:order_number' in actual_attrs
            # Remove audit_with_order when no longer needed - implemented for REV-141
            if has_api_key_permissions and (mode_changed or active_changed or audit_with_order):
                if mode_changed and active_changed and not is_active:
                    # if the requester wanted to deactivate but specified the wrong mode, fail
                    # the request (on the assumption that the requester had outdated information
                    # about the currently active enrollment).
                    msg = u"Enrollment mode mismatch: active mode={}, requested mode={}. Won't deactivate.".format(
                        enrollment["mode"], mode
                    )
                    log.warning(msg)
                    return Response(status=status.HTTP_400_BAD_REQUEST, data={"message": msg})

                if len(missing_attrs) > 0:
                    msg = u"Missing enrollment attributes: requested mode={} required attributes={}".format(
                        mode, REQUIRED_ATTRIBUTES.get(mode)
                    )
                    log.warning(msg)
                    return Response(status=status.HTTP_400_BAD_REQUEST, data={"message": msg})

                response = api.update_enrollment(
                    username,
                    unicode(course_id),
                    mode=mode,
                    is_active=is_active,
                    enrollment_attributes=enrollment_attributes,
                    # If we are updating enrollment by authorized api caller, we should allow expired modes
                    include_expired=has_api_key_permissions
                )
            else:
                # Will reactivate inactive enrollments.
                response = api.add_enrollment(
                    username,
                    unicode(course_id),
                    mode=mode,
                    is_active=is_active,
                    enrollment_attributes=enrollment_attributes,
                    user=user,
                    is_ecommerce_request=is_ecommerce_request
                )

            cohort_name = request.data.get('cohort')
            if cohort_name is not None:
                cohort = get_cohort_by_name(course_id, cohort_name)
                add_user_to_cohort(cohort, user)
            email_opt_in = request.data.get('email_opt_in', None)
            if email_opt_in is not None:
                org = course_id.org
                update_email_opt_in(request.user, org, email_opt_in)

            log.info('The user [%s] has already been enrolled in course run [%s].', username, course_id)
            return Response(response)
        except CourseModeNotFoundError as error:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"The [{mode}] course mode is expired or otherwise unavailable for course run [{course_id}]."
                    ).format(mode=mode, course_id=course_id),
                    "course_details": error.data
                })
        except CourseNotFoundError:
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
                }
            )
        except CourseEnrollmentExistsError as error:
            log.warning('An enrollment already exists for user [%s] in course run [%s].', username, course_id)
            return Response(data=error.enrollment)
        except CourseEnrollmentError:
            log.exception("An error occurred while creating the new course enrollment for user "
                          "[%s] in course run [%s]", username, course_id)
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": (
                        u"An error occurred while creating the new course enrollment for user "
                        u"'{username}' in course '{course_id}'"
                    ).format(username=username, course_id=course_id)
                }
            )
        except CourseUserGroup.DoesNotExist:
            log.exception('Missing cohort [%s] in course run [%s]', cohort_name, course_id)
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": "An error occured while adding to cohort [%s]" % cohort_name
                })
        finally:
            # Assumes that the ecommerce service uses an API key to authenticate.
            if has_api_key_permissions:
                current_enrollment = api.get_enrollment(username, unicode(course_id))
                audit_log(
                    'enrollment_change_requested',
                    course_id=unicode(course_id),
                    requested_mode=mode,
                    actual_mode=current_enrollment['mode'] if current_enrollment else None,
                    requested_activation=is_active,
                    actual_activation=current_enrollment['is_active'] if current_enrollment else None,
                    user_id=user.id
                )
コード例 #26
0
    def post(self, request):
        log.info(request.data)
        username = request.data.get('username')
        try:
            user = User.objects.get(username=username)
        except ObjectDoesNotExist:
            log.error(u"User {username} does not exist".format(username=username))
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"User {username} does not exist".format(username=username)}
            )

        course_id = request.data.get('course_id')
        if not course_id:
            log.error(u"Course ID must be specified to create a new enrollment.")
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Course ID must be specified to create a new enrollment."}
            )

        try:
            course_key = CourseKey.from_string(course_id)
        except InvalidKeyError:
            log.error(u"No course '{course_id}' found for enrollment".format(course_id=course_id))
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={
                    "message": u"No course '{course_id}' found for enrollment".format(course_id=course_id)
                }
            )
        course_is_cohorted = is_course_cohorted(course_key)
        if not course_is_cohorted:
            log.info(u"Course {course_id} is not cohorted.".format(course_id=course_id))
            return Response(
                status=status.HTTP_200_OK,
                data={"message": u"Course {course_id} is not cohorted.".format(course_id=course_id)}
            )

        action = request.data.get('action')
        if action not in [u'add', u'delete']:
            log.error(u"Available actions are 'add' and 'delete'.")
            return Response(
                status=status.HTTP_400_BAD_REQUEST,
                data={"message": u"Available actions are 'add' and 'delete'."}
            )

        cohort_exists = is_cohort_exists(course_key, VERIFIED)
        if not cohort_exists:
            if action == u'add':
                log.info(u"Cohort VERIFIED doesn't exist for course {} so let's create it!".format(course_id))
                cohort = add_cohort(course_key, VERIFIED, 'manual')
                log.info(u"Cohort VEIFIED created for the course {}".format(course_id))
            else:
                log.info(u"There aren't cohort verified for {course_id}".format(course_id=course_id))
                return Response(
                    status=status.HTTP_200_OK,
                    data={"message": u"There aren't cohort verified for {course_id}".format(course_id=course_id)}
                )
        else:
            cohort = get_cohort_by_name(course_key, VERIFIED)

        enrollment = CourseEnrollment.objects.get(
            user__username=username, course_id=course_key
        )
        if not enrollment or not enrollment.is_active:
            if action == u'add':
                log.error(u"Failed to add user into verified cohort. User {username} not enrolled or unenrolled in course {course_id}.".format(username=username, course_id=course_id))
                return Response(
                    status=status.HTTP_400_BAD_REQUEST,
                    data={"message": u"User {username} not enrolled or unenrolled in course {course_id}.".format(
                        username=username,
                        course_id=course_id
                    )}
                )
            if action == u'delete':
                if not enrollment:
                    log.info(u"User {username} is not enrolled in course {course_id}. (!!!)".format(username=username, course_id=course_id))
                    return Response(
                        status=status.HTTP_200_OK,
                        data={"message": u"User {username} is not enrolled in course {course_id}. (!!!)".format(
                            username=username,
                            course_id=course_id
                        )}
                    )
                else:
                    log.info(u"User {username} was unenrolled from course {course_id}.".format(username=username, course_id=course_id))
                    return Response(
                        status=status.HTTP_200_OK,
                        data={"message": u"User {username} was unenrolled from course {course_id}.".format(
                            username=username,
                            course_id=course_id
                        )}
                    )

        course_cohorts = CourseUserGroup.objects.filter(
            course_id=course_key,
            users__id=user.id,
            group_type=CourseUserGroup.COHORT
        )

        default_group = None
        for group in CourseUserGroup.objects.filter(course_id=course_key, group_type=CourseUserGroup.COHORT):
            if group.name.lower() == "default" or group.name.lower() == "default group":
                default_group = group
        if not default_group:
            log.info(u"Cohort DEFAULT doesn't exist for course {} so let's create it!".format(course_id))
            default_group = add_cohort(course_key, "Default Group", 'random')
            log.info(u"Cohort 'Default Group' succesfully created for the course {}".format(course_id))

        # remove user from verified cohort and add to default
        if action == u'delete':
            # let's check, that user not already presented into other cohort
            if course_cohorts.exists():
                if course_cohorts.first().name == default_group.name:
                    log.warning(
                        u"User {username} already present into default cohort {cohort_name} in course {course_id}".format(
                            username=username, cohort_name=default_group.name, course_id=course_id))
                    return Response(
                        status=status.HTTP_200_OK,
                        data={
                            "message": u"User {username} already present into default cohort {cohort_name} in course {course_id}".format(
                                username=username,
                                cohort_name=default_group.name,
                                course_id=course_id
                            )}
                    )
                elif course_cohorts.first().name == VERIFIED:
                    try:
                        add_user_to_cohort(default_group, username)
                        log.info(
                            u"User {username} succesfully moved into default cohort {cohort_name} in course {course_id}".format(
                                username=username, cohort_name=default_group.name, course_id=course_id))
                    except ValueError:
                        log.warning(
                            u"User {username} already present into default cohort {cohort_name} in course {course_id}".format(
                                username=username, cohort_name=default_group.name, course_id=course_id))
                    return Response(
                        status=status.HTTP_200_OK,
                        data={
                            "message": u"User {username} moved into default cohort {cohort_name} in course {course_id}".format(
                                username=username,
                                cohort_name=default_group.name,
                                course_id=course_id
                            )}
                    )
                else:
                    log.warning(u"Moving user {username} into default cohort {cohort_name} from verified in course {course_id}".format(username=username, cohort_name=default_group.name, course_id=course_id))
                    try:
                        add_user_to_cohort(default_group, username)
                        log.info(u"User {username} succesfully moved into default cohort {cohort_name} in course {course_id}".format(username=username, cohort_name=default_group.name, course_id=course_id))
                    except ValueError:
                        log.warning(u"User {username} already present into default cohort {cohort_name} in course {course_id}".format(username=username, cohort_name=default_group.name, course_id=course_id))
                    return Response(
                        status=status.HTTP_200_OK,
                        data={"message": u"User {username} already present in non-verified cohort {cohort_name} in course {course_id}".format(
                                username=username, cohort_name=course_cohorts.first().name, course_id=course_id
                        )}
                    )

        if action == u"add":
            message = add_user_into_verified_cohort(course_cohorts, cohort, user)
            if not message:
                message = u"User {username} added to cohort {cohort_name} into course {course_id}".format(username=user.username, cohort_name=cohort.name, course_id=course_id)
            log.info(message)
            return Response(
                status=status.HTTP_200_OK,
                data={"message":message}
            )