Exemple #1
0
    def post(self, request):
        """
        POST /api/user/v1/accounts/retire/

        {
            'username': '******'
        }

        Retires the user with the given username.  This includes
        retiring this username, the associates email address, and
        any other PII associated with this user.
        """
        username = request.data['username']
        if is_username_retired(username):
            return Response(status=status.HTTP_404_NOT_FOUND)

        try:
            retirement_status = UserRetirementStatus.get_retirement_for_retirement_action(username)
            user = retirement_status.user
            retired_username = retirement_status.retired_username or get_retired_username_by_username(username)
            retired_email = retirement_status.retired_email or get_retired_email_by_email(user.email)
            original_email = retirement_status.original_email

            # Retire core user/profile information
            self.clear_pii_from_userprofile(user)
            self.delete_users_profile_images(user)
            self.delete_users_country_cache(user)

            # Retire data from Enterprise models
            self.retire_users_data_sharing_consent(username, retired_username)
            self.retire_sapsf_data_transmission(user)
            self.retire_user_from_pending_enterprise_customer_user(user, retired_email)
            self.retire_entitlement_support_detail(user)

            # Retire misc. models that may contain PII of this user
            SoftwareSecurePhotoVerification.retire_user(user.id)
            PendingEmailChange.delete_by_user_value(user, field='user')
            UserOrgTag.delete_by_user_value(user, field='user')

            # Retire any objects linked to the user via their original email
            CourseEnrollmentAllowed.delete_by_user_value(original_email, field='email')
            UnregisteredLearnerCohortAssignments.delete_by_user_value(original_email, field='email')

            # TODO: Password Reset links - https://openedx.atlassian.net/browse/PLAT-2104
            # TODO: Delete OAuth2 records - https://openedx.atlassian.net/browse/EDUCATOR-2703

            user.first_name = ''
            user.last_name = ''
            user.is_active = False
            user.username = retired_username
            user.save()
        except UserRetirementStatus.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except RetirementStateError as exc:
            return Response(text_type(exc), status=status.HTTP_400_BAD_REQUEST)
        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)
Exemple #2
0
    def test_retire_nonuser(self):
        """
        Attempt to Retire User with no records in table
        """
        user = UserFactory.create()
        attempt = SoftwareSecurePhotoVerification(user=user)

        # User with no records in table
        self.assertFalse(attempt.retire_user(user_id=user.id))

        # No user
        self.assertFalse(attempt.retire_user(user_id=47))
Exemple #3
0
    def test_retire_nonuser(self):
        """
        Attempt to Retire User with no records in table
        """
        user = UserFactory.create()
        attempt = SoftwareSecurePhotoVerification(user=user)

        # User with no records in table
        self.assertFalse(attempt.retire_user(user_id=user.id))

        # No user
        self.assertFalse(attempt.retire_user(user_id=47))
Exemple #4
0
    def test_retire_user(self):
        """
        Retire user with record(s) in table
        """
        user = UserFactory.create()
        user.profile.name = "Enrique"
        attempt = SoftwareSecurePhotoVerification(user=user)

        # Populate Record
        attempt.mark_ready()
        attempt.status = PhotoVerification.STATUS.submitted
        attempt.photo_id_image_url = "https://example.com/test/image/img.jpg"
        attempt.face_image_url = "https://example.com/test/face/img.jpg"
        attempt.photo_id_key = 'there_was_an_attempt'
        attempt.approve()

        # Validate data before retirement
        assert attempt.name == user.profile.name
        assert attempt.photo_id_image_url == 'https://example.com/test/image/img.jpg'
        assert attempt.face_image_url == 'https://example.com/test/face/img.jpg'
        assert attempt.photo_id_key == 'there_was_an_attempt'

        # Retire User
        attempt_again = SoftwareSecurePhotoVerification(user=user)
        assert attempt_again.retire_user(user_id=user.id)

        # Validate data after retirement
        assert attempt_again.name == ''
        assert attempt_again.face_image_url == ''
        assert attempt_again.photo_id_image_url == ''
        assert attempt_again.photo_id_key == ''
Exemple #5
0
    def test_retire_user(self):
        """
        Retire user with record(s) in table
        """
        user = UserFactory.create()
        user.profile.name = u"Enrique"
        attempt = SoftwareSecurePhotoVerification(user=user)

        # Populate Record
        attempt.mark_ready()
        attempt.status = "submitted"
        attempt.photo_id_image_url = "https://example.com/test/image/img.jpg"
        attempt.face_image_url = "https://example.com/test/face/img.jpg"
        attempt.photo_id_key = 'there_was_an_attempt'
        attempt.approve()

        # Validate data before retirement
        self.assertEqual(attempt.name, user.profile.name)
        self.assertEqual(attempt.photo_id_image_url,
                         'https://example.com/test/image/img.jpg')
        self.assertEqual(attempt.face_image_url,
                         'https://example.com/test/face/img.jpg')
        self.assertEqual(attempt.photo_id_key, 'there_was_an_attempt')

        # Retire User
        attempt_again = SoftwareSecurePhotoVerification(user=user)
        self.assertTrue(attempt_again.retire_user(user_id=user.id))

        # Validate data after retirement
        self.assertEqual(attempt_again.name, '')
        self.assertEqual(attempt_again.face_image_url, '')
        self.assertEqual(attempt_again.photo_id_image_url, '')
        self.assertEqual(attempt_again.photo_id_key, '')
Exemple #6
0
    def test_retire_user(self):
        """
        Retire user with record(s) in table
        """
        user = UserFactory.create()
        user.profile.name = u"Enrique"
        attempt = SoftwareSecurePhotoVerification(user=user)

        # Populate Record
        attempt.mark_ready()
        attempt.status = "submitted"
        attempt.photo_id_image_url = "https://example.com/test/image/img.jpg"
        attempt.face_image_url = "https://example.com/test/face/img.jpg"
        attempt.photo_id_key = 'there_was_an_attempt'
        attempt.approve()

        # Validate data before retirement
        self.assertEqual(attempt.name, user.profile.name)
        self.assertEqual(attempt.photo_id_image_url, 'https://example.com/test/image/img.jpg')
        self.assertEqual(attempt.face_image_url, 'https://example.com/test/face/img.jpg')
        self.assertEqual(attempt.photo_id_key, 'there_was_an_attempt')

        # Retire User
        attempt_again = SoftwareSecurePhotoVerification(user=user)
        self.assertTrue(attempt_again.retire_user(user_id=user.id))

        # Validate data after retirement
        self.assertEqual(attempt_again.name, '')
        self.assertEqual(attempt_again.face_image_url, '')
        self.assertEqual(attempt_again.photo_id_image_url, '')
        self.assertEqual(attempt_again.photo_id_key, '')
Exemple #7
0
    def post(self, request):
        """
        POST /api/user/v1/accounts/retire/

        {
            'username': '******'
        }

        Retires the user with the given username.  This includes
        retiring this username, the associates email address, and
        any other PII associated with this user.
        """
        username = request.data['username']
        if is_username_retired(username):
            return Response(status=status.HTTP_404_NOT_FOUND)

        try:
            retirement_status = UserRetirementStatus.get_retirement_for_retirement_action(
                username)
            user = retirement_status.user
            retired_username = retirement_status.retired_username or get_retired_username_by_username(
                username)
            retired_email = retirement_status.retired_email or get_retired_email_by_email(
                user.email)
            original_email = retirement_status.original_email

            # Retire core user/profile information
            self.clear_pii_from_userprofile(user)
            self.delete_users_profile_images(user)
            self.delete_users_country_cache(user)

            # Retire data from Enterprise models
            self.retire_users_data_sharing_consent(username, retired_username)
            self.retire_sapsf_data_transmission(user)
            self.retire_degreed_data_transmission(user)
            self.retire_user_from_pending_enterprise_customer_user(
                user, retired_email)
            self.retire_entitlement_support_detail(user)

            # Retire misc. models that may contain PII of this user
            SoftwareSecurePhotoVerification.retire_user(user.id)
            PendingEmailChange.delete_by_user_value(user, field='user')
            UserOrgTag.delete_by_user_value(user, field='user')

            # Retire any objects linked to the user via their original email
            CourseEnrollmentAllowed.delete_by_user_value(original_email,
                                                         field='email')
            UnregisteredLearnerCohortAssignments.delete_by_user_value(
                original_email, field='email')

            # TODO: Password Reset links - https://openedx.atlassian.net/browse/PLAT-2104
            # TODO: Delete OAuth2 records - https://openedx.atlassian.net/browse/EDUCATOR-2703

            user.first_name = ''
            user.last_name = ''
            user.is_active = False
            user.username = retired_username
            user.save()
        except UserRetirementStatus.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        except RetirementStateError as exc:
            return Response(text_type(exc), status=status.HTTP_400_BAD_REQUEST)
        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)