Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
gitlab-ce
Commits
a10925e1
Commit
a10925e1
authored
Nov 03, 2017
by
Douwe Maan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reallow project paths ending in periods
parent
97b80fef
Changes
18
Show whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
223 additions
and
159 deletions
+223
-159
app/models/namespace.rb
app/models/namespace.rb
+1
-1
app/models/project.rb
app/models/project.rb
+1
-3
app/models/user.rb
app/models/user.rb
+1
-1
app/validators/abstract_path_validator.rb
app/validators/abstract_path_validator.rb
+38
-0
app/validators/dynamic_path_validator.rb
app/validators/dynamic_path_validator.rb
+0
-53
app/validators/namespace_path_validator.rb
app/validators/namespace_path_validator.rb
+19
-0
app/validators/project_path_validator.rb
app/validators/project_path_validator.rb
+19
-0
app/validators/user_path_validator.rb
app/validators/user_path_validator.rb
+15
-0
changelogs/unreleased/dm-reallow-project-path-ending-in-period.yml
...s/unreleased/dm-reallow-project-path-ending-in-period.yml
+5
-0
lib/constraints/group_url_constrainer.rb
lib/constraints/group_url_constrainer.rb
+1
-1
lib/constraints/project_url_constrainer.rb
lib/constraints/project_url_constrainer.rb
+1
-1
lib/constraints/user_url_constrainer.rb
lib/constraints/user_url_constrainer.rb
+1
-1
lib/gitlab/o_auth/user.rb
lib/gitlab/o_auth/user.rb
+1
-1
spec/models/project_spec.rb
spec/models/project_spec.rb
+6
-0
spec/validators/dynamic_path_validator_spec.rb
spec/validators/dynamic_path_validator_spec.rb
+0
-97
spec/validators/namespace_path_validator_spec.rb
spec/validators/namespace_path_validator_spec.rb
+38
-0
spec/validators/project_path_validator_spec.rb
spec/validators/project_path_validator_spec.rb
+38
-0
spec/validators/user_path_validator_spec.rb
spec/validators/user_path_validator_spec.rb
+38
-0
No files found.
app/models/namespace.rb
View file @
a10925e1
...
@@ -36,7 +36,7 @@ class Namespace < ActiveRecord::Base
...
@@ -36,7 +36,7 @@ class Namespace < ActiveRecord::Base
validates
:path
,
validates
:path
,
presence:
true
,
presence:
true
,
length:
{
maximum:
255
},
length:
{
maximum:
255
},
dynamic
_path:
true
namespace
_path:
true
validate
:nesting_level_allowed
validate
:nesting_level_allowed
...
...
app/models/project.rb
View file @
a10925e1
...
@@ -240,10 +240,8 @@ class Project < ActiveRecord::Base
...
@@ -240,10 +240,8 @@ class Project < ActiveRecord::Base
message:
Gitlab
::
Regex
.
project_name_regex_message
}
message:
Gitlab
::
Regex
.
project_name_regex_message
}
validates
:path
,
validates
:path
,
presence:
true
,
presence:
true
,
dynamic
_path:
true
,
project
_path:
true
,
length:
{
maximum:
255
},
length:
{
maximum:
255
},
format:
{
with:
Gitlab
::
PathRegex
.
project_path_format_regex
,
message:
Gitlab
::
PathRegex
.
project_path_format_message
},
uniqueness:
{
scope: :namespace_id
}
uniqueness:
{
scope: :namespace_id
}
validates
:namespace
,
presence:
true
validates
:namespace
,
presence:
true
...
...
app/models/user.rb
View file @
a10925e1
...
@@ -146,7 +146,7 @@ class User < ActiveRecord::Base
...
@@ -146,7 +146,7 @@ class User < ActiveRecord::Base
presence:
true
,
presence:
true
,
numericality:
{
greater_than_or_equal_to:
0
,
less_than_or_equal_to:
Gitlab
::
Database
::
MAX_INT_VALUE
}
numericality:
{
greater_than_or_equal_to:
0
,
less_than_or_equal_to:
Gitlab
::
Database
::
MAX_INT_VALUE
}
validates
:username
,
validates
:username
,
dynamic
_path:
true
,
user
_path:
true
,
presence:
true
,
presence:
true
,
uniqueness:
{
case_sensitive:
false
}
uniqueness:
{
case_sensitive:
false
}
...
...
app/validators/abstract_path_validator.rb
0 → 100644
View file @
a10925e1
class
AbstractPathValidator
<
ActiveModel
::
EachValidator
extend
Gitlab
::
EncodingHelper
def
self
.
path_regex
raise
NotImplementedError
end
def
self
.
format_regex
raise
NotImplementedError
end
def
self
.
format_error_message
raise
NotImplementedError
end
def
self
.
full_path
(
record
,
value
)
value
end
def
self
.
valid_path?
(
path
)
encode!
(
path
)
"
#{
path
}
/"
=~
path_regex
end
def
validate_each
(
record
,
attribute
,
value
)
unless
value
=~
self
.
class
.
format_regex
record
.
errors
.
add
(
attribute
,
self
.
class
.
format_error_message
)
return
end
full_path
=
self
.
class
.
full_path
(
record
,
value
)
return
unless
full_path
unless
self
.
class
.
valid_path?
(
full_path
)
record
.
errors
.
add
(
attribute
,
"
#{
value
}
is a reserved name"
)
end
end
end
app/validators/dynamic_path_validator.rb
deleted
100644 → 0
View file @
97b80fef
# DynamicPathValidator
#
# Custom validator for GitLab path values.
# These paths are assigned to `Namespace` (& `Group` as a subclass) & `Project`
#
# Values are checked for formatting and exclusion from a list of illegal path
# names.
class
DynamicPathValidator
<
ActiveModel
::
EachValidator
extend
Gitlab
::
EncodingHelper
class
<<
self
def
valid_user_path?
(
path
)
encode!
(
path
)
"
#{
path
}
/"
=~
Gitlab
::
PathRegex
.
root_namespace_path_regex
end
def
valid_group_path?
(
path
)
encode!
(
path
)
"
#{
path
}
/"
=~
Gitlab
::
PathRegex
.
full_namespace_path_regex
end
def
valid_project_path?
(
path
)
encode!
(
path
)
"
#{
path
}
/"
=~
Gitlab
::
PathRegex
.
full_project_path_regex
end
end
def
path_valid_for_record?
(
record
,
value
)
full_path
=
record
.
respond_to?
(
:build_full_path
)
?
record
.
build_full_path
:
value
return
true
unless
full_path
case
record
when
Project
self
.
class
.
valid_project_path?
(
full_path
)
when
Group
self
.
class
.
valid_group_path?
(
full_path
)
else
# User or non-Group Namespace
self
.
class
.
valid_user_path?
(
full_path
)
end
end
def
validate_each
(
record
,
attribute
,
value
)
unless
value
=~
Gitlab
::
PathRegex
.
namespace_format_regex
record
.
errors
.
add
(
attribute
,
Gitlab
::
PathRegex
.
namespace_format_message
)
return
end
unless
path_valid_for_record?
(
record
,
value
)
record
.
errors
.
add
(
attribute
,
"
#{
value
}
is a reserved name"
)
end
end
end
app/validators/namespace_path_validator.rb
0 → 100644
View file @
a10925e1
class
NamespacePathValidator
<
AbstractPathValidator
extend
Gitlab
::
EncodingHelper
def
self
.
path_regex
Gitlab
::
PathRegex
.
full_namespace_path_regex
end
def
self
.
format_regex
Gitlab
::
PathRegex
.
namespace_format_regex
end
def
self
.
format_error_message
Gitlab
::
PathRegex
.
namespace_format_message
end
def
self
.
full_path
(
record
,
value
)
record
.
build_full_path
end
end
app/validators/project_path_validator.rb
0 → 100644
View file @
a10925e1
class
ProjectPathValidator
<
AbstractPathValidator
extend
Gitlab
::
EncodingHelper
def
self
.
path_regex
Gitlab
::
PathRegex
.
full_project_path_regex
end
def
self
.
format_regex
Gitlab
::
PathRegex
.
project_path_format_regex
end
def
self
.
format_error_message
Gitlab
::
PathRegex
.
project_path_format_message
end
def
self
.
full_path
(
record
,
value
)
record
.
build_full_path
end
end
app/validators/user_path_validator.rb
0 → 100644
View file @
a10925e1
class
UserPathValidator
<
AbstractPathValidator
extend
Gitlab
::
EncodingHelper
def
self
.
path_regex
Gitlab
::
PathRegex
.
root_namespace_path_regex
end
def
self
.
format_regex
Gitlab
::
PathRegex
.
namespace_format_regex
end
def
self
.
format_error_message
Gitlab
::
PathRegex
.
namespace_format_message
end
end
changelogs/unreleased/dm-reallow-project-path-ending-in-period.yml
0 → 100644
View file @
a10925e1
---
title
:
Reallow project paths ending in periods
merge_request
:
author
:
type
:
fixed
lib/constraints/group_url_constrainer.rb
View file @
a10925e1
...
@@ -2,7 +2,7 @@ class GroupUrlConstrainer
...
@@ -2,7 +2,7 @@ class GroupUrlConstrainer
def
matches?
(
request
)
def
matches?
(
request
)
full_path
=
request
.
params
[
:group_id
]
||
request
.
params
[
:id
]
full_path
=
request
.
params
[
:group_id
]
||
request
.
params
[
:id
]
return
false
unless
DynamicPathValidator
.
valid_group
_path?
(
full_path
)
return
false
unless
NamespacePathValidator
.
valid
_path?
(
full_path
)
Group
.
find_by_full_path
(
full_path
,
follow_redirects:
request
.
get?
).
present?
Group
.
find_by_full_path
(
full_path
,
follow_redirects:
request
.
get?
).
present?
end
end
...
...
lib/constraints/project_url_constrainer.rb
View file @
a10925e1
...
@@ -4,7 +4,7 @@ class ProjectUrlConstrainer
...
@@ -4,7 +4,7 @@ class ProjectUrlConstrainer
project_path
=
request
.
params
[
:project_id
]
||
request
.
params
[
:id
]
project_path
=
request
.
params
[
:project_id
]
||
request
.
params
[
:id
]
full_path
=
[
namespace_path
,
project_path
].
join
(
'/'
)
full_path
=
[
namespace_path
,
project_path
].
join
(
'/'
)
return
false
unless
DynamicPathValidator
.
valid_project
_path?
(
full_path
)
return
false
unless
ProjectPathValidator
.
valid
_path?
(
full_path
)
# We intentionally allow SELECT(*) here so result of this query can be used
# We intentionally allow SELECT(*) here so result of this query can be used
# as cache for further Project.find_by_full_path calls within request
# as cache for further Project.find_by_full_path calls within request
...
...
lib/constraints/user_url_constrainer.rb
View file @
a10925e1
...
@@ -2,7 +2,7 @@ class UserUrlConstrainer
...
@@ -2,7 +2,7 @@ class UserUrlConstrainer
def
matches?
(
request
)
def
matches?
(
request
)
full_path
=
request
.
params
[
:username
]
full_path
=
request
.
params
[
:username
]
return
false
unless
DynamicPathValidator
.
valid_user
_path?
(
full_path
)
return
false
unless
UserPathValidator
.
valid
_path?
(
full_path
)
User
.
find_by_full_path
(
full_path
,
follow_redirects:
request
.
get?
).
present?
User
.
find_by_full_path
(
full_path
,
follow_redirects:
request
.
get?
).
present?
end
end
...
...
lib/gitlab/o_auth/user.rb
View file @
a10925e1
...
@@ -179,7 +179,7 @@ module Gitlab
...
@@ -179,7 +179,7 @@ module Gitlab
valid_username
=
::
Namespace
.
clean_path
(
username
)
valid_username
=
::
Namespace
.
clean_path
(
username
)
uniquify
=
Uniquify
.
new
uniquify
=
Uniquify
.
new
valid_username
=
uniquify
.
string
(
valid_username
)
{
|
s
|
!
DynamicPathValidator
.
valid_user
_path?
(
s
)
}
valid_username
=
uniquify
.
string
(
valid_username
)
{
|
s
|
!
UserPathValidator
.
valid
_path?
(
s
)
}
name
=
auth_hash
.
name
name
=
auth_hash
.
name
name
=
valid_username
if
name
.
strip
.
empty?
name
=
valid_username
if
name
.
strip
.
empty?
...
...
spec/models/project_spec.rb
View file @
a10925e1
...
@@ -276,6 +276,12 @@ describe Project do
...
@@ -276,6 +276,12 @@ describe Project do
expect
(
project
).
to
be_valid
expect
(
project
).
to
be_valid
end
end
it
'allows a path ending in a period'
do
project
=
build
(
:project
,
path:
'foo.'
)
expect
(
project
).
to
be_valid
end
end
end
end
end
...
...
spec/validators/dynamic_path_validator_spec.rb
deleted
100644 → 0
View file @
97b80fef
require
'spec_helper'
describe
DynamicPathValidator
do
let
(
:validator
)
{
described_class
.
new
(
attributes:
[
:path
])
}
def
expect_handles_invalid_utf8
expect
{
yield
(
'\255invalid'
)
}.
to
be_falsey
end
describe
'.valid_user_path'
do
it
'handles invalid utf8'
do
expect
(
described_class
.
valid_user_path?
(
"a
\0
weird
\255
path"
)).
to
be_falsey
end
end
describe
'.valid_group_path'
do
it
'handles invalid utf8'
do
expect
(
described_class
.
valid_group_path?
(
"a
\0
weird
\255
path"
)).
to
be_falsey
end
end
describe
'.valid_project_path'
do
it
'handles invalid utf8'
do
expect
(
described_class
.
valid_project_path?
(
"a
\0
weird
\255
path"
)).
to
be_falsey
end
end
describe
'#path_valid_for_record?'
do
context
'for project'
do
it
'calls valid_project_path?'
do
project
=
build
(
:project
,
path:
'activity'
)
expect
(
described_class
).
to
receive
(
:valid_project_path?
).
with
(
project
.
full_path
).
and_call_original
expect
(
validator
.
path_valid_for_record?
(
project
,
'activity'
)).
to
be_truthy
end
end
context
'for group'
do
it
'calls valid_group_path?'
do
group
=
build
(
:group
,
:nested
,
path:
'activity'
)
expect
(
described_class
).
to
receive
(
:valid_group_path?
).
with
(
group
.
full_path
).
and_call_original
expect
(
validator
.
path_valid_for_record?
(
group
,
'activity'
)).
to
be_falsey
end
end
context
'for user'
do
it
'calls valid_user_path?'
do
user
=
build
(
:user
,
username:
'activity'
)
expect
(
described_class
).
to
receive
(
:valid_user_path?
).
with
(
user
.
full_path
).
and_call_original
expect
(
validator
.
path_valid_for_record?
(
user
,
'activity'
)).
to
be_truthy
end
end
context
'for user namespace'
do
it
'calls valid_user_path?'
do
user
=
create
(
:user
,
username:
'activity'
)
namespace
=
user
.
namespace
expect
(
described_class
).
to
receive
(
:valid_user_path?
).
with
(
namespace
.
full_path
).
and_call_original
expect
(
validator
.
path_valid_for_record?
(
namespace
,
'activity'
)).
to
be_truthy
end
end
end
describe
'#validates_each'
do
it
'adds a message when the path is not in the correct format'
do
group
=
build
(
:group
)
validator
.
validate_each
(
group
,
:path
,
"Path with spaces, and comma's!"
)
expect
(
group
.
errors
[
:path
]).
to
include
(
Gitlab
::
PathRegex
.
namespace_format_message
)
end
it
'adds a message when the path is not in the correct format'
do
group
=
build
(
:group
,
path:
'users'
)
validator
.
validate_each
(
group
,
:path
,
'users'
)
expect
(
group
.
errors
[
:path
]).
to
include
(
'users is a reserved name'
)
end
it
'updating to an invalid path is not allowed'
do
project
=
create
(
:project
)
project
.
path
=
'update'
validator
.
validate_each
(
project
,
:path
,
'update'
)
expect
(
project
.
errors
[
:path
]).
to
include
(
'update is a reserved name'
)
end
end
end
spec/validators/namespace_path_validator_spec.rb
0 → 100644
View file @
a10925e1
require
'spec_helper'
describe
NamespacePathValidator
do
let
(
:validator
)
{
described_class
.
new
(
attributes:
[
:path
])
}
describe
'.valid_path?'
do
it
'handles invalid utf8'
do
expect
(
described_class
.
valid_path?
(
"a
\0
weird
\255
path"
)).
to
be_falsey
end
end
describe
'#validates_each'
do
it
'adds a message when the path is not in the correct format'
do
group
=
build
(
:group
)
validator
.
validate_each
(
group
,
:path
,
"Path with spaces, and comma's!"
)
expect
(
group
.
errors
[
:path
]).
to
include
(
Gitlab
::
PathRegex
.
namespace_format_message
)
end
it
'adds a message when the path is reserved when creating'
do
group
=
build
(
:group
,
path:
'help'
)
validator
.
validate_each
(
group
,
:path
,
'help'
)
expect
(
group
.
errors
[
:path
]).
to
include
(
'help is a reserved name'
)
end
it
'adds a message when the path is reserved when updating'
do
group
=
create
(
:group
)
group
.
path
=
'help'
validator
.
validate_each
(
group
,
:path
,
'help'
)
expect
(
group
.
errors
[
:path
]).
to
include
(
'help is a reserved name'
)
end
end
end
spec/validators/project_path_validator_spec.rb
0 → 100644
View file @
a10925e1
require
'spec_helper'
describe
ProjectPathValidator
do
let
(
:validator
)
{
described_class
.
new
(
attributes:
[
:path
])
}
describe
'.valid_path?'
do
it
'handles invalid utf8'
do
expect
(
described_class
.
valid_path?
(
"a
\0
weird
\255
path"
)).
to
be_falsey
end
end
describe
'#validates_each'
do
it
'adds a message when the path is not in the correct format'
do
project
=
build
(
:project
)
validator
.
validate_each
(
project
,
:path
,
"Path with spaces, and comma's!"
)
expect
(
project
.
errors
[
:path
]).
to
include
(
Gitlab
::
PathRegex
.
project_path_format_message
)
end
it
'adds a message when the path is reserved when creating'
do
project
=
build
(
:project
,
path:
'blob'
)
validator
.
validate_each
(
project
,
:path
,
'blob'
)
expect
(
project
.
errors
[
:path
]).
to
include
(
'blob is a reserved name'
)
end
it
'adds a message when the path is reserved when updating'
do
project
=
create
(
:project
)
project
.
path
=
'blob'
validator
.
validate_each
(
project
,
:path
,
'blob'
)
expect
(
project
.
errors
[
:path
]).
to
include
(
'blob is a reserved name'
)
end
end
end
spec/validators/user_path_validator_spec.rb
0 → 100644
View file @
a10925e1
require
'spec_helper'
describe
UserPathValidator
do
let
(
:validator
)
{
described_class
.
new
(
attributes:
[
:username
])
}
describe
'.valid_path?'
do
it
'handles invalid utf8'
do
expect
(
described_class
.
valid_path?
(
"a
\0
weird
\255
path"
)).
to
be_falsey
end
end
describe
'#validates_each'
do
it
'adds a message when the path is not in the correct format'
do
user
=
build
(
:user
)
validator
.
validate_each
(
user
,
:username
,
"Path with spaces, and comma's!"
)
expect
(
user
.
errors
[
:username
]).
to
include
(
Gitlab
::
PathRegex
.
namespace_format_message
)
end
it
'adds a message when the path is reserved when creating'
do
user
=
build
(
:user
,
username:
'help'
)
validator
.
validate_each
(
user
,
:username
,
'help'
)
expect
(
user
.
errors
[
:username
]).
to
include
(
'help is a reserved name'
)
end
it
'adds a message when the path is reserved when updating'
do
user
=
create
(
:user
)
user
.
username
=
'help'
validator
.
validate_each
(
user
,
:username
,
'help'
)
expect
(
user
.
errors
[
:username
]).
to
include
(
'help is a reserved name'
)
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment