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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gitlab-ce
Commits
551145bc
Commit
551145bc
authored
Jul 27, 2014
by
Robert Schilling
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Validate branch-names and references in WebUI, API
Add specs for GitRefValidator
parent
7a0e1c72
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
184 additions
and
25 deletions
+184
-25
app/controllers/projects/branches_controller.rb
app/controllers/projects/branches_controller.rb
+11
-3
app/services/create_branch_service.rb
app/services/create_branch_service.rb
+26
-1
app/services/delete_branch_service.rb
app/services/delete_branch_service.rb
+6
-5
app/views/projects/branches/new.html.haml
app/views/projects/branches/new.html.haml
+6
-2
doc/api/branches.md
doc/api/branches.md
+4
-1
features/project/commits/branches.feature
features/project/commits/branches.feature
+18
-0
features/steps/project/browse_branches.rb
features/steps/project/browse_branches.rb
+31
-3
lib/api/branches.rb
lib/api/branches.rb
+12
-4
lib/gitlab/git_ref_validator.rb
lib/gitlab/git_ref_validator.rb
+11
-0
spec/lib/git_ref_validator_spec.rb
spec/lib/git_ref_validator_spec.rb
+20
-0
spec/requests/api/branches_spec.rb
spec/requests/api/branches_spec.rb
+39
-6
No files found.
app/controllers/projects/branches_controller.rb
View file @
551145bc
...
@@ -17,9 +17,17 @@ class Projects::BranchesController < Projects::ApplicationController
...
@@ -17,9 +17,17 @@ class Projects::BranchesController < Projects::ApplicationController
end
end
def
create
def
create
@branch
=
CreateBranchService
.
new
.
execute
(
project
,
params
[
:branch_name
],
params
[
:ref
],
current_user
)
result
=
CreateBranchService
.
new
.
execute
(
project
,
params
[
:branch_name
],
redirect_to
project_tree_path
(
@project
,
@branch
.
name
)
params
[
:ref
],
current_user
)
if
result
[
:status
]
==
:success
@branch
=
result
[
:branch
]
redirect_to
project_tree_path
(
@project
,
@branch
.
name
)
else
@error
=
result
[
:message
]
render
action:
'new'
end
end
end
def
destroy
def
destroy
...
...
app/services/create_branch_service.rb
View file @
551145bc
class
CreateBranchService
class
CreateBranchService
def
execute
(
project
,
branch_name
,
ref
,
current_user
)
def
execute
(
project
,
branch_name
,
ref
,
current_user
)
valid_branch
=
Gitlab
::
GitRefValidator
.
validate
(
branch_name
)
if
valid_branch
==
false
return
error
(
'Branch name invalid'
)
end
repository
=
project
.
repository
repository
=
project
.
repository
existing_branch
=
repository
.
find_branch
(
branch_name
)
if
existing_branch
return
error
(
'Branch already exists'
)
end
repository
.
add_branch
(
branch_name
,
ref
)
repository
.
add_branch
(
branch_name
,
ref
)
new_branch
=
repository
.
find_branch
(
branch_name
)
new_branch
=
repository
.
find_branch
(
branch_name
)
if
new_branch
if
new_branch
Event
.
create_ref_event
(
project
,
current_user
,
new_branch
,
'add'
)
Event
.
create_ref_event
(
project
,
current_user
,
new_branch
,
'add'
)
return
success
(
new_branch
)
else
return
error
(
'Invalid reference name'
)
end
end
end
def
error
(
message
)
{
message:
message
,
status: :error
}
end
new_branch
def
success
(
branch
)
{
branch:
branch
,
status: :success
}
end
end
end
end
app/services/delete_branch_service.rb
View file @
551145bc
...
@@ -5,21 +5,21 @@ class DeleteBranchService
...
@@ -5,21 +5,21 @@ class DeleteBranchService
# No such branch
# No such branch
unless
branch
unless
branch
return
error
(
'No such branch'
)
return
error
(
'No such branch'
,
404
)
end
end
if
branch_name
==
repository
.
root_ref
if
branch_name
==
repository
.
root_ref
return
error
(
'Cannot remove HEAD branch'
)
return
error
(
'Cannot remove HEAD branch'
,
405
)
end
end
# Dont allow remove of protected branch
# Dont allow remove of protected branch
if
project
.
protected_branch?
(
branch_name
)
if
project
.
protected_branch?
(
branch_name
)
return
error
(
'Protected branch cant be removed'
)
return
error
(
'Protected branch cant be removed'
,
405
)
end
end
# Dont allow user to remove branch if he is not allowed to push
# Dont allow user to remove branch if he is not allowed to push
unless
current_user
.
can?
(
:push_code
,
project
)
unless
current_user
.
can?
(
:push_code
,
project
)
return
error
(
'You dont have push access to repo'
)
return
error
(
'You dont have push access to repo'
,
405
)
end
end
if
repository
.
rm_branch
(
branch_name
)
if
repository
.
rm_branch
(
branch_name
)
...
@@ -30,9 +30,10 @@ class DeleteBranchService
...
@@ -30,9 +30,10 @@ class DeleteBranchService
end
end
end
end
def
error
(
message
)
def
error
(
message
,
return_code
=
400
)
{
{
message:
message
,
message:
message
,
return_code:
return_code
,
state: :error
state: :error
}
}
end
end
...
...
app/views/projects/branches/new.html.haml
View file @
551145bc
-
if
@error
.alert.alert-danger
%button
{
type:
"button"
,
class:
"close"
,
"data-dismiss"
=>
"alert"
}
×
=
@error
%h3
.page-title
%h3
.page-title
%i
.icon-code-fork
%i
.icon-code-fork
New branch
New branch
...
@@ -5,11 +9,11 @@
...
@@ -5,11 +9,11 @@
.form-group
.form-group
=
label_tag
:branch_name
,
'Name for new branch'
,
class:
'control-label'
=
label_tag
:branch_name
,
'Name for new branch'
,
class:
'control-label'
.col-sm-10
.col-sm-10
=
text_field_tag
:branch_name
,
nil
,
placeholder:
'enter new branch name'
,
required:
true
,
tabindex:
1
,
class:
'form-control'
=
text_field_tag
:branch_name
,
params
[
:branch_name
]
,
placeholder:
'enter new branch name'
,
required:
true
,
tabindex:
1
,
class:
'form-control'
.form-group
.form-group
=
label_tag
:ref
,
'Create from'
,
class:
'control-label'
=
label_tag
:ref
,
'Create from'
,
class:
'control-label'
.col-sm-10
.col-sm-10
=
text_field_tag
:ref
,
nil
,
placeholder:
'existing branch name, tag or commit SHA'
,
required:
true
,
tabindex:
2
,
class:
'form-control'
=
text_field_tag
:ref
,
params
[
:ref
]
,
placeholder:
'existing branch name, tag or commit SHA'
,
required:
true
,
tabindex:
2
,
class:
'form-control'
.form-actions
.form-actions
=
submit_tag
'Create branch'
,
class:
'btn btn-create'
,
tabindex:
3
=
submit_tag
'Create branch'
,
class:
'btn btn-create'
,
tabindex:
3
=
link_to
'Cancel'
,
project_branches_path
(
@project
),
class:
'btn btn-cancel'
=
link_to
'Cancel'
,
project_branches_path
(
@project
),
class:
'btn btn-cancel'
...
...
doc/api/branches.md
View file @
551145bc
...
@@ -196,6 +196,8 @@ Parameters:
...
@@ -196,6 +196,8 @@ Parameters:
}
}
```
```
It return 200 if succeed or 400 if failed with error message explaining reason.
## Delete repository branch
## Delete repository branch
```
```
...
@@ -207,4 +209,5 @@ Parameters:
...
@@ -207,4 +209,5 @@ Parameters:
-
`id`
(required) - The ID of a project
-
`id`
(required) - The ID of a project
-
`branch`
(required) - The name of the branch
-
`branch`
(required) - The name of the branch
It return 200 if succeed or 405 if failed with error message explaining reason.
It return 200 if succeed, 404 if the branch to be deleted does not exist
or 400 for other reasons. In case of an error, an explaining message is provided.
features/project/commits/branches.feature
View file @
551145bc
...
@@ -23,3 +23,21 @@ Feature: Project Browse branches
...
@@ -23,3 +23,21 @@ Feature: Project Browse branches
Given
I visit project branches page
Given
I visit project branches page
And
I click branch 'improve/awesome' delete link
And
I click branch 'improve/awesome' delete link
Then
I should not see branch 'improve/awesome'
Then
I should not see branch 'improve/awesome'
Scenario
:
I
create a branch with invalid name
Given
I visit project branches page
And
I click new branch link
When
I submit new branch form with invalid name
Then
I should see new an error that branch is invalid
Scenario
:
I
create a branch with invalid reference
Given
I visit project branches page
And
I click new branch link
When
I submit new branch form with invalid reference
Then
I should see new an error that ref is invalid
Scenario
:
I
create a branch that already exists
Given
I visit project branches page
And
I click new branch link
When
I submit new branch form with branch that already exists
Then
I should see new an error that branch already exists
features/steps/project/browse_branches.rb
View file @
551145bc
...
@@ -38,10 +38,38 @@ class ProjectBrowseBranches < Spinach::FeatureSteps
...
@@ -38,10 +38,38 @@ class ProjectBrowseBranches < Spinach::FeatureSteps
click_button
'Create branch'
click_button
'Create branch'
end
end
step
'I submit new branch form with invalid name'
do
fill_in
'branch_name'
,
with:
'1.0 stable'
fill_in
'ref'
,
with:
'master'
click_button
'Create branch'
end
step
'I submit new branch form with invalid reference'
do
fill_in
'branch_name'
,
with:
'foo'
fill_in
'ref'
,
with:
'foo'
click_button
'Create branch'
end
step
'I submit new branch form with branch that already exists'
do
fill_in
'branch_name'
,
with:
'master'
fill_in
'ref'
,
with:
'master'
click_button
'Create branch'
end
step
'I should see new branch created'
do
step
'I should see new branch created'
do
within
'.tree-ref-holder'
do
page
.
should
have_content
'deploy_keys'
page
.
should
have_content
'deploy_keys'
end
end
step
'I should see new an error that branch is invalid'
do
page
.
should
have_content
'Branch name invalid'
end
step
'I should see new an error that ref is invalid'
do
page
.
should
have_content
'Invalid reference name'
end
step
'I should see new an error that branch already exists'
do
page
.
should
have_content
'Branch already exists'
end
end
step
"I click branch 'improve/awesome' delete link"
do
step
"I click branch 'improve/awesome' delete link"
do
...
...
lib/api/branches.rb
View file @
551145bc
...
@@ -80,9 +80,17 @@ module API
...
@@ -80,9 +80,17 @@ module API
# POST /projects/:id/repository/branches
# POST /projects/:id/repository/branches
post
":id/repository/branches"
do
post
":id/repository/branches"
do
authorize_push_project
authorize_push_project
@branch
=
CreateBranchService
.
new
.
execute
(
user_project
,
params
[
:branch_name
],
params
[
:ref
],
current_user
)
result
=
CreateBranchService
.
new
.
execute
(
user_project
,
params
[
:branch_name
],
present
@branch
,
with:
Entities
::
RepoObject
,
project:
user_project
params
[
:ref
],
current_user
)
if
result
[
:status
]
==
:success
present
result
[
:branch
],
with:
Entities
::
RepoObject
,
project:
user_project
else
render_api_error!
(
result
[
:message
],
400
)
end
end
end
# Delete branch
# Delete branch
...
@@ -99,7 +107,7 @@ module API
...
@@ -99,7 +107,7 @@ module API
if
result
[
:state
]
==
:success
if
result
[
:state
]
==
:success
true
true
else
else
render_api_error!
(
result
[
:message
],
405
)
render_api_error!
(
result
[
:message
],
result
[
:return_code
]
)
end
end
end
end
end
end
...
...
lib/gitlab/git_ref_validator.rb
0 → 100644
View file @
551145bc
module
Gitlab
module
GitRefValidator
extend
self
# Validates a given name against the git reference specification
#
# Returns true for a valid reference name, false otherwise
def
validate
(
ref_name
)
system
*
%W(git check-ref-format refs/
#{
ref_name
}
)
end
end
end
spec/lib/git_ref_validator_spec.rb
0 → 100644
View file @
551145bc
require
'spec_helper'
describe
Gitlab
::
GitRefValidator
do
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature/new'
).
should
be_true
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'implement_@all'
).
should
be_true
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'my_new_feature'
).
should
be_true
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'#1'
).
should
be_true
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature/~new/'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature/^new/'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature/:new/'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature/?new/'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature/*new/'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature/[new/'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature/new/'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature/new.'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature\@{'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature\new'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature//new'
).
should
be_false
}
it
{
Gitlab
::
GitRefValidator
.
validate
(
'feature new'
).
should
be_false
}
end
spec/requests/api/branches_spec.rb
View file @
551145bc
...
@@ -94,22 +94,50 @@ describe API::API, api: true do
...
@@ -94,22 +94,50 @@ describe API::API, api: true do
describe
"POST /projects/:id/repository/branches"
do
describe
"POST /projects/:id/repository/branches"
do
it
"should create a new branch"
do
it
"should create a new branch"
do
post
api
(
"/projects/
#{
project
.
id
}
/repository/branches"
,
user
),
post
api
(
"/projects/
#{
project
.
id
}
/repository/branches"
,
user
),
branch_name:
branch_name
,
branch_name:
'feature1'
,
ref:
branch_sha
ref:
branch_sha
response
.
status
.
should
==
201
response
.
status
.
should
==
201
json_response
[
'name'
].
should
==
branch_name
json_response
[
'name'
].
should
==
'feature1'
json_response
[
'commit'
][
'id'
].
should
==
branch_sha
json_response
[
'commit'
][
'id'
].
should
==
branch_sha
end
end
it
"should deny for user without push access"
do
it
"should deny for user without push access"
do
post
api
(
"/projects/
#{
project
.
id
}
/repository/branches"
,
user2
),
post
api
(
"/projects/
#{
project
.
id
}
/repository/branches"
,
user2
),
branch_name:
branch_name
,
branch_name:
branch_name
,
ref:
branch_sha
ref:
branch_sha
response
.
status
.
should
==
403
response
.
status
.
should
==
403
end
end
it
'should return 400 if branch name is invalid'
do
post
api
(
"/projects/
#{
project
.
id
}
/repository/branches"
,
user
),
branch_name:
'new design'
,
ref:
branch_sha
response
.
status
.
should
==
400
json_response
[
'message'
].
should
==
'Branch name invalid'
end
it
'should return 400 if branch already exists'
do
post
api
(
"/projects/
#{
project
.
id
}
/repository/branches"
,
user
),
branch_name:
'new_design1'
,
ref:
branch_sha
response
.
status
.
should
==
201
post
api
(
"/projects/
#{
project
.
id
}
/repository/branches"
,
user
),
branch_name:
'new_design1'
,
ref:
branch_sha
response
.
status
.
should
==
400
json_response
[
'message'
].
should
==
'Branch already exists'
end
it
'should return 400 if ref name is invalid'
do
post
api
(
"/projects/
#{
project
.
id
}
/repository/branches"
,
user
),
branch_name:
'new_design3'
,
ref:
'foo'
response
.
status
.
should
==
400
json_response
[
'message'
].
should
==
'Invalid reference name'
end
end
end
describe
"DELETE /projects/:id/repository/branches/:branch"
do
describe
"DELETE /projects/:id/repository/branches/:branch"
do
...
@@ -120,6 +148,11 @@ describe API::API, api: true do
...
@@ -120,6 +148,11 @@ describe API::API, api: true do
response
.
status
.
should
==
200
response
.
status
.
should
==
200
end
end
it
'should return 404 if branch not exists'
do
delete
api
(
"/projects/
#{
project
.
id
}
/repository/branches/foobar"
,
user
)
response
.
status
.
should
==
404
end
it
"should remove protected branch"
do
it
"should remove protected branch"
do
project
.
protected_branches
.
create
(
name:
branch_name
)
project
.
protected_branches
.
create
(
name:
branch_name
)
delete
api
(
"/projects/
#{
project
.
id
}
/repository/branches/
#{
branch_name
}
"
,
user
)
delete
api
(
"/projects/
#{
project
.
id
}
/repository/branches/
#{
branch_name
}
"
,
user
)
...
...
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