Commit 9e7c908c authored by Jan Provaznik's avatar Jan Provaznik

Project-compatible path validations

There are path validation differences for namespaces vs projects:
* project can end with `.`
* namespace path length must be at least 2 chars

When a project namespace is created for each project, we have
to use same restrictions as for project, instead of for namespace.
parent fd079767
......@@ -63,17 +63,27 @@ class Namespace < ApplicationRecord
length: { maximum: 255 }
validates :description, length: { maximum: 255 }
validates :path,
presence: true,
length: { maximum: URL_MAX_LENGTH },
namespace_path: true
length: { maximum: URL_MAX_LENGTH }
validates :path, namespace_path: true, if: ->(n) { !n.project_namespace? }
# Project path validator is used for project namespaces for now to assure
# compatibility with project paths
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/341764
validates :path, project_path: true, if: ->(n) { n.project_namespace? }
# Introduce minimal path length of 2 characters.
# Allow change of other attributes without forcing users to
# rename their user or group. At the same time prevent changing
# the path without complying with new 2 chars requirement.
# Issue https://gitlab.com/gitlab-org/gitlab/-/issues/225214
validates :path, length: { minimum: 2 }, if: :path_changed?
#
# For ProjectNamespace we don't check minimal path length to keep
# compatibility with existing project restrictions.
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/341764
validates :path, length: { minimum: 2 }, if: :enforce_minimum_path_length?
validates :max_artifacts_size, numericality: { only_integer: true, greater_than: 0, allow_nil: true }
......@@ -575,6 +585,10 @@ class Namespace < ApplicationRecord
project.track_project_repository
end
end
def enforce_minimum_path_length?
path_changed? && !project_namespace?
end
end
Namespace.prepend_mod_with('Namespace')
......@@ -133,39 +133,77 @@ RSpec.describe Namespace do
end
context 'top-level group' do
let(:group) { build(:group, path: 'tree') }
let(:group) { build(:namespace, path: 'tree') }
it { expect(group).to be_valid }
end
end
describe '1 char path length' do
it 'does not allow to create one' do
namespace = build(:namespace, path: 'j')
describe 'path validator' do
using RSpec::Parameterized::TableSyntax
expect(namespace).not_to be_valid
expect(namespace.errors[:path].first).to eq('is too short (minimum is 2 characters)')
let_it_be(:parent) { create(:namespace) }
# rubocop:disable Lint/BinaryOperatorWithIdenticalOperands
where(:namespace_type, :path, :valid) do
ref(:project_sti_name) | 'j' | true
ref(:project_sti_name) | 'path.' | true
ref(:project_sti_name) | 'blob' | false
ref(:group_sti_name) | 'j' | false
ref(:group_sti_name) | 'path.' | false
ref(:group_sti_name) | 'blob' | true
ref(:user_sti_name) | 'j' | false
ref(:user_sti_name) | 'path.' | false
ref(:user_sti_name) | 'blob' | true
end
# rubocop:enable Lint/BinaryOperatorWithIdenticalOperands
it 'does not allow to update one' do
namespace = create(:namespace)
namespace.update(path: 'j')
with_them do
it 'validates namespace path' do
parent_namespace = parent if namespace_type == Namespaces::ProjectNamespace.sti_name
namespace = build(:namespace, type: namespace_type, parent: parent_namespace, path: path)
expect(namespace).not_to be_valid
expect(namespace.errors[:path].first).to eq('is too short (minimum is 2 characters)')
expect(namespace.valid?).to be(valid)
end
end
end
it 'allows updating other attributes for existing record' do
namespace = build(:namespace, path: 'j', owner: create(:user))
namespace.save(validate: false)
namespace.reload
describe '1 char path length' do
context 'with user namespace' do
let(:namespace) { build(:namespace) }
expect(namespace.path).to eq('j')
it 'does not allow to update path to single char' do
namespace.save!
namespace.update(name: 'something new')
namespace.path = 'j'
expect(namespace).to be_valid
expect(namespace.name).to eq('something new')
expect(namespace).not_to be_valid
expect(namespace.errors[:path].first).to eq('is too short (minimum is 2 characters)')
end
it 'allows updating other attributes for existing record' do
namespace.save!
namespace.update_attribute(:path, 'j')
namespace.reload
expect(namespace.path).to eq('j')
namespace.update(name: 'something new')
expect(namespace).to be_valid
expect(namespace.name).to eq('something new')
end
end
context 'with project namespace' do
let(:namespace) { build(:project_namespace) }
it 'allows to update path to single char' do
namespace = create(:project_namespace)
namespace.update(path: 'j')
expect(namespace).to be_valid
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