示例#1
0
 def test_password_bad_min_length_validation_decision(self):
     password = '******' * (password_min_length() - 1)
     msg = u'Enter a password with at least {0} characters.'.format(password_min_length())
     self.assertValidationDecision(
         {'password': password},
         {"password": msg}
     )
示例#2
0
 def test_password_bad_min_length_validation_decision(self):
     password = '******' * (password_min_length() - 1)
     msg = u'Enter a password with at least {0} characters.'.format(password_min_length())
     self.assertValidationDecision(
         {'password': password},
         {"password": msg}
     )
示例#3
0
    def _add_password_field(self, form_desc, required=True):
        """Add a password field to a form description.
        Arguments:
            form_desc: A form description
        Keyword Arguments:
            required (bool): Whether this field is required; defaults to True
        """
        # Translators: This label appears above a field on the registration form
        # meant to hold the user's password.
        password_label = _(u"Password")

        restrictions = {
            "min_length": password_min_length(),
            "max_length": password_max_length(),
        }

        complexities = password_complexity()
        for key, value in complexities.iteritems():
            api_key = key.lower().replace(' ', '_')
            restrictions[api_key] = value

        form_desc.add_field(
            "password",
            label=password_label,
            field_type="password",
            instructions=password_instructions(),
            restrictions=restrictions,
            required=required
        )
示例#4
0
    def _add_password_field(self, form_desc, required=True):
        """Add a password field to a form description.
        Arguments:
            form_desc: A form description
        Keyword Arguments:
            required (bool): Whether this field is required; defaults to True
        """
        # Translators: This label appears above a field on the registration form
        # meant to hold the user's password.
        password_label = _(u"Password")

        restrictions = {
            "min_length": password_min_length(),
            "max_length": password_max_length(),
        }

        complexities = password_complexity()
        for key, value in complexities.iteritems():
            api_key = key.lower().replace(' ', '_')
            restrictions[api_key] = value

        form_desc.add_field("password",
                            label=password_label,
                            field_type="password",
                            instructions=password_instructions(),
                            restrictions=restrictions,
                            required=required)
    def test_unicode_password(self):
        """ Tests that validate_password enforces unicode """
        byte_str = b'Ёдно'
        unicode_str = u'Ёдно'

        # Sanity checks and demonstration of why this test is useful
        self.assertEqual(len(byte_str), 4)
        self.assertEqual(len(unicode_str), 1)
        self.assertEqual(password_min_length(), 2)

        # Test length check
        with self.assertRaises(ValidationError):
            validate_password(byte_str)
        validate_password(byte_str + byte_str)

        # Test badly encoded password
        with self.assertRaises(ValidationError) as cm:
            validate_password(b'\xff\xff')
        self.assertEquals('Invalid password.', cm.exception.message)
    def test_unicode_password(self):
        """ Tests that validate_password enforces unicode """
        byte_str = b'Ёдно'
        unicode_str = u'Ёдно'

        # Sanity checks and demonstration of why this test is useful
        self.assertEqual(len(byte_str), 4)
        self.assertEqual(len(unicode_str), 1)
        self.assertEqual(password_min_length(), 2)

        # Test length check
        with self.assertRaises(ValidationError):
            validate_password(byte_str)
        validate_password(byte_str + byte_str)

        # Test badly encoded password
        with self.assertRaises(ValidationError) as cm:
            validate_password(b'\xff\xff')
        self.assertEquals('Invalid password.', cm.exception.message)
示例#7
0
    def _add_password_field(self, form_desc, required=True):
        """Add a password field to a form description.
        Arguments:
            form_desc: A form description
        Keyword Arguments:
            required (bool): Whether this field is required; defaults to True
        """
        # Translators: This label appears above a field on the registration form
        # meant to hold the user's password.
        password_label = _(u"Password")

        form_desc.add_field(
            "password",
            label=password_label,
            field_type="password",
            restrictions={
                "min_length": password_min_length(),
                "max_length": password_max_length(),
            },
            required=required
        )
示例#8
0
class AccountCreationForm(forms.Form):
    """
    A form to for account creation data. It is currently only used for
    validation, not rendering.
    """

    _EMAIL_INVALID_MSG = _("A properly formatted e-mail is required")
    _PASSWORD_INVALID_MSG = _("A valid password is required")
    _NAME_TOO_SHORT_MSG = _(
        "Your legal name must be a minimum of two characters long")

    # TODO: Resolve repetition

    username = UsernameField()

    email = forms.EmailField(
        max_length=accounts_settings.EMAIL_MAX_LENGTH,
        min_length=accounts_settings.EMAIL_MIN_LENGTH,
        error_messages={
            "required":
            _EMAIL_INVALID_MSG,
            "invalid":
            _EMAIL_INVALID_MSG,
            "max_length":
            _("Email cannot be more than %(limit_value)s characters long"),
        })
    password = forms.CharField(min_length=password_min_length(),
                               max_length=password_max_length(),
                               error_messages={
                                   "required": _PASSWORD_INVALID_MSG,
                                   "min_length": _PASSWORD_INVALID_MSG,
                                   "max_length": _PASSWORD_INVALID_MSG,
                               })
    name = forms.CharField(min_length=accounts_settings.NAME_MIN_LENGTH,
                           error_messages={
                               "required": _NAME_TOO_SHORT_MSG,
                               "min_length": _NAME_TOO_SHORT_MSG,
                           },
                           validators=[validate_name])

    def __init__(self,
                 data=None,
                 extra_fields=None,
                 extended_profile_fields=None,
                 enforce_password_policy=False,
                 tos_required=True):
        super(AccountCreationForm, self).__init__(data)

        extra_fields = extra_fields or {}
        self.extended_profile_fields = extended_profile_fields or {}
        self.enforce_password_policy = enforce_password_policy
        if tos_required:
            self.fields["terms_of_service"] = TrueField(
                error_messages={
                    "required": _("You must accept the terms of service.")
                })

        # TODO: These messages don't say anything about minimum length
        error_message_dict = {
            "level_of_education": _("A level of education is required"),
            "gender": _("Your gender is required"),
            "year_of_birth": _("Your year of birth is required"),
            "mailing_address": _("Your mailing address is required"),
            "goals": _("A description of your goals is required"),
            "city": _("A city is required"),
            "country": _("A country is required")
        }
        for field_name, field_value in extra_fields.items():
            if field_name not in self.fields:
                if field_name == "honor_code":
                    if field_value == "required":
                        self.fields[field_name] = TrueField(
                            error_messages={
                                "required":
                                _("To enroll, you must follow the honor code.")
                            })
                else:
                    required = field_value == "required"
                    min_length = 1 if field_name in (
                        "gender", "level_of_education") else 2
                    error_message = error_message_dict.get(
                        field_name,
                        _("You are missing one or more required fields"))
                    self.fields[field_name] = forms.CharField(
                        required=required,
                        min_length=min_length,
                        error_messages={
                            "required": error_message,
                            "min_length": error_message,
                        })

        for field in self.extended_profile_fields:
            if field not in self.fields:
                self.fields[field] = forms.CharField(required=False)

    def clean_password(self):
        """Enforce password policies (if applicable)"""
        password = self.cleaned_data["password"]
        if self.enforce_password_policy:
            validate_password(password,
                              username=self.cleaned_data.get('username'))
        return password

    def clean_email(self):
        """ Enforce email restrictions (if applicable) """
        email = self.cleaned_data["email"]
        if settings.REGISTRATION_EMAIL_PATTERNS_ALLOWED is not None:
            # This Open edX instance has restrictions on what email addresses are allowed.
            allowed_patterns = settings.REGISTRATION_EMAIL_PATTERNS_ALLOWED
            # We append a '$' to the regexs to prevent the common mistake of using a
            # pattern like '.*@edx\\.org' which would match '*****@*****.**'
            if not any(
                    re.match(pattern + "$", email)
                    for pattern in allowed_patterns):
                # This email is not on the whitelist of allowed emails. Check if
                # they may have been manually invited by an instructor and if not,
                # reject the registration.
                if not CourseEnrollmentAllowed.objects.filter(
                        email=email).exists():
                    raise ValidationError(_("Unauthorized email address."))
        if email_exists_or_retired(email):
            raise ValidationError(
                _("It looks like {email} belongs to an existing account. Try again with a different email address."
                  ).format(email=email))
        return email

    def clean_year_of_birth(self):
        """
        Parse year_of_birth to an integer, but just use None instead of raising
        an error if it is malformed
        """
        try:
            year_str = self.cleaned_data["year_of_birth"]
            return int(year_str) if year_str is not None else None
        except ValueError:
            return None

    @property
    def cleaned_extended_profile(self):
        """
        Return a dictionary containing the extended_profile_fields and values
        """
        return {
            key: value
            for key, value in self.cleaned_data.items()
            if key in self.extended_profile_fields and value is not None
        }
示例#9
0
 def test_password_empty_validation_decision(self):
     msg = u'Enter a password with at least {0} characters.'.format(password_min_length())
     self.assertValidationDecision(
         {'password': ''},
         {"password": msg}
     )
示例#10
0
 def test_password_empty_validation_decision(self):
     msg = u'Enter a password with at least {0} characters.'.format(password_min_length())
     self.assertValidationDecision(
         {'password': ''},
         {"password": msg}
     )
示例#11
0
]

INVALID_PASSWORDS = [None, u'', u'a', u'a' * (password_max_length() + 1)]

INVALID_COUNTRIES = [None, "", "--"]

VALID_NAMES = ['Validation Bot', u'Validation Bot']

VALID_USERNAMES_UNICODE = [
    u'Enchanté',
    u'username_with_@',
    u'username with spaces',
    u'eastern_arabic_numbers_١٢٣',
]

VALID_USERNAMES = [
    u'username', u'a' * USERNAME_MIN_LENGTH, u'a' * USERNAME_MAX_LENGTH,
    u'-' * USERNAME_MIN_LENGTH, u'-' * USERNAME_MAX_LENGTH, u'_username_',
    u'-username-', u'-_username_-'
]

VALID_EMAILS = ['*****@*****.**']

VALID_PASSWORDS = [
    u'password',  # :)
    u'a' * password_min_length(),
    u'a' * password_max_length()
]

VALID_COUNTRIES = [u'PK', u'Pakistan', u'US']
示例#12
0
 def test_password_bad_min_length_validation_decision(self):
     password = '******' * (password_min_length() - 1)
     msg = u'Password: Invalid Length (must be {0} characters or more)'.format(
         password_min_length())
     self.assertValidationDecision({'password': password},
                                   {"password": msg})
示例#13
0
 def test_password_empty_validation_decision(self):
     msg = u'Password: Invalid Length (must be {0} characters or more)'.format(
         password_min_length())
     self.assertValidationDecision({'password': ''}, {"password": msg})
示例#14
0
    u'username with spaces',
    u'eastern_arabic_numbers_١٢٣',
]

VALID_USERNAMES = [
    u'username',
    u'a' * USERNAME_MIN_LENGTH,
    u'a' * USERNAME_MAX_LENGTH,
    u'-' * USERNAME_MIN_LENGTH,
    u'-' * USERNAME_MAX_LENGTH,
    u'_username_',
    u'-username-',
    u'-_username_-'
]

VALID_EMAILS = [
    '*****@*****.**'
]

VALID_PASSWORDS = [
    u'password',  # :)
    u'a' * password_min_length(),
    u'a' * password_max_length()
]

VALID_COUNTRIES = [
    u'PK',
    u'Pakistan',
    u'US'
]