Commit 533c4977 authored by fjgarlin's avatar fjgarlin Committed by drumm
Browse files

Issue #3302622: Isolate the logic to validate a gitlab username so it can be reused

parent 05fcc4ce
......@@ -35,6 +35,12 @@ define('DRUPALORG_GIT_GATECTL_SANDBOXES', 0x04);
// defining this constant in hopeful anticipation :)
// define('DRUPALORG_GIT_GATECTL_ISSUES', 0x08);
define('DRUPALORG_GIT_USERNAME_TAKEN', 'username_taken');
define('DRUPALORG_GIT_USERNAME_INVALID_PATTERN', 'username_invalid_pattern');
define('DRUPALORG_GIT_USERNAME_INVALID_CONTAINS_RESERVED_NAME', 'username_invalid_reserved_name');
define('DRUPALORG_GIT_USERNAME_INVALID_CONTAINS_FILE_EXTENSION', 'username_invalid_file_extension');
define('DRUPALORG_GIT_USERNAME_VALID', 'username_valid');
/**
* Implements hook_menu().
*/
......@@ -324,3 +330,45 @@ function drupalorg_git_gateway_mail($key, &$message, $params = array()) {
return;
}
}
/**
* Validation of username.
*
* @param string $username
* Username to check.
* @param int $uid
* Id of the user the username is attached to.
*
* @return int
* Code that explains if it's a valid username or not, and why.
*/
function drupalorg_git_gateway_username_check($username, $uid) {
// Ensure the requested ID isn't taken.
if ($uid = db_query("SELECT uid FROM {users} WHERE git_username = :git_username AND uid <> :uid", [':git_username' => $username, ':uid' => $uid])->fetchField()) {
return DRUPALORG_GIT_USERNAME_TAKEN;
}
// And is a valid pattern. Adapted from NAMESPACE_FORMAT_REGEX in
// https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/path_regex.rb
// and project_name_regex in
// https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/regex.rb
// since Git usernames are used in sandbox project names.
elseif (!preg_match('/^(?:[a-zA-Z0-9_][a-zA-Z0-9_\-\.]*[a-zA-Z0-9_\-]|[a-zA-Z0-9_])(?<!\.git|\.atom)$/', $username)) {
return DRUPALORG_GIT_USERNAME_INVALID_PATTERN;
}
elseif (in_array(drupal_strtolower($username), variable_get('drupalorg_git_reserved_names', []))) {
return DRUPALORG_GIT_USERNAME_INVALID_CONTAINS_RESERVED_NAME;
}
elseif (preg_match('/\.([^.]*)$/', $username, $match) && in_array($match[1], ['html', 'xhtml', 'text', 'txt', 'js', 'css', 'ics', 'csv', 'vcf', 'vtt', 'png', 'jpeg', 'jpg', 'jpe', 'pjpeg', 'gif', 'bmp', 'tiff', 'tif', 'svg', 'mpeg', 'mpg', 'mpe', 'mp3', 'mp1', 'mp2', 'ogg', 'oga', 'spx', 'opus', 'm4a', 'mpg4', 'aac', 'webm', 'mp4', 'm4v', 'otf', 'ttf', 'woff', 'woff2', 'xml', 'rss', 'atom', 'yaml', 'yml', 'multipart_form', 'url_encoded_form', 'pdf', 'zip', 'gzip', 'gz', 'diff', 'patch', 'markdown', 'md', 'mov', 'ogv', 'json', 'ico'])) {
return DRUPALORG_GIT_USERNAME_INVALID_CONTAINS_FILE_EXTENSION;
}
return DRUPALORG_GIT_USERNAME_VALID;
}
/**
* Suggest a valid gitlab username.
*/
function drupalorg_git_gateway_username_prepare($username) {
$username = drupal_strtolower($username);
return preg_replace('/[^A-Za-z0-9\._-]/', '', $username);
}
......@@ -359,22 +359,17 @@ function drupalorg_git_gateway_user_form_base_validate($form, &$form_state) {
* Element validate callback.
*/
function drupalorg_git_gateway_username_validate($element, $form_state) {
// Ensure the requested ID isn't taken.
if ($uid = db_query("SELECT uid FROM {users} WHERE git_username = :git_username AND uid <> :uid", [':git_username' => $element['#value'], ':uid' => $form_state['account']->uid])->fetchField()) {
$username_check = drupalorg_git_gateway_username_check($element['#value'], $form_state['account']->uid);
if ($username_check == DRUPALORG_GIT_USERNAME_TAKEN) {
form_set_error('git_username', t('The requested Git username is already taken.'));
}
// And is a valid pattern. Adapted from NAMESPACE_FORMAT_REGEX in
// https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/path_regex.rb
// and project_name_regex in
// https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/regex.rb
// since Git usernames are used in sandbox project names.
elseif (!preg_match('/^(?:[a-zA-Z0-9_][a-zA-Z0-9_\-\.]*[a-zA-Z0-9_\-]|[a-zA-Z0-9_])(?<!\.git|\.atom)$/', $element['#value'])) {
elseif ($username_check == DRUPALORG_GIT_USERNAME_INVALID_PATTERN) {
form_set_error('git_username', t('The requested username contains invalid characters.'));
}
elseif (in_array(drupal_strtolower($element['#value']), variable_get('drupalorg_git_reserved_names', []))) {
elseif ($username_check == DRUPALORG_GIT_USERNAME_INVALID_CONTAINS_RESERVED_NAME) {
form_set_error('git_username', t('The requested username is reserved, please choose a different Git username.'));
}
elseif (preg_match('/\.([^.]*)$/', $element['#value'], $match) && in_array($match[1], ['html', 'xhtml', 'text', 'txt', 'js', 'css', 'ics', 'csv', 'vcf', 'vtt', 'png', 'jpeg', 'jpg', 'jpe', 'pjpeg', 'gif', 'bmp', 'tiff', 'tif', 'svg', 'mpeg', 'mpg', 'mpe', 'mp3', 'mp1', 'mp2', 'ogg', 'oga', 'spx', 'opus', 'm4a', 'mpg4', 'aac', 'webm', 'mp4', 'm4v', 'otf', 'ttf', 'woff', 'woff2', 'xml', 'rss', 'atom', 'yaml', 'yml', 'multipart_form', 'url_encoded_form', 'pdf', 'zip', 'gzip', 'gz', 'diff', 'patch', 'markdown', 'md', 'mov', 'ogv', 'json', 'ico'])) {
elseif ($username_check == DRUPALORG_GIT_USERNAME_INVALID_CONTAINS_FILE_EXTENSION) {
form_set_error('git_username', t('The requested username is reserved, please choose a different Git username.'));
}
}
......
Supports Markdown
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