This instance was upgraded to Heptapod 0.27.2 on 2021-12-08 at 22:00 UTC+1

Commit 43b17508 authored by Douwe Maan's avatar Douwe Maan
Browse files

Revert "Remove changes that are not absolutely necessary"

This reverts commit f0fc11a523e8
parent bbab187a9726
...@@ -74,6 +74,6 @@ def logs_tree ...@@ -74,6 +74,6 @@ def logs_tree
private private
def validate_ref_id def validate_ref_id
return not_found! if params[:id].present? && params[:id] !~ Gitlab::Regex.git_reference_regex return not_found! if params[:id].present? && params[:id] !~ Gitlab::PathRegex.git_reference_regex
end end
end end
...@@ -205,8 +205,8 @@ def update_forks_visibility_level ...@@ -205,8 +205,8 @@ def update_forks_visibility_level
presence: true, presence: true,
dynamic_path: true, dynamic_path: true,
length: { maximum: 255 }, length: { maximum: 255 },
format: { with: Gitlab::Regex.project_path_format_regex, format: { with: Gitlab::PathRegex.project_path_format_regex,
message: Gitlab::Regex.project_path_regex_message }, message: Gitlab::PathRegex.project_path_format_message },
uniqueness: { scope: :namespace_id } uniqueness: { scope: :namespace_id }
validates :namespace, presence: true validates :namespace, presence: true
...@@ -380,11 +380,9 @@ def sort(method) ...@@ -380,11 +380,9 @@ def sort(method)
end end
def reference_pattern def reference_pattern
name_pattern = Gitlab::Regex::FULL_NAMESPACE_REGEX_STR
%r{ %r{
((?<namespace>#{name_pattern})\/)? ((?<namespace>#{Gitlab::PathRegex::FULL_NAMESPACE_FORMAT_REGEX})\/)?
(?<project>#{name_pattern}) (?<project>#{Gitlab::PathRegex::PROJECT_PATH_FORMAT_REGEX})
}x }x
end end
......
...@@ -367,7 +367,7 @@ def reference_prefix ...@@ -367,7 +367,7 @@ def reference_prefix
def reference_pattern def reference_pattern
%r{ %r{
#{Regexp.escape(reference_prefix)} #{Regexp.escape(reference_prefix)}
(?<user>#{Gitlab::Regex::FULL_NAMESPACE_REGEX_STR}) (?<user>#{Gitlab::PathRegex::FULL_NAMESPACE_FORMAT_REGEX})
}x }x
end end
......
...@@ -3,16 +3,20 @@ ...@@ -3,16 +3,20 @@
# Custom validator for GitLab path values. # Custom validator for GitLab path values.
# These paths are assigned to `Namespace` (& `Group` as a subclass) & `Project` # These paths are assigned to `Namespace` (& `Group` as a subclass) & `Project`
# #
# Values are checked for formatting and exclusion from a list of reserved path # Values are checked for formatting and exclusion from a list of illegal path
# names. # names.
class DynamicPathValidator < ActiveModel::EachValidator class DynamicPathValidator < ActiveModel::EachValidator
class << self class << self
def valid_namespace_path?(path) def valid_user_path?(path)
"#{path}/" =~ Gitlab::Regex.full_namespace_path_regex "#{path}/" =~ Gitlab::PathRegex.root_namespace_path_regex
end
def valid_group_path?(path)
"#{path}/" =~ Gitlab::PathRegex.full_namespace_path_regex
end end
def valid_project_path?(path) def valid_project_path?(path)
"#{path}/" =~ Gitlab::Regex.full_project_path_regex "#{path}/" =~ Gitlab::PathRegex.full_project_path_regex
end end
end end
...@@ -24,14 +28,16 @@ def path_valid_for_record?(record, value) ...@@ -24,14 +28,16 @@ def path_valid_for_record?(record, value)
case record case record
when Project when Project
self.class.valid_project_path?(full_path) self.class.valid_project_path?(full_path)
else when Group
self.class.valid_namespace_path?(full_path) self.class.valid_group_path?(full_path)
else # User or non-Group Namespace
self.class.valid_user_path?(full_path)
end end
end end
def validate_each(record, attribute, value) def validate_each(record, attribute, value)
unless value =~ Gitlab::Regex.namespace_regex unless value =~ Gitlab::PathRegex.namespace_format_regex
record.errors.add(attribute, Gitlab::Regex.namespace_regex_message) record.errors.add(attribute, Gitlab::PathRegex.namespace_format_message)
return return
end end
......
...@@ -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."
.username.form-group .username.form-group
= f.label :username = f.label :username
= f.text_field :username, class: "form-control middle", pattern: Gitlab::Regex::NAMESPACE_REGEX_STR_JS, required: true, title: 'Please create a username with only alphanumeric characters.' = f.text_field :username, class: "form-control middle", pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, 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...
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
%strong= parent.full_path + '/' %strong= parent.full_path + '/'
= f.text_field :path, placeholder: 'open-source', class: 'form-control', = f.text_field :path, placeholder: 'open-source', class: 'form-control',
autofocus: local_assigns[:autofocus] || false, required: true, autofocus: local_assigns[:autofocus] || false, required: true,
pattern: Gitlab::Regex::NAMESPACE_REGEX_STR_JS, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS,
title: 'Please choose a group path with no special characters.', title: 'Please choose a group path with no special characters.',
"data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}" "data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
- if parent - if parent
......
require 'sidekiq/web' require 'sidekiq/web'
require 'sidekiq/cron/web' require 'sidekiq/cron/web'
require 'constraints/group_url_constrainer'
Rails.application.routes.draw do Rails.application.routes.draw do
concern :access_requestable do concern :access_requestable do
...@@ -85,20 +84,6 @@ ...@@ -85,20 +84,6 @@
root to: "root#index" root to: "root#index"
# Since group show page is wildcard routing
# we want all other routing to be checked before matching this one
constraints(GroupUrlConstrainer.new) do
scope(path: '*id',
as: :group,
constraints: { id: Gitlab::Regex.namespace_route_regex, format: /(html|json|atom)/ },
controller: :groups) do
get '/', action: :show
patch '/', action: :update
put '/', action: :update
delete '/', action: :destroy
end
end
draw :test if Rails.env.test? draw :test if Rails.env.test?
get '*unmatched_route', to: 'application#route_not_found' get '*unmatched_route', to: 'application#route_not_found'
......
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
scope(path: 'groups/*id', scope(path: 'groups/*id',
controller: :groups, controller: :groups,
constraints: { id: Gitlab::Regex.namespace_route_regex, format: /(html|json|atom)/ }) do constraints: { id: Gitlab::PathRegex.full_namespace_route_regex, format: /(html|json|atom)/ }) do
scope(as: :group) do scope(as: :group) do
put :members_update put :members_update
...@@ -70,10 +70,10 @@ ...@@ -70,10 +70,10 @@
scope(path: 'projects/*namespace_id', scope(path: 'projects/*namespace_id',
as: :namespace, as: :namespace,
constraints: { namespace_id: Gitlab::Regex.namespace_route_regex }) do constraints: { namespace_id: Gitlab::PathRegex.full_namespace_route_regex }) do
resources(:projects, resources(:projects,
path: '/', path: '/',
constraints: { id: Gitlab::Regex.project_route_regex }, constraints: { id: Gitlab::PathRegex.project_route_regex },
only: [:show]) do only: [:show]) do
member do member do
......
scope(path: '*namespace_id/:project_id', scope(path: '*namespace_id/:project_id',
format: nil, format: nil,
constraints: { namespace_id: Gitlab::Regex.namespace_route_regex }) do constraints: { namespace_id: Gitlab::PathRegex.full_namespace_route_regex }) do
scope(constraints: { project_id: Gitlab::Regex.project_git_route_regex }, module: :projects) do scope(constraints: { project_id: Gitlab::PathRegex.project_git_route_regex }, module: :projects) do
# Git HTTP clients ('git clone' etc.) # Git HTTP clients ('git clone' etc.)
scope(controller: :git_http) do scope(controller: :git_http) do
get '/info/refs', action: :info_refs get '/info/refs', action: :info_refs
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
end end
# Redirect /group/project/info/refs to /group/project.git/info/refs # Redirect /group/project/info/refs to /group/project.git/info/refs
scope(constraints: { project_id: Gitlab::Regex.project_route_regex }) do scope(constraints: { project_id: Gitlab::PathRegex.project_route_regex }) do
# Allow /info/refs, /info/refs?service=git-upload-pack, and # Allow /info/refs, /info/refs?service=git-upload-pack, and
# /info/refs?service=git-receive-pack, but nothing else. # /info/refs?service=git-receive-pack, but nothing else.
# #
......
require 'constraints/group_url_constrainer'
resources :groups, only: [:index, :new, :create] resources :groups, only: [:index, :new, :create]
scope(path: 'groups/*group_id', scope(path: 'groups/*group_id',
module: :groups, module: :groups,
as: :group, as: :group,
constraints: { group_id: Gitlab::Regex.namespace_route_regex }) do constraints: { group_id: Gitlab::PathRegex.full_namespace_route_regex }) do
resources :group_members, only: [:index, :create, :update, :destroy], concerns: :access_requestable do resources :group_members, only: [:index, :create, :update, :destroy], concerns: :access_requestable do
post :resend_invite, on: :member post :resend_invite, on: :member
delete :leave, on: :collection delete :leave, on: :collection
...@@ -25,7 +27,7 @@ ...@@ -25,7 +27,7 @@
scope(path: 'groups/*id', scope(path: 'groups/*id',
controller: :groups, controller: :groups,
constraints: { id: Gitlab::Regex.namespace_route_regex, format: /(html|json|atom)/ }) do constraints: { id: Gitlab::PathRegex.full_namespace_route_regex, format: /(html|json|atom)/ }) do
get :edit, as: :edit_group get :edit, as: :edit_group
get :issues, as: :issues_group get :issues, as: :issues_group
get :merge_requests, as: :merge_requests_group get :merge_requests, as: :merge_requests_group
...@@ -34,3 +36,15 @@ ...@@ -34,3 +36,15 @@
get :subgroups, as: :subgroups_group get :subgroups, as: :subgroups_group
get '/', action: :show, as: :group_canonical get '/', action: :show, as: :group_canonical
end end
constraints(GroupUrlConstrainer.new) do
scope(path: '*id',
as: :group,
constraints: { id: Gitlab::PathRegex.full_namespace_route_regex, format: /(html|json|atom)/ },
controller: :groups) do
get '/', action: :show
patch '/', action: :update
put '/', action: :update
delete '/', action: :destroy
end
end
...@@ -13,16 +13,16 @@ ...@@ -13,16 +13,16 @@
# Otherwise, Rails will overwrite the constraint with `/.+?/`, # Otherwise, Rails will overwrite the constraint with `/.+?/`,
# which breaks some of our wildcard routes like `/blob/*id` # which breaks some of our wildcard routes like `/blob/*id`
# and `/tree/*id` that depend on the negative lookahead inside # and `/tree/*id` that depend on the negative lookahead inside
# `Gitlab::Regex.namespace_route_regex`, which helps the router # `Gitlab::PathRegex.full_namespace_route_regex`, which helps the router
# determine whether a certain path segment is part of `*namespace_id`, # determine whether a certain path segment is part of `*namespace_id`,
# `:project_id`, or `*id`. # `:project_id`, or `*id`.
# #
# See https://github.com/rails/rails/blob/v4.2.8/actionpack/lib/action_dispatch/routing/mapper.rb#L155 # See https://github.com/rails/rails/blob/v4.2.8/actionpack/lib/action_dispatch/routing/mapper.rb#L155
scope(path: '*namespace_id', scope(path: '*namespace_id',
as: :namespace, as: :namespace,
namespace_id: Gitlab::Regex.namespace_route_regex) do namespace_id: Gitlab::PathRegex.full_namespace_route_regex) do
scope(path: ':project_id', scope(path: ':project_id',
constraints: { project_id: Gitlab::Regex.project_route_regex }, constraints: { project_id: Gitlab::PathRegex.project_route_regex },
module: :projects, module: :projects,
as: :project) do as: :project) do
...@@ -329,7 +329,7 @@ ...@@ -329,7 +329,7 @@
resources :runner_projects, only: [:create, :destroy] resources :runner_projects, only: [:create, :destroy]
resources :badges, only: [:index] do resources :badges, only: [:index] do
collection do collection do
scope '*ref', constraints: { ref: Gitlab::Regex.git_reference_regex } do scope '*ref', constraints: { ref: Gitlab::PathRegex.git_reference_regex } do
constraints format: /svg/ do constraints format: /svg/ do
get :build get :build
get :coverage get :coverage
...@@ -352,7 +352,7 @@ ...@@ -352,7 +352,7 @@
resources(:projects, resources(:projects,
path: '/', path: '/',
constraints: { id: Gitlab::Regex.project_route_regex }, constraints: { id: Gitlab::PathRegex.project_route_regex },
only: [:edit, :show, :update, :destroy]) do only: [:edit, :show, :update, :destroy]) do
member do member do
put :transfer put :transfer
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
resource :repository, only: [:create] do resource :repository, only: [:create] do
member do member do
get 'archive', constraints: { format: Gitlab::Regex.archive_formats_regex } get 'archive', constraints: { format: Gitlab::PathRegex.archive_formats_regex }
end end
end end
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
member do member do
# tree viewer logs # tree viewer logs
get 'logs_tree', constraints: { id: Gitlab::Regex.git_reference_regex } get 'logs_tree', constraints: { id: Gitlab::PathRegex.git_reference_regex }
# Directories with leading dots erroneously get rejected if git # Directories with leading dots erroneously get rejected if git
# ref regex used in constraints. Regex verification now done in controller. # ref regex used in constraints. Regex verification now done in controller.
get 'logs_tree/*path', action: :logs_tree, as: :logs_file, format: false, constraints: { get 'logs_tree/*path', action: :logs_tree, as: :logs_file, format: false, constraints: {
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
end end
end end
scope constraints: { id: Gitlab::Regex.git_reference_regex } do scope constraints: { id: Gitlab::PathRegex.git_reference_regex } do
resources :network, only: [:show] resources :network, only: [:show]
resources :graphs, only: [:show] do resources :graphs, only: [:show] do
......
...@@ -11,19 +11,7 @@ ...@@ -11,19 +11,7 @@
get '/users/almost_there' => 'confirmations#almost_there' get '/users/almost_there' => 'confirmations#almost_there'
end end
constraints(UserUrlConstrainer.new) do scope(constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }) do
# Get all keys of user
get ':username.keys' => 'profiles/keys#get_keys', constraints: { username: Gitlab::Regex.root_namespace_route_regex }
scope(path: ':username',
as: :user,
constraints: { username: Gitlab::Regex.root_namespace_route_regex },
controller: :users) do
get '/', action: :show
end
end
scope(constraints: { username: Gitlab::Regex.root_namespace_route_regex }) do
scope(path: 'users/:username', scope(path: 'users/:username',
as: :user, as: :user,
controller: :users) do controller: :users) do
...@@ -34,7 +22,7 @@ ...@@ -34,7 +22,7 @@
get :contributed, as: :contributed_projects get :contributed, as: :contributed_projects
get :snippets get :snippets
get :exists get :exists
get '/', to: redirect('/%{username}') get '/', to: redirect('/%{username}'), as: nil
end end
# Compatibility with old routing # Compatibility with old routing
...@@ -46,3 +34,15 @@ ...@@ -46,3 +34,15 @@
get '/u/:username/snippets', to: redirect('/users/%{username}/snippets') get '/u/:username/snippets', to: redirect('/users/%{username}/snippets')
get '/u/:username/contributed', to: redirect('/users/%{username}/contributed') get '/u/:username/contributed', to: redirect('/users/%{username}/contributed')
end end
constraints(UserUrlConstrainer.new) do
# Get all keys of user
get ':username.keys' => 'profiles/keys#get_keys', constraints: { username: Gitlab::PathRegex.root_namespace_route_regex }
scope(path: ':username',
as: :user,
constraints: { username: Gitlab::PathRegex.root_namespace_route_regex },
controller: :users) do
get '/', action: :show
end
end
...@@ -71,7 +71,7 @@ structure. ...@@ -71,7 +71,7 @@ structure.
- You need to be an Owner of a group in order to be able to create - You need to be an Owner of a group in order to be able to create
a subgroup. For more information check the [permissions table][permissions]. a subgroup. For more information check the [permissions table][permissions].
- For a list of words that are not allowed to be used as group names see the - For a list of words that are not allowed to be used as group names see the
[`regex.rb` file][reserved] under the `TOP_LEVEL_ROUTES`, `PROJECT_WILDCARD_ROUTES` and `GROUP_ROUTES` lists: [`path_regex.rb` file][reserved] under the `TOP_LEVEL_ROUTES`, `PROJECT_WILDCARD_ROUTES` and `GROUP_ROUTES` lists:
- `TOP_LEVEL_ROUTES`: are names that are reserved as usernames or top level groups - `TOP_LEVEL_ROUTES`: are names that are reserved as usernames or top level groups
- `PROJECT_WILDCARD_ROUTES`: are names that are reserved for child groups or projects. - `PROJECT_WILDCARD_ROUTES`: are names that are reserved for child groups or projects.
- `GROUP_ROUTES`: are names that are reserved for all groups or projects. - `GROUP_ROUTES`: are names that are reserved for all groups or projects.
...@@ -163,4 +163,4 @@ Here's a list of what you can't do with subgroups: ...@@ -163,4 +163,4 @@ Here's a list of what you can't do with subgroups:
[ce-2772]: https://gitlab.com/gitlab-org/gitlab-ce/issues/2772 [ce-2772]: https://gitlab.com/gitlab-org/gitlab-ce/issues/2772
[permissions]: ../../permissions.md#group [permissions]: ../../permissions.md#group
[reserved]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/regex.rb [reserved]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/path_regex.rb
...@@ -85,7 +85,7 @@ def assign_blob_vars! ...@@ -85,7 +85,7 @@ def assign_blob_vars!
optional :sha, type: String, desc: 'The commit sha of the archive to be downloaded' optional :sha, type: String, desc: 'The commit sha of the archive to be downloaded'
optional :format, type: String, desc: 'The archive format' optional :format, type: String, desc: 'The archive format'
end end
get ':id/repository/archive', requirements: { format: Gitlab::Regex.archive_formats_regex } do get ':id/repository/archive', requirements: { format: Gitlab::PathRegex.archive_formats_regex } do
begin begin
send_git_archive user_project.repository, ref: params[:sha], format: params[:format] send_git_archive user_project.repository, ref: params[:sha], format: params[:format]
rescue rescue
......
...@@ -72,7 +72,7 @@ def handle_project_member_errors(errors) ...@@ -72,7 +72,7 @@ def handle_project_member_errors(errors)
optional :sha, type: String, desc: 'The commit sha of the archive to be downloaded' optional :sha, type: String, desc: 'The commit sha of the archive to be downloaded'
optional :format, type: String, desc: 'The archive format' optional :format, type: String, desc: 'The archive format'
end end
get ':id/repository/archive', requirements: { format: Gitlab::Regex.archive_formats_regex } do get ':id/repository/archive', requirements: { format: Gitlab::PathRegex.archive_formats_regex } do
begin begin
send_git_archive user_project.repository, ref: params[:sha], format: params[:format] send_git_archive user_project.repository, ref: params[:sha], format: params[:format]
rescue rescue
......
class GroupUrlConstrainer class GroupUrlConstrainer
def matches?(request) def matches?(request)
id = request.params[:group_id] || request.params[:id] full_path = request.params[:group_id] || request.params[:id]
return false unless DynamicPathValidator.valid_namespace_path?(id) return false unless DynamicPathValidator.valid_group_path?(full_path)
Group.find_by_full_path(id, follow_redirects: request.get?).present? Group.find_by_full_path(full_path, follow_redirects: request.get?).present?
end end
end end
...@@ -2,7 +2,7 @@ class ProjectUrlConstrainer ...@@ -2,7 +2,7 @@ class ProjectUrlConstrainer
def matches?(request) def matches?(request)
namespace_path = request.params[:namespace_id] namespace_path = request.params[:namespace_id]
project_path = request.params[:project_id] || request.params[:id] project_path = request.params[:project_id] || request.params[:id]
full_path = namespace_path + '/' + project_path full_path = [namespace_path, project_path].join('/')
return false unless DynamicPathValidator.valid_project_path?(full_path) return false unless DynamicPathValidator.valid_project_path?(full_path)
......
class UserUrlConstrainer class UserUrlConstrainer
def matches?(request) def matches?(request)
User.find_by_full_path(request.params[:username], follow_redirects: request.get?).present? full_path = request.params[:username]
return false unless DynamicPathValidator.valid_user_path?(full_path)
User.find_by_full_path(full_path, follow_redirects: request.get?).present?
end end
end end
...@@ -10,7 +10,7 @@ class Router ...@@ -10,7 +10,7 @@ class Router
# - Ending in `issues/id`/realtime_changes` for the `issue_title` route # - Ending in `issues/id`/realtime_changes` for the `issue_title` route
USED_IN_ROUTES = %w[noteable issue notes issues realtime_changes USED_IN_ROUTES = %w[noteable issue notes issues realtime_changes
commit pipelines merge_requests new].freeze commit pipelines merge_requests new].freeze
RESERVED_WORDS = Gitlab::Regex::ILLEGAL_PROJECT_PATH_WORDS - USED_IN_ROUTES RESERVED_WORDS = Gitlab::PathRegex::ILLEGAL_PROJECT_PATH_WORDS - USED_IN_ROUTES
RESERVED_WORDS_REGEX = Regexp.union(*RESERVED_WORDS) RESERVED_WORDS_REGEX = Regexp.union(*RESERVED_WORDS)
ROUTES = [ ROUTES = [
Gitlab::EtagCaching::Router::Route.new( Gitlab::EtagCaching::Router::Route.new(
......
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