Skip to content
Snippets Groups Projects
Verified Commit e6cc7a0a authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets
Browse files

Restrict nested group names to prevent ambiguous routes

parent 6b2d4947
No related branches found
No related tags found
1 merge request!9738Nested groups path restrictions pt. 1
Pipeline #
Loading
Loading
@@ -35,12 +35,21 @@ class NamespaceValidator < ActiveModel::EachValidator
users
].freeze
 
WILDCARD_ROUTES = %w[tree commits wikis new edit create update logs_tree
preview blob blame raw files create_dir find_file].freeze
STRICT_RESERVED = (RESERVED + WILDCARD_ROUTES).freeze
def self.valid?(value)
!reserved?(value) && follow_format?(value)
end
 
def self.reserved?(value)
RESERVED.include?(value)
def self.reserved?(value, strict: false)
if strict
STRICT_RESERVED.include?(value)
else
RESERVED.include?(value)
end
end
 
def self.follow_format?(value)
Loading
Loading
@@ -54,7 +63,9 @@ class NamespaceValidator < ActiveModel::EachValidator
record.errors.add(attribute, Gitlab::Regex.namespace_regex_message)
end
 
if reserved?(value)
strict = record.is_a?(Group) && record.parent_id
if reserved?(value, strict: strict)
record.errors.add(attribute, "#{value} is a reserved name")
end
end
Loading
Loading
Loading
Loading
@@ -14,10 +14,8 @@ class ProjectPathValidator < ActiveModel::EachValidator
# without tree as reserved name routing can match 'group/project' as group name,
# 'tree' as project name and 'deploy_keys' as route.
#
RESERVED = (NamespaceValidator::RESERVED -
%w[dashboard help ci admin search notes services assets profile public] +
%w[tree commits wikis new edit create update logs_tree
preview blob blame raw files create_dir find_file]).freeze
RESERVED = (NamespaceValidator::STRICT_RESERVED -
%w[dashboard help ci admin search notes services assets profile public]).freeze
 
def self.valid?(value)
!reserved?(value)
Loading
Loading
---
title: Restrict nested group names to prevent ambiguous routes
merge_request: 9738
author:
Loading
Loading
@@ -28,6 +28,20 @@ describe Namespace, models: true do
expect(nested).not_to be_valid
expect(nested.errors[:parent_id].first).to eq('has too deep level of nesting')
end
describe 'reserved path validation' do
context 'nested group' do
let(:group) { build(:group, :nested, path: 'tree') }
it { expect(group).not_to be_valid }
end
context 'top-level group' do
let(:group) { build(:group, path: 'tree') }
it { expect(group).to be_valid }
end
end
end
 
describe "Respond to" do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment