Commit 78b6d662 authored by Timothy Andrew's avatar Timothy Andrew

Allow registering users where the username contains dots (.).

Javascript does not support the negative lookbehind assertion (?<!) used
in the Ruby regex (to disallow usernames ending in `.git` or `.atom`.

Getting the client side code to fully support this format is
non-trivial, since we'd either have to heavily complicate the
regex used, or modify the frontend code to support more complex
validation schemes (it currently uses HTML5 validations).

The pragmatic choice is to create a
`Gitlab::Regex::NAMESPACE_REGEX_STR_SIMPLE` regex to serve as a
Javascript-compatible version of `NAMESPACE_REGEX_STR`.

The client-side code will not display an error for usernames ending in
`.git` and `.atom`, but these will be caught by the server-side
validation.
parent b33791d8
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
= f.text_field :name, class: "form-control top", required: true, title: "This field is required." = f.text_field :name, class: "form-control top", required: true, title: "This field is required."
%div.username.form-group %div.username.form-group
= f.label :username = f.label :username
= f.text_field :username, class: "form-control middle", pattern: "[a-zA-Z0-9]+", required: true, title: 'Please create a username with only alphanumeric characters.' = f.text_field :username, class: "form-control middle", pattern: Gitlab::Regex::NAMESPACE_REGEX_STR_SIMPLE, required: true, title: 'Please create a username with only alphanumeric characters.'
%p.validation-error.hide Username is already taken. %p.validation-error.hide Username is already taken.
%p.validation-success.hide Username is available. %p.validation-success.hide Username is available.
%p.validation-pending.hide Checking username availability... %p.validation-pending.hide Checking username availability...
......
...@@ -2,7 +2,14 @@ module Gitlab ...@@ -2,7 +2,14 @@ module Gitlab
module Regex module Regex
extend self extend self
NAMESPACE_REGEX_STR = '(?:[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*[a-zA-Z0-9_\-]|[a-zA-Z0-9_])(?<!\.git|\.atom)'.freeze # The namespace regex is used in Javascript to validate usernames in the "Register" form. However, Javascript
# does not support the negative lookbehind assertion (?<!) that disallows usernames ending in `.git` and `.atom`.
# Since this is a non-trivial problem to solve in Javascript (heavily complicate the regex, modify view code to
# allow non-regex validatiions, etc), `NAMESPACE_REGEX_STR_SIMPLE` serves as a Javascript-compatible version of
# `NAMESPACE_REGEX_STR`, with the negative lookbehind assertion removed. This means that the client-side validation
# will pass for usernames ending in `.atom` and `.git`, but will be caught by the server-side validation.
NAMESPACE_REGEX_STR_SIMPLE = '[a-zA-Z0-9_\.][a-zA-Z0-9_\-\.]*[a-zA-Z0-9_\-]|[a-zA-Z0-9_]'.freeze
NAMESPACE_REGEX_STR = "(?:#{NAMESPACE_REGEX_STR_SIMPLE})(?<!\.git|\.atom)".freeze
def namespace_regex def namespace_regex
@namespace_regex ||= /\A#{NAMESPACE_REGEX_STR}\z/.freeze @namespace_regex ||= /\A#{NAMESPACE_REGEX_STR}\z/.freeze
......
...@@ -74,16 +74,29 @@ feature 'Users', feature: true, js: true do ...@@ -74,16 +74,29 @@ feature 'Users', feature: true, js: true do
visit new_user_session_path visit new_user_session_path
click_link 'Register' click_link 'Register'
end end
scenario 'doesn\'t show an error border if the username is available' do
fill_in username_input, with: 'new-user'
wait_for_ajax
expect(find('.username')).not_to have_css '.gl-field-error-outline'
end
scenario 'does not show an error border if the username contains dots (.)' do
fill_in username_input, with: 'new.user.username'
wait_for_ajax
expect(find('.username')).not_to have_css '.gl-field-error-outline'
end
scenario 'shows an error border if the username already exists' do scenario 'shows an error border if the username already exists' do
fill_in username_input, with: user.username fill_in username_input, with: user.username
wait_for_ajax wait_for_ajax
expect(find('.username')).to have_css '.gl-field-error-outline' expect(find('.username')).to have_css '.gl-field-error-outline'
end end
scenario 'doesn\'t show an error border if the username is available' do scenario 'shows an error border if the username contains special characters' do
fill_in username_input, with: 'new-user' fill_in username_input, with: 'new$user!username'
wait_for_ajax wait_for_ajax
expect(find('#new_user_username')).not_to have_css '.gl-field-error-outline' expect(find('.username')).to have_css '.gl-field-error-outline'
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment