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 ...@@ -63,17 +63,27 @@ class Namespace < ApplicationRecord
length: { maximum: 255 } length: { maximum: 255 }
validates :description, length: { maximum: 255 } validates :description, length: { maximum: 255 }
validates :path, validates :path,
presence: true, presence: true,
length: { maximum: URL_MAX_LENGTH }, length: { maximum: URL_MAX_LENGTH }
namespace_path: true
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. # Introduce minimal path length of 2 characters.
# Allow change of other attributes without forcing users to # Allow change of other attributes without forcing users to
# rename their user or group. At the same time prevent changing # rename their user or group. At the same time prevent changing
# the path without complying with new 2 chars requirement. # the path without complying with new 2 chars requirement.
# Issue https://gitlab.com/gitlab-org/gitlab/-/issues/225214 # 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 } validates :max_artifacts_size, numericality: { only_integer: true, greater_than: 0, allow_nil: true }
...@@ -575,6 +585,10 @@ class Namespace < ApplicationRecord ...@@ -575,6 +585,10 @@ class Namespace < ApplicationRecord
project.track_project_repository project.track_project_repository
end end
end end
def enforce_minimum_path_length?
path_changed? && !project_namespace?
end
end end
Namespace.prepend_mod_with('Namespace') Namespace.prepend_mod_with('Namespace')
...@@ -133,39 +133,77 @@ RSpec.describe Namespace do ...@@ -133,39 +133,77 @@ RSpec.describe Namespace do
end end
context 'top-level group' do context 'top-level group' do
let(:group) { build(:group, path: 'tree') } let(:group) { build(:namespace, path: 'tree') }
it { expect(group).to be_valid } it { expect(group).to be_valid }
end end
end end
describe '1 char path length' do describe 'path validator' do
it 'does not allow to create one' do using RSpec::Parameterized::TableSyntax
namespace = build(:namespace, path: 'j')
expect(namespace).not_to be_valid let_it_be(:parent) { create(:namespace) }
expect(namespace.errors[:path].first).to eq('is too short (minimum is 2 characters)')
# 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 end
# rubocop:enable Lint/BinaryOperatorWithIdenticalOperands
it 'does not allow to update one' do with_them do
namespace = create(:namespace) it 'validates namespace path' do
namespace.update(path: 'j') 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.valid?).to be(valid)
expect(namespace.errors[:path].first).to eq('is too short (minimum is 2 characters)') end
end end
end
it 'allows updating other attributes for existing record' do describe '1 char path length' do
namespace = build(:namespace, path: 'j', owner: create(:user)) context 'with user namespace' do
namespace.save(validate: false) let(:namespace) { build(:namespace) }
namespace.reload
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).not_to be_valid
expect(namespace.name).to eq('something new') 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 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