Exemplo n.º 1
0
def test_retirement_request_created_upon_status(setup_retirement_states):  # pylint: disable=unused-argument, redefined-outer-name
    """
    Ensure that retirement request record is created upon retirement status creation.
    """
    user = UserFactory()
    UserRetirementStatus.create_retirement(user)
    assert UserRetirementRequest.has_user_requested_retirement(user)
Exemplo n.º 2
0
def test_retirement_request_created_upon_status(setup_retirement_states):  # pylint: disable=unused-argument, redefined-outer-name
    """
    Ensure that retirement request record is created upon retirement status creation.
    """
    user = UserFactory()
    UserRetirementStatus.create_retirement(user)
    assert UserRetirementRequest.has_user_requested_retirement(user)
Exemplo n.º 3
0
 def post(self, request):
     """
     Unenrolls the specified user from all courses.
     """
     try:
         # Get the username from the request.
         username = request.data['username']
         # Ensure that a retirement request status row exists for this username.
         UserRetirementStatus.get_retirement_for_retirement_action(username)
         enrollments = api.get_enrollments(username)
         active_enrollments = [
             enrollment for enrollment in enrollments
             if enrollment['is_active']
         ]
         if len(active_enrollments) < 1:
             return Response(status=status.HTTP_204_NO_CONTENT)
         return Response(api.unenroll_user_from_all_courses(username))
     except KeyError:
         return Response(u'Username not specified.',
                         status=status.HTTP_404_NOT_FOUND)
     except UserRetirementStatus.DoesNotExist:
         return Response(u'No retirement request status for username.',
                         status=status.HTTP_404_NOT_FOUND)
     except Exception as exc:  # pylint: disable=broad-except
         return Response(text_type(exc),
                         status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Exemplo n.º 4
0
def test_retirement_create_no_default_state():
    """
    Confirm that if no states have been loaded we fail with a RetirementStateError
    """
    user = UserFactory()

    with pytest.raises(RetirementStateError):
        UserRetirementStatus.create_retirement(user)
Exemplo n.º 5
0
def test_retirement_create_no_default_state():
    """
    Confirm that if no states have been loaded we fail with a RetirementStateError
    """
    user = UserFactory()

    with pytest.raises(RetirementStateError):
        UserRetirementStatus.create_retirement(user)
Exemplo n.º 6
0
def test_retirement_create_already_retired(setup_retirement_states):  # pylint: disable=unused-argument, redefined-outer-name
    """
    Confirm the correct error bubbles up if the user already has a retirement row
    """
    user = UserFactory()
    retirement = UserRetirementStatus.create_retirement(user)
    _assert_retirementstatus_is_user(retirement, user)

    with pytest.raises(RetirementStateError):
        UserRetirementStatus.create_retirement(user)
Exemplo n.º 7
0
def test_retirement_create_already_retired(setup_retirement_states):  # pylint: disable=unused-argument, redefined-outer-name
    """
    Confirm the correct error bubbles up if the user already has a retirement row
    """
    user = UserFactory()
    retirement = UserRetirementStatus.create_retirement(user)
    _assert_retirementstatus_is_user(retirement, user)

    with pytest.raises(RetirementStateError):
        UserRetirementStatus.create_retirement(user)
Exemplo n.º 8
0
def test_retirement_create_success(setup_retirement_states):  # pylint: disable=unused-argument, redefined-outer-name
    """
    Basic test to make sure default creation succeeds
    """
    user = UserFactory()
    retirement = UserRetirementStatus.create_retirement(user)
    _assert_retirementstatus_is_user(retirement, user)
Exemplo n.º 9
0
 def setUp(self):
     super(CreditRequestTest, self).setUp()
     RetirementTestCase.setup_states()
     self.user = UserFactory.create()
     self.retirement = UserRetirementStatus.create_retirement(self.user)
     self.credit_course = CreditCourse.objects.create()
     self.provider = CreditProvider.objects.create()
Exemplo n.º 10
0
    def post(self, request):
        """
        Implements the retirement endpoint.
        """
        username = request.data['username']

        try:
            retirement = UserRetirementStatus.get_retirement_for_retirement_action(
                username)
            cc_user = comment_client.User.from_django_user(retirement.user)

            # Send the retired username to the forums service, as the service cannot generate
            # the retired username itself. Forums users are referenced by Django auth_user id.
            cc_user.retire(retirement.retired_username)
        except UserRetirementStatus.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except comment_client.CommentClientRequestError as exc:
            # 404s from client service for users that don't exist there are expected
            # we can just pass those up.
            if exc.status_code == 404:
                return Response(status=status.HTTP_404_NOT_FOUND)
            raise
        except Exception as exc:  # pylint: disable=broad-except
            return Response(text_type(exc),
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response(status=status.HTTP_204_NO_CONTENT)
Exemplo n.º 11
0
 def setUp(self):
     super(CreditRequirementStatusTests, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
     self.course_key = CourseKey.from_string("edX/DemoX/Demo_Course")
     self.old_username = "******"
     self.user = UserFactory(username=self.old_username)
     self.retirement = UserRetirementStatus.create_retirement(self.user)
     self.credit_course = add_credit_course(self.course_key)
Exemplo n.º 12
0
def test_retirement_create_success(setup_retirement_states):  # pylint: disable=unused-argument, redefined-outer-name
    """
    Basic test to make sure default creation succeeds
    """
    user = UserFactory()
    retirement = UserRetirementStatus.create_retirement(user)
    _assert_retirementstatus_is_user(retirement, user)
 def setUp(self):
     super().setUp()
     self.course_key = CourseKey.from_string("edX/DemoX/Demo_Course")
     self.old_username = "******"
     self.user = UserFactory(username=self.old_username)
     self.retirement = UserRetirementStatus.create_retirement(self.user)
     self.credit_course = add_credit_course(self.course_key)
Exemplo n.º 14
0
    def post(self, request):
        """
        Implements the retirement endpoint.
        """
        username = request.data['username']

        try:
            retirement = UserRetirementStatus.get_retirement_for_retirement_action(username)
            cc_user = comment_client.User.from_django_user(retirement.user)

            # Send the retired username to the forums service, as the service cannot generate
            # the retired username itself. Forums users are referenced by Django auth_user id.
            cc_user.retire(retirement.retired_username)
        except UserRetirementStatus.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except comment_client.CommentClientRequestError as exc:
            # 404s from client service for users that don't exist there are expected
            # we can just pass those up.
            if exc.status_code == 404:
                return Response(status=status.HTTP_404_NOT_FOUND)
            raise
        except Exception as exc:  # pylint: disable=broad-except
            return Response(text_type(exc), status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response(status=status.HTTP_204_NO_CONTENT)
Exemplo n.º 15
0
 def setUp(self):
     super(CreditRequirementStatusTests, self).setUp()
     self.course_key = CourseKey.from_string("edX/DemoX/Demo_Course")
     self.old_username = "******"
     self.user = UserFactory(username=self.old_username)
     self.retirement = UserRetirementStatus.create_retirement(self.user)
     self.credit_course = add_credit_course(self.course_key)
Exemplo n.º 16
0
 def post(self, request):
     """
     Unenrolls the specified user from all courses.
     """
     try:
         # Get the username from the request.
         username = request.data['username']
         # Ensure that a retirement request status row exists for this username.
         UserRetirementStatus.get_retirement_for_retirement_action(username)
         enrollments = api.get_enrollments(username)
         active_enrollments = [enrollment for enrollment in enrollments if enrollment['is_active']]
         if len(active_enrollments) < 1:
             return Response(status=status.HTTP_204_NO_CONTENT)
         return Response(api.unenroll_user_from_all_courses(username))
     except KeyError:
         return Response(u'Username not specified.', status=status.HTTP_404_NOT_FOUND)
     except UserRetirementStatus.DoesNotExist:
         return Response(u'No retirement request status for username.', status=status.HTTP_404_NOT_FOUND)
     except Exception as exc:  # pylint: disable=broad-except
         return Response(text_type(exc), status=status.HTTP_500_INTERNAL_SERVER_ERROR)
Exemplo n.º 17
0
def test_retirement_request_preserved_upon_non_pending_status_delete(setup_retirement_states):  # pylint: disable=unused-argument, redefined-outer-name
    """
    Ensure that retirement request record is not deleted upon deletion of a non-PENDING retirement status.
    """
    user = UserFactory()
    retirement_status = UserRetirementStatus.create_retirement(user)
    assert UserRetirementRequest.has_user_requested_retirement(user)
    non_pending = RetirementState.objects.all().order_by('state_execution_order')[1]
    retirement_status.current_state = non_pending
    retirement_status.delete()
    assert UserRetirementRequest.has_user_requested_retirement(user)
Exemplo n.º 18
0
def test_retirement_request_deleted_upon_pending_status_delete(
    setup_retirement_states):  # pylint: disable=unused-argument, redefined-outer-name
    """
    Ensure that retirement request record is deleted upon deletion of a PENDING retirement status.
    """
    user = UserFactory()
    retirement_status = UserRetirementStatus.create_retirement(user)
    assert UserRetirementRequest.has_user_requested_retirement(user)
    pending = RetirementState.objects.all().order_by(
        'state_execution_order')[0]
    assert retirement_status.current_state == pending
    retirement_status.delete()
    assert not UserRetirementRequest.has_user_requested_retirement(user)
Exemplo n.º 19
0
    def post(self, request):
        """
        Implements the retirement endpoint.
        """
        username = request.data['username']
        try:
            retirement = UserRetirementStatus.get_retirement_for_retirement_action(username)
            delete_all_notes_for_user(retirement.user)
        except UserRetirementStatus.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except RetirementStateError as exc:
            return Response(text_type(exc), status=status.HTTP_405_METHOD_NOT_ALLOWED)
        except Exception as exc:  # pylint: disable=broad-except
            return Response(text_type(exc), status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response(status=status.HTTP_204_NO_CONTENT)
Exemplo n.º 20
0
def create_retirement_status(user, state=None, create_datetime=None):
    """
    Helper method to create a RetirementStatus with useful defaults.
    Assumes that retirement states have been setup before calling.
    """
    if create_datetime is None:
        create_datetime = datetime.datetime.now(pytz.UTC) - datetime.timedelta(days=8)

    retirement = UserRetirementStatus.create_retirement(user)
    if state:
        retirement.current_state = state
        retirement.last_state = state
    retirement.created = create_datetime
    retirement.modified = create_datetime
    retirement.save()
    return retirement
Exemplo n.º 21
0
def create_retirement_status(user, state=None, create_datetime=None):
    """
    Helper method to create a RetirementStatus with useful defaults.
    Assumes that retirement states have been setup before calling.
    """
    if create_datetime is None:
        create_datetime = datetime.datetime.now(pytz.UTC) - datetime.timedelta(days=8)

    retirement = UserRetirementStatus.create_retirement(user)
    if state:
        retirement.current_state = state
        retirement.last_state = state
    retirement.created = create_datetime
    retirement.modified = create_datetime
    retirement.save()
    return retirement
Exemplo n.º 22
0
    def post(self, request):
        """
        Implements the retirement endpoint.
        """
        username = request.data['username']
        try:
            retirement = UserRetirementStatus.get_retirement_for_retirement_action(username)
            delete_all_notes_for_user(retirement.user)
        except UserRetirementStatus.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except RetirementStateError as exc:
            return Response(text_type(exc), status=status.HTTP_405_METHOD_NOT_ALLOWED)
        except Exception as exc:  # pylint: disable=broad-except
            return Response(text_type(exc), status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response(status=status.HTTP_204_NO_CONTENT)
def test_users_in_bad_states():
    """
    Test that having users in the process of retirement cause this to fail
    """
    user = UserFactory()

    # First populate the table
    call_command('populate_retirement_states')

    # Create a UserRetirementStatus in an active state
    retirement = UserRetirementStatus.create_retirement(user)
    retirement.current_state = RetirementState.objects.get(state_name='LOCKING_ACCOUNT')
    retirement.save()

    # Now try to update
    with pytest.raises(CommandError, match=r'Users are currently being processed'):
        call_command('populate_retirement_states')
def test_users_in_bad_states():
    """
    Test that having users in the process of retirement cause this to fail
    """
    user = UserFactory()

    # First populate the table
    call_command('populate_retirement_states')

    # Create a UserRetirementStatus in an active state
    retirement = UserRetirementStatus.create_retirement(user)
    retirement.current_state = RetirementState.objects.get(
        state_name='LOCKING_ACCOUNT')
    retirement.save()

    # Now try to update
    with pytest.raises(CommandError,
                       match=r'Users are currently being processed'):
        call_command('populate_retirement_states')
Exemplo n.º 25
0
    def test_cannot_retire_nonexistent_user(self):
        test_parameters = {'hi': 'there'}
        CreditRequest.objects.create(
            username=self.user.username,
            course=self.credit_course,
            provider=self.provider,
            parameters=test_parameters,
        )
        another_user = UserFactory.create()
        another_retirement = UserRetirementStatus.create_retirement(another_user)

        credit_request_before_retire = CreditRequest.objects.filter(
            username=self.retirement.original_username
        )[0]

        was_retired = CreditRequest.retire_user(another_retirement)
        credit_request_before_retire.refresh_from_db()

        self.assertFalse(was_retired)
        self.assertEqual(credit_request_before_retire.parameters, test_parameters)
    def test_cannot_retire_nonexistent_user(self):
        test_parameters = {'hi': 'there'}
        CreditRequest.objects.create(
            username=self.user.username,
            course=self.credit_course,
            provider=self.provider,
            parameters=test_parameters,
        )
        another_user = UserFactory.create()
        another_retirement = UserRetirementStatus.create_retirement(
            another_user)

        credit_request_before_retire = CreditRequest.objects.filter(
            username=self.retirement.original_username)[0]

        was_retired = CreditRequest.retire_user(another_retirement)
        credit_request_before_retire.refresh_from_db()

        assert not was_retired
        assert credit_request_before_retire.parameters == test_parameters
def _setup_users():
    """
    Creates and returns test users in the different states of needing rehash:
    - Skipped: has not yet been retired
    - Faked: has been fake-retired, but the retired username does not require updating
    - Needing rehash: has been fake-retired and name changed so it triggers a hash update
    """
    # When we loop through creating users, take additional action on these
    user_indexes_to_be_fake_retired = (2, 4, 6, 8, 10)
    user_indexes_to_be_rehashed = (4, 6)

    users_skipped = []
    users_faked = []
    users_needing_rehash = []
    retirements = {}

    # Create some test users with retirements
    for i in range(1, 11):
        user = UserFactory()
        retirement = UserRetirementStatus.create_retirement(user)
        retirements[user.id] = retirement

        if i in user_indexes_to_be_fake_retired:
            fake_completed_retirement(user)

            if i in user_indexes_to_be_rehashed:
                # In order to need a rehash user.username must be the same as
                # retirement.retired_username and NOT the same as the hash
                # generated when the script is run. So we force that here.
                retirement.retired_username = retirement.retired_username.upper(
                )
                user.username = retirement.retired_username
                retirement.save()
                user.save()
                users_needing_rehash.append(user)
            else:
                users_faked.append(user)
        else:
            users_skipped.append(user)
    return users_skipped, users_faked, users_needing_rehash, retirements
Exemplo n.º 28
0
    def post(self, request):
        """
        Implements the retirement endpoint.
        """
        username = request.data['username']

        try:
            retirement = UserRetirementStatus.get_retirement_for_retirement_action(
                username)
            cc_user = comment_client.User.from_django_user(retirement.user)

            # We can't count on the LMS username being un-retired at this point,
            # so we pass the old username as a parameter to describe which
            # user to retire. This will either succeed or throw an error which
            # should be good to raise from here.
            cc_user.retire(username)
        except UserRetirementStatus.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except Exception as exc:  # pylint: disable=broad-except
            return Response(text_type(exc),
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

        return Response(status=status.HTTP_204_NO_CONTENT)
Exemplo n.º 29
0
 def setUp(self):
     super(CreditRequestTest, self).setUp()
     self.user = UserFactory.create()
     self.retirement = UserRetirementStatus.create_retirement(self.user)
     self.credit_course = CreditCourse.objects.create()
     self.provider = CreditProvider.objects.create()
Exemplo n.º 30
0
def delete_edxapp_user(*args, **kwargs):
    """
    Deletes a user from the platform.
    """
    msg = None

    user = kwargs.get("user")
    case_id = kwargs.get("case_id")
    site = kwargs.get("site")
    is_support_user = kwargs.get("is_support_user")

    user_response = "The user {username} <{email}> ".format(
        username=user.username, email=user.email)

    signup_sources = user.usersignupsource_set.all()
    sources = [signup_source.site for signup_source in signup_sources]

    if site and site.name.upper() in (source.upper() for source in sources):
        if len(sources) == 1:
            with transaction.atomic():
                support_label = "_support" if is_support_user else ""
                user.email = "{email}{case}.ednx{support}_retired".format(
                    email=user.email,
                    case=case_id,
                    support=support_label,
                )
                user.save()

                # Add user to retirement queue.
                UserRetirementStatus.create_retirement(user)

                # Unlink LMS social auth accounts
                UserSocialAuth.objects.filter(user_id=user.id).delete()

                # Change LMS password & email
                user.email = get_retired_email_by_email(user.email)
                user.save()
                _set_unusable_password(user)

                # Remove the activation keys sent by email to the user for account activation.
                Registration.objects.filter(user=user).delete()

                # Delete OAuth tokens associated with the user.
                retire_dot_oauth2_models(user)

                # Delete user signup source object
                signup_sources[0].delete()

                msg = "{user} has been removed".format(user=user_response)
        else:
            for signup_source in signup_sources:
                if signup_source.site.upper() == site.name.upper():
                    signup_source.delete()

                    msg = "{user} has more than one signup source. The signup source from the site {site} has been deleted".format(
                        user=user_response,
                        site=site,
                    )

        return msg, status.HTTP_200_OK

    raise NotFound(
        "{user} does not have a signup source on the site {site}".format(
            user=user_response, site=site))
Exemplo n.º 31
0
 def setUp(self):
     super(CreditRequestTest, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
     self.user = UserFactory.create()
     self.retirement = UserRetirementStatus.create_retirement(self.user)
     self.credit_course = CreditCourse.objects.create()
     self.provider = CreditProvider.objects.create()
 def setUp(self):
     super().setUp()
     self.user = UserFactory.create()
     self.retirement = UserRetirementStatus.create_retirement(self.user)
     self.credit_course = CreditCourse.objects.create()
     self.provider = CreditProvider.objects.create()