예제 #1
0
def generate_username_suggestions(name):
    """ Generate 3 available username suggestions """
    username_suggestions = []
    max_length = USERNAME_MAX_LENGTH
    names = name.split(' ')
    if names:
        first_name = remove_special_characters_from_name(names[0].lower())
        last_name = remove_special_characters_from_name(names[-1].lower())

        if first_name != last_name and first_name:
            # username combination of first and last name
            suggestion = f'{first_name}{last_name}'[:max_length]
            if not username_exists_or_retired(suggestion):
                username_suggestions.append(suggestion)

            # username is combination of first letter of first name and last name
            suggestion = f'{first_name[0]}-{last_name}'[:max_length]
            if not username_exists_or_retired(suggestion):
                username_suggestions.append(suggestion)

        if len(first_name) >= 2:

            short_username = first_name[:max_length -
                                        6] if max_length is not None else first_name
            short_username = short_username.replace('_', '').replace('-', '')

            int_ranges = [
                {
                    'min': 0,
                    'max': 9
                },
                {
                    'min': 10,
                    'max': 99
                },
                {
                    'min': 100,
                    'max': 999
                },
                {
                    'min': 1000,
                    'max': 99999
                },
            ]
            for int_range in int_ranges:
                for _ in range(10):
                    random_int = random.randint(int_range['min'],
                                                int_range['max'])
                    suggestion = f'{short_username}_{random_int}'
                    if not username_exists_or_retired(suggestion):
                        username_suggestions.append(suggestion)
                        break

                if len(username_suggestions) == 3:
                    break

    return username_suggestions
예제 #2
0
    def _handle_duplicate_email_username(self, request, data):
        # pylint: disable=no-member
        # TODO Verify whether this check is needed here - it may be duplicated in user_api.
        email = data.get('email')
        username = data.get('username')
        errors = {}

        # TODO: remove the is_authn_mfe check and use the new error message as default after redesign
        is_authn_mfe = data.get('is_authn_mfe', False)

        error_code = 'duplicate'
        if email is not None and email_exists_or_retired(email):
            error_code += '-email'
            error_message = accounts_settings.AUTHN_EMAIL_CONFLICT_MSG if is_authn_mfe else (
                accounts_settings.EMAIL_CONFLICT_MSG.format(email_address=email)
            )
            errors['email'] = [{'user_message': error_message}]

        if username is not None and username_exists_or_retired(username):
            error_code += '-username'
            error_message = accounts_settings.AUTHN_USERNAME_CONFLICT_MSG if is_authn_mfe else (
                accounts_settings.USERNAME_CONFLICT_MSG.format(username=username)
            )
            errors['username'] = [{'user_message': error_message}]
            errors['username_suggestions'] = generate_username_suggestions(username)

        if errors:
            return self._create_response(request, errors, status_code=409, error_code=error_code)
예제 #3
0
def generate_username_suggestions(username):
    """ Generate 3 available username suggestions """
    max_length = USERNAME_MAX_LENGTH
    short_username = username[:max_length -
                              4] if max_length is not None else username

    username_suggestions = []
    int_ranges = {
        1: {
            'min': 0,
            'max': 9
        },
        2: {
            'min': 10,
            'max': 99
        },
        3: {
            'min': 100,
            'max': 999
        },
    }
    while len(username_suggestions) < 3:
        int_length = len(username_suggestions) + 1
        int_range = int_ranges[int_length]
        random_int = random.randint(int_range['min'], int_range['max'])
        username = f'{short_username}_{random_int}'
        if not username_exists_or_retired(username):
            username_suggestions.append(username)

    return username_suggestions
예제 #4
0
    def _handle_duplicate_email_username(self, request, data):
        # pylint: disable=no-member
        # TODO Verify whether this check is needed here - it may be duplicated in user_api.
        email = data.get('email')
        username = data.get('username')
        errors = {}

        error_code = 'duplicate'
        if email is not None and email_exists_or_retired(email):
            error_code += '-email'
            errors["email"] = [{
                "user_message":
                accounts_settings.EMAIL_CONFLICT_MSG.format(
                    email_address=email)
            }]

        if username is not None and username_exists_or_retired(username):
            error_code += '-username'
            errors["username"] = [{
                "user_message":
                accounts_settings.USERNAME_CONFLICT_MSG.format(
                    username=username)
            }]

        if errors:
            return self._create_response(request,
                                         errors,
                                         status_code=409,
                                         error_code=error_code)
예제 #5
0
def generate_username_suggestions(username):
    """ Generate 3 available username suggestions """
    max_length = USERNAME_MAX_LENGTH
    short_username = username[:max_length - 6] if max_length is not None else username
    short_username = short_username.replace('_', '').replace('-', '')

    username_suggestions = []
    int_ranges = [
        {'min': 0, 'max': 9},
        {'min': 10, 'max': 99},
        {'min': 100, 'max': 999},
        {'min': 1000, 'max': 99999},
    ]
    for int_range in int_ranges:
        for _ in range(10):
            random_int = random.randint(int_range['min'], int_range['max'])
            suggestion = f'{short_username}_{random_int}'
            if not username_exists_or_retired(suggestion):
                username_suggestions.append(suggestion)
                break

        if len(username_suggestions) == 3:
            break

    return username_suggestions
예제 #6
0
def _validate_username_doesnt_exist(username):
    """Validate that the username is not associated with an existing user.

    :param username: The proposed username (unicode).
    :return: None
    :raises: errors.AccountUsernameAlreadyExists
    """
    if username is not None and username_exists_or_retired(username):
        raise errors.AccountUsernameAlreadyExists(_(accounts.USERNAME_CONFLICT_MSG).format(username=username))
예제 #7
0
def check_edxapp_account_conflicts(email, username):
    """
    Exposed function to check conflicts
    """
    conflicts = []

    if username and username_exists_or_retired(username):
        conflicts.append("username")

    if email and email_exists_or_retired(email):
        conflicts.append("email")

    return conflicts
예제 #8
0
def generate_username_suggestions(username):
    """ Generate available username suggestions """
    min_length = accounts.USERNAME_MIN_LENGTH
    max_length = accounts.USERNAME_MAX_LENGTH
    short_username = username[:max_length - min_length] if max_length is not None else username

    username_suggestions = []
    while len(username_suggestions) < 3:
        username = f'{short_username}_{uuid4().hex[:min_length]}'
        if not username_exists_or_retired(username):
            username_suggestions.append(username)

    return username_suggestions
예제 #9
0
파일: api.py 프로젝트: sekz/edx-platform
def _validate_username_doesnt_exist(username, api_version='v1'):
    """Validate that the username is not associated with an existing user.

    :param username: The proposed username (unicode).
    :param api_version: Validation API version; it is used to determine the error message
    :return: None
    :raises: errors.AccountUsernameAlreadyExists
    """
    if api_version == 'v1':
        error_message = accounts.USERNAME_CONFLICT_MSG.format(username=username)
    else:
        error_message = accounts.AUTHN_USERNAME_CONFLICT_MSG
    if username is not None and username_exists_or_retired(username):
        raise errors.AccountUsernameAlreadyExists(_(error_message))  # lint-amnesty, pylint: disable=translation-of-non-string
예제 #10
0
def do_create_account(form, custom_form=None):
    """
    Given cleaned post variables, create the User and UserProfile objects, as well as the
    registration for this user.

    Returns a tuple (User, UserProfile, Registration).

    Note: this function is also used for creating test users.
    """
    # Check if ALLOW_PUBLIC_ACCOUNT_CREATION flag turned off to restrict user account creation
    if not configuration_helpers.get_value(
            'ALLOW_PUBLIC_ACCOUNT_CREATION',
            settings.FEATURES.get('ALLOW_PUBLIC_ACCOUNT_CREATION', True)):
        raise PermissionDenied()

    errors = {}
    errors.update(form.errors)
    if custom_form:
        errors.update(custom_form.errors)

    if errors:
        raise ValidationError(errors)

    proposed_username = form.cleaned_data["username"]
    user = User(username=proposed_username,
                email=form.cleaned_data["email"],
                is_active=False)
    password = normalize_password(form.cleaned_data["password"])
    user.set_password(password)
    registration = Registration()

    # TODO: Rearrange so that if part of the process fails, the whole process fails.
    # Right now, we can have e.g. no registration e-mail sent out and a zombie account
    try:
        with transaction.atomic():
            user.save()
            if custom_form:
                custom_model = custom_form.save(commit=False)
                custom_model.user = user
                custom_model.save()
    except IntegrityError:
        # Figure out the cause of the integrity error
        # TODO duplicate email is already handled by form.errors above as a ValidationError.
        # The checks for duplicate email/username should occur in the same place with an
        # AccountValidationError and a consistent user message returned (i.e. both should
        # return "It looks like {username} belongs to an existing account. Try again with a
        # different username.")
        if username_exists_or_retired(user.username):
            raise AccountValidationError(
                USERNAME_EXISTS_MSG_FMT.format(username=proposed_username),
                field="username")
        elif email_exists_or_retired(user.email):
            raise AccountValidationError(_(
                "An account with the Email '{email}' already exists.").format(
                    email=user.email),
                                         field="email")
        else:
            raise

    registration.register(user)

    profile_fields = [
        "name", "level_of_education", "gender", "mailing_address", "city",
        "country", "goals", "year_of_birth"
    ]
    profile = UserProfile(
        user=user,
        **{key: form.cleaned_data.get(key)
           for key in profile_fields})
    extended_profile = form.cleaned_extended_profile
    if extended_profile:
        profile.meta = json.dumps(extended_profile)
    try:
        profile.save()
    except Exception:
        log.exception(
            "UserProfile creation failed for user {id}.".format(id=user.id))
        raise

    return user, profile, registration