Example #1
0
    def clean_email_or_username(self):
        """
        Clean email form field

        Returns:
            str: the cleaned value, converted to an email address (or an empty string)
        """
        email_or_username = self.cleaned_data[
            self.Fields.EMAIL_OR_USERNAME].strip()

        if not email_or_username:
            # The field is blank; we just return the existing blank value.
            return email_or_username

        email = email_or_username__to__email(email_or_username)
        bulk_entry = len(split_usernames_and_emails(email)) > 1
        if bulk_entry:
            for email in split_usernames_and_emails(email):
                validate_email_to_link(
                    email,
                    None,
                    ValidationMessages.INVALID_EMAIL_OR_USERNAME,
                    ignore_existing=True)
            email = email_or_username
        else:
            validate_email_to_link(
                email,
                email_or_username,
                ValidationMessages.INVALID_EMAIL_OR_USERNAME,
                ignore_existing=True)

        return email
    def test_validate_email_to_link_invalid_email(self, email, raw_email, msg_template):
        assert EnterpriseCustomerUser.objects.get_link_by_email(email) is None, \
            "Precondition check - should not have EnterpriseCustomerUser or PendingEnterpriseCustomerUser"

        expected_message = msg_template.format(argument=raw_email)

        with raises(ValidationError, match=expected_message):
            validate_email_to_link(email, raw_email)
Example #3
0
    def _handle_singular(cls, request, enterprise_customer,
                         manage_learners_form):
        """
        Link single user by email or username.

        Arguments:
            enterprise_customer (EnterpriseCustomer): learners will be linked to this Enterprise Customer instance
            manage_learners_form (ManageLearnersForm): bound ManageLearners form instance
        """
        form_field_value = manage_learners_form.cleaned_data[
            ManageLearnersForm.Fields.EMAIL_OR_USERNAME]
        email = email_or_username__to__email(form_field_value)
        try:
            existing_record = validate_email_to_link(
                email, form_field_value,
                ValidationMessages.INVALID_EMAIL_OR_USERNAME, True)
        except ValidationError as exc:
            manage_learners_form.add_error(
                ManageLearnersForm.Fields.EMAIL_OR_USERNAME, exc)
        else:
            if isinstance(existing_record, PendingEnterpriseCustomerUser) and existing_record.enterprise_customer \
                    != enterprise_customer:
                messages.warning(
                    request,
                    ValidationMessages.PENDING_USER_ALREADY_LINKED.format(
                        user_email=email,
                        ec_name=existing_record.enterprise_customer.name))
                return None
            EnterpriseCustomerUser.objects.link_user(enterprise_customer,
                                                     email)
            return [email]
Example #4
0
    def _handle_singular(cls, enterprise_customer, manage_learners_form):
        """
        Link single user by email or username.

        Arguments:
            enterprise_customer (EnterpriseCustomer): learners will be linked to this Enterprise Customer instance
            manage_learners_form (ManageLearnersForm): bound ManageLearners form instance
        """
        form_field_value = manage_learners_form.cleaned_data[ManageLearnersForm.Fields.EMAIL_OR_USERNAME]
        email = email_or_username__to__email(form_field_value)
        try:
            validate_email_to_link(email, form_field_value, ValidationMessages.INVALID_EMAIL_OR_USERNAME)
        except ValidationError as exc:
            manage_learners_form.add_error(ManageLearnersForm.Fields.EMAIL_OR_USERNAME, exc.message)
        else:
            EnterpriseCustomerUser.objects.link_user(enterprise_customer, email)
            return [email]
    def test_validate_email_to_link_existing_pending_record(self, ignore_existing):
        email = FAKER.email()  # pylint: disable=no-member
        existing_record = PendingEnterpriseCustomerUserFactory(user_email=email)
        assert PendingEnterpriseCustomerUser.objects.get(user_email=email) == existing_record, \
            "Precondition check - should have PendingEnterpriseCustomerUser"
        assert not EnterpriseCustomerUser.objects.exists(), \
            "Precondition check - should not have EnterpriseCustomerUser"

        if ignore_existing:
            exists = validate_email_to_link(email, ignore_existing=True)
            assert exists
        else:
            expected_message = ValidationMessages.USER_ALREADY_REGISTERED.format(
                email=email, ec_name=existing_record.enterprise_customer.name
            )

            with raises(ValidationError, match=expected_message):
                exists = validate_email_to_link(email)
    def test_validate_email_to_link_normal(self):
        email = FAKER.email()  # pylint: disable=no-member
        assert PendingEnterpriseCustomerUser.objects.filter(user_email=email).count() == 0, \
            "Precondition check - should not have PendingEnterpriseCustomerUser"
        assert EnterpriseCustomerUser.objects.count() == 0, \
            "Precondition check - should not have EnterpriseCustomerUser"

        exists = validate_email_to_link(email)  # should not raise any Exceptions
        assert exists is False
    def test_validate_email_to_link_normal(self):
        email = FAKER.email()
        assert len(PendingEnterpriseCustomerUser.objects.filter(user_email=email)) == 0, \
            "Precondition check - should not have PendingEnterpriseCustomerUser"
        assert len(EnterpriseCustomerUser.objects.all()) == 0, \
            "Precondition check - should not have EnterpriseCustomerUser"

        exists = validate_email_to_link(email)  # should not raise any Exceptions
        assert exists is False
    def test_validate_email_to_link_existing_user_record(self, ignore_existing):
        user = UserFactory()
        email = user.email
        existing_record = EnterpriseCustomerUserFactory(user_id=user.id)
        assert not PendingEnterpriseCustomerUser.objects.exists(), \
            "Precondition check - should not have PendingEnterpriseCustomerUser"
        assert EnterpriseCustomerUser.objects.get(user_id=user.id) == existing_record, \
            "Precondition check - should have EnterpriseCustomerUser"

        if ignore_existing:
            exists = validate_email_to_link(email, ignore_existing=True)
            assert exists
        else:
            expected_message = ValidationMessages.USER_ALREADY_REGISTERED.format(
                email=email, ec_name=existing_record.enterprise_customer.name
            )

            with raises(ValidationError, match=expected_message):
                validate_email_to_link(email)
Example #9
0
    def clean_email_or_username(self):
        """
        Clean email form field

        Returns:
            str: the cleaned value, converted to an email address (or an empty string)
        """
        email_or_username = self.cleaned_data[
            self.Fields.EMAIL_OR_USERNAME].strip()

        if not email_or_username:
            # The field is blank; we just return the existing blank value.
            return email_or_username

        email = email_or_username__to__email(email_or_username)
        validate_email_to_link(email, email_or_username,
                               ValidationMessages.INVALID_EMAIL_OR_USERNAME)

        return email
Example #10
0
    def _handle_bulk_upload(cls, enterprise_customer, manage_learners_form,
                            request):
        """
        Bulk link users by email.

        Arguments:
            enterprise_customer (EnterpriseCustomer): learners will be linked to this Enterprise Customer instance
            manage_learners_form (ManageLearnersForm): bound ManageLearners form instance
            request (django.http.request.HttpRequest): HTTP Request instance
        """
        errors = []
        emails = set()
        already_linked_emails = []
        duplicate_emails = []
        csv_file = manage_learners_form.cleaned_data[
            ManageLearnersForm.Fields.BULK_UPLOAD]
        try:
            parsed_csv = parse_csv(
                csv_file,
                expected_columns={ManageLearnersForm.CsvColumns.EMAIL})
            for index, row in enumerate(parsed_csv):
                email = row[ManageLearnersForm.CsvColumns.EMAIL]
                try:
                    already_linked = validate_email_to_link(
                        email, ignore_existing=True)
                except ValidationError as exc:
                    message = _("Error at line {line}: {message}\n").format(
                        line=index + 1, message=exc.message)
                    errors.append(message)
                else:
                    if already_linked:
                        already_linked_emails.append(email)
                    elif email in emails:
                        duplicate_emails.append(email)
                    else:
                        emails.add(email)
        except ValidationError as exc:
            errors.append(exc.message)

        if errors:
            manage_learners_form.add_error(
                ManageLearnersForm.Fields.GENERAL_ERRORS,
                ValidationMessages.BULK_LINK_FAILED)
            for error in errors:
                manage_learners_form.add_error(
                    ManageLearnersForm.Fields.BULK_UPLOAD, error)
            return

        # There were no errors. Now do the actual linking:
        for email in emails:
            EnterpriseCustomerUser.objects.link_user(enterprise_customer,
                                                     email)

        # Report what happened:
        count = len(emails)
        messages.success(
            request,
            ungettext(
                "{count} new user was linked to {enterprise_customer_name}.",
                "{count} new users were linked to {enterprise_customer_name}.",
                count).format(
                    count=count,
                    enterprise_customer_name=enterprise_customer.name))
        if already_linked_emails:
            messages.warning(
                request,
                _("Some users were already linked to this Enterprise Customer: {list_of_emails}"
                  ).format(list_of_emails=", ".join(already_linked_emails)))
        if duplicate_emails:
            messages.warning(
                request,
                _("Some duplicate emails in the CSV were ignored: {list_of_emails}"
                  ).format(list_of_emails=", ".join(duplicate_emails)))
        return list(emails) + already_linked_emails
Example #11
0
    def _handle_bulk_upload(cls,
                            enterprise_customer,
                            manage_learners_form,
                            request,
                            email_list=None):
        """
        Bulk link users by email.

        Arguments:
            enterprise_customer (EnterpriseCustomer): learners will be linked to this Enterprise Customer instance
            manage_learners_form (ManageLearnersForm): bound ManageLearners form instance
            request (django.http.request.HttpRequest): HTTP Request instance
            email_list (iterable): A list of pre-processed email addresses to handle using the form
        """
        errors = []
        emails = set()
        already_linked_emails = []
        duplicate_emails = []
        csv_file = manage_learners_form.cleaned_data[
            ManageLearnersForm.Fields.BULK_UPLOAD]
        if email_list:
            parsed_csv = [{
                ManageLearnersForm.CsvColumns.EMAIL: email
            } for email in email_list]
        else:
            parsed_csv = parse_csv(
                csv_file,
                expected_columns={ManageLearnersForm.CsvColumns.EMAIL})

        try:
            for index, row in enumerate(parsed_csv):
                email = row[ManageLearnersForm.CsvColumns.EMAIL]
                try:
                    already_linked = validate_email_to_link(
                        email, ignore_existing=True)
                except ValidationError as exc:
                    message = _("Error at line {line}: {message}\n").format(
                        line=index + 1, message=exc)
                    errors.append(message)
                else:
                    if already_linked:
                        already_linked_emails.append(
                            (email, already_linked.enterprise_customer))
                    elif email in emails:
                        duplicate_emails.append(email)
                    else:
                        emails.add(email)
        except ValidationError as exc:
            errors.append(exc)

        if errors:
            manage_learners_form.add_error(
                ManageLearnersForm.Fields.GENERAL_ERRORS,
                ValidationMessages.BULK_LINK_FAILED)
            for error in errors:
                manage_learners_form.add_error(
                    ManageLearnersForm.Fields.BULK_UPLOAD, error)
            return

        # There were no errors. Now do the actual linking:
        for email in emails:
            EnterpriseCustomerUser.objects.link_user(enterprise_customer,
                                                     email)

        # Report what happened:
        count = len(emails)
        messages.success(
            request,
            ungettext(
                "{count} new learner was added to {enterprise_customer_name}.",
                "{count} new learners were added to {enterprise_customer_name}.",
                count).format(
                    count=count,
                    enterprise_customer_name=enterprise_customer.name))
        this_customer_linked_emails = [
            email for email, customer in already_linked_emails
            if customer == enterprise_customer
        ]
        other_customer_linked_emails = [
            email for email, __ in already_linked_emails
            if email not in this_customer_linked_emails
        ]
        if this_customer_linked_emails:
            messages.warning(
                request,
                _("The following learners were already associated with this Enterprise "
                  "Customer: {list_of_emails}").format(
                      list_of_emails=", ".join(this_customer_linked_emails)))
        if other_customer_linked_emails:
            messages.warning(
                request,
                _("The following learners are already associated with "
                  "another Enterprise Customer. These learners were not "
                  "added to {enterprise_customer_name}: {list_of_emails}").
                format(
                    enterprise_customer_name=enterprise_customer.name,
                    list_of_emails=", ".join(other_customer_linked_emails),
                ))
        if duplicate_emails:
            messages.warning(
                request,
                _("The following duplicate email addresses were not added: "
                  "{list_of_emails}").format(
                      list_of_emails=", ".join(duplicate_emails)))
        # Build a list of all the emails that we can act on further; that is,
        # emails that we either linked to this customer, or that were linked already.
        all_processable_emails = list(emails) + this_customer_linked_emails

        return all_processable_emails