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
Boxiang Sun
gitlab-ce
Commits
e646439e
Commit
e646439e
authored
Oct 05, 2016
by
Ruben Davila
Browse files
Options
Browse Files
Download
Plain Diff
Merge commit 'dev/8-12-stable' into 8-12-stable
parents
467e1ca4
ba8aeb7c
Changes
39
Hide whitespace changes
Inline
Side-by-side
Showing
39 changed files
with
566 additions
and
73 deletions
+566
-73
CHANGELOG
CHANGELOG
+16
-1
VERSION
VERSION
+1
-1
app/assets/javascripts/compare_autocomplete.js
app/assets/javascripts/compare_autocomplete.js
+3
-2
app/assets/javascripts/copy_to_clipboard.js
app/assets/javascripts/copy_to_clipboard.js
+9
-9
app/assets/stylesheets/pages/builds.scss
app/assets/stylesheets/pages/builds.scss
+10
-3
app/assets/stylesheets/pages/projects.scss
app/assets/stylesheets/pages/projects.scss
+57
-1
app/controllers/concerns/authenticates_with_two_factor.rb
app/controllers/concerns/authenticates_with_two_factor.rb
+13
-2
app/models/merge_request.rb
app/models/merge_request.rb
+4
-0
app/models/project_feature.rb
app/models/project_feature.rb
+4
-1
app/models/service.rb
app/models/service.rb
+1
-0
app/models/user.rb
app/models/user.rb
+16
-0
app/services/projects/create_service.rb
app/services/projects/create_service.rb
+7
-1
app/views/projects/builds/_sidebar.html.haml
app/views/projects/builds/_sidebar.html.haml
+2
-2
app/views/projects/compare/_form.html.haml
app/views/projects/compare/_form.html.haml
+11
-6
app/views/projects/compare/_ref_dropdown.html.haml
app/views/projects/compare/_ref_dropdown.html.haml
+1
-0
lib/gitlab/github_import/importer.rb
lib/gitlab/github_import/importer.rb
+1
-2
lib/gitlab/github_import/project_creator.rb
lib/gitlab/github_import/project_creator.rb
+24
-11
lib/gitlab/import_export/attribute_cleaner.rb
lib/gitlab/import_export/attribute_cleaner.rb
+13
-0
lib/gitlab/import_export/command_line_util.rb
lib/gitlab/import_export/command_line_util.rb
+8
-1
lib/gitlab/import_export/file_importer.rb
lib/gitlab/import_export/file_importer.rb
+1
-1
lib/gitlab/import_export/project_tree_restorer.rb
lib/gitlab/import_export/project_tree_restorer.rb
+3
-2
lib/gitlab/import_export/project_tree_saver.rb
lib/gitlab/import_export/project_tree_saver.rb
+3
-1
lib/gitlab/import_export/relation_factory.rb
lib/gitlab/import_export/relation_factory.rb
+9
-3
lib/gitlab/import_export/repo_restorer.rb
lib/gitlab/import_export/repo_restorer.rb
+1
-1
lib/gitlab/import_export/repo_saver.rb
lib/gitlab/import_export/repo_saver.rb
+1
-1
lib/gitlab/import_export/version_saver.rb
lib/gitlab/import_export/version_saver.rb
+3
-1
lib/gitlab/import_export/wiki_repo_saver.rb
lib/gitlab/import_export/wiki_repo_saver.rb
+1
-1
lib/gitlab/lfs_token.rb
lib/gitlab/lfs_token.rb
+2
-7
spec/controllers/sessions_controller_spec.rb
spec/controllers/sessions_controller_spec.rb
+38
-0
spec/features/compare_spec.rb
spec/features/compare_spec.rb
+17
-9
spec/features/projects/import_export/export_file_spec.rb
spec/features/projects/import_export/export_file_spec.rb
+2
-0
spec/lib/gitlab/github_import/project_creator_spec.rb
spec/lib/gitlab/github_import/project_creator_spec.rb
+22
-2
spec/lib/gitlab/import_export/attribute_cleaner_spec.rb
spec/lib/gitlab/import_export/attribute_cleaner_spec.rb
+34
-0
spec/lib/gitlab/import_export/relation_factory_spec.rb
spec/lib/gitlab/import_export/relation_factory_spec.rb
+125
-0
spec/models/merge_request_spec.rb
spec/models/merge_request_spec.rb
+24
-0
spec/models/service_spec.rb
spec/models/service_spec.rb
+17
-0
spec/services/merge_requests/merge_service_spec.rb
spec/services/merge_requests/merge_service_spec.rb
+36
-0
spec/services/projects/destroy_service_spec.rb
spec/services/projects/destroy_service_spec.rb
+22
-1
spec/support/import_export/export_file_helper.rb
spec/support/import_export/export_file_helper.rb
+4
-0
No files found.
CHANGELOG
View file @
e646439e
Please view this file on the master branch, on stable branches it's out of date.
Please view this file on the master branch, on stable branches it's out of date.
v 8.12.4 (unreleased)
v 8.12.5 (unreleased)
v 8.12.4
- Fix "Copy to clipboard" tooltip to say "Copied!" when clipboard button is clicked. !6294 (lukehowell)
- Fix padding in build sidebar. !6506
- Changed compare dropdowns to dropdowns with isolated search input. !6550
- Fix race condition on LFS Token. !6592
- Fix type mismatch bug when closing Jira issue. !6619
- Fix lint-doc error. !6623
- Skip wiki creation when GitHub project has wiki enabled. !6665
- Fix issues importing services via Import/Export. !6667
- Restrict failed login attempts for users with 2FA enabled. !6668
- Fix failed project deletion when feature visibility set to private. !6688
- Prevent claiming associated model IDs via import.
- Set GitLab project exported file permissions to owner only
v 8.12.3
v 8.12.3
- Update Gitlab Shell to support low IO priority for storage moves
- Update Gitlab Shell to support low IO priority for storage moves
...
@@ -8,6 +22,7 @@ v 8.12.3
...
@@ -8,6 +22,7 @@ v 8.12.3
v 8.12.2
v 8.12.2
- Fix Import/Export not recognising correctly the imported services.
- Fix Import/Export not recognising correctly the imported services.
- Fix snippets pagination
- Fix snippets pagination
- Fix "Create project" button layout when visibility options are restricted
- Fix List-Unsubscribe header in emails
- Fix List-Unsubscribe header in emails
- Fix IssuesController#show degradation including project on loaded notes
- Fix IssuesController#show degradation including project on loaded notes
- Fix an issue with the "Commits" section of the cycle analytics summary. !6513
- Fix an issue with the "Commits" section of the cycle analytics summary. !6513
...
...
VERSION
View file @
e646439e
8.12.
3
8.12.
4
app/assets/javascripts/compare_autocomplete.js
View file @
e646439e
...
@@ -23,8 +23,9 @@
...
@@ -23,8 +23,9 @@
selectable
:
true
,
selectable
:
true
,
filterable
:
true
,
filterable
:
true
,
filterByText
:
true
,
filterByText
:
true
,
fieldName
:
$dropdown
.
attr
(
'
name
'
),
toggleLabel
:
true
,
filterInput
:
'
input[type="text"]
'
,
fieldName
:
$dropdown
.
data
(
'
field-name
'
),
filterInput
:
'
input[type="search"]
'
,
renderRow
:
function
(
ref
)
{
renderRow
:
function
(
ref
)
{
var
link
;
var
link
;
if
(
ref
.
header
!=
null
)
{
if
(
ref
.
header
!=
null
)
{
...
...
app/assets/javascripts/copy_to_clipboard.js
View file @
e646439e
...
@@ -26,15 +26,15 @@
...
@@ -26,15 +26,15 @@
};
};
showTooltip
=
function
(
target
,
title
)
{
showTooltip
=
function
(
target
,
title
)
{
return
$
(
target
).
tooltip
({
var
$target
=
$
(
target
);
container
:
'
body
'
,
var
originalTitle
=
$target
.
data
(
'
original-title
'
);
html
:
'
true
'
,
placement
:
'
auto bottom
'
,
$target
title
:
title
,
.
attr
(
'
title
'
,
'
Copied!
'
)
trigger
:
'
manual
'
.
tooltip
(
'
fixTitle
'
)
}).
tooltip
(
'
show
'
).
one
(
'
mouseleave
'
,
function
()
{
.
tooltip
(
'
show
'
)
return
$
(
this
).
tooltip
(
'
hide
'
);
.
attr
(
'
title
'
,
originalTitle
)
}
);
.
tooltip
(
'
fixTitle
'
);
};
};
$
(
function
()
{
$
(
function
()
{
...
...
app/assets/stylesheets/pages/builds.scss
View file @
e646439e
...
@@ -107,10 +107,14 @@
...
@@ -107,10 +107,14 @@
.block
{
.block
{
width
:
100%
;
width
:
100%
;
}
.block-first
{
&
.coverage
{
padding
:
5px
16px
11px
;
padding
:
0
16px
11px
;
}
.btn-group-justified
{
margin-top
:
5px
;
}
}
}
.js-build-variable
{
.js-build-variable
{
...
@@ -214,6 +218,9 @@
...
@@ -214,6 +218,9 @@
.build-detail-row
{
.build-detail-row
{
margin-bottom
:
5px
;
margin-bottom
:
5px
;
&
:last-of-type
{
margin-bottom
:
0
;
}
}
}
.build-light-text
{
.build-light-text
{
...
...
app/assets/stylesheets/pages/projects.scss
View file @
e646439e
...
@@ -743,6 +743,62 @@ pre.light-well {
...
@@ -743,6 +743,62 @@ pre.light-well {
.dropdown-menu
{
.dropdown-menu
{
width
:
300px
;
width
:
300px
;
}
}
&
.from
.compare-dropdown-toggle
{
width
:
237px
;
}
&
.to
.compare-dropdown-toggle
{
width
:
254px
;
}
.dropdown-toggle-text
{
display
:
block
;
height
:
100%
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
width
:
100%
;
}
}
.compare-ellipsis
{
display
:
inline
;
}
@media
(
max-width
:
$screen-xs-max
)
{
.compare-form-group
{
.input-group
{
width
:
100%
;
&
>
.compare-dropdown-toggle
{
width
:
100%
;
}
}
.dropdown-menu
{
width
:
100%
;
}
}
.compare-switch-container
{
text-align
:
center
;
padding
:
0
0
$gl-padding
;
.commits-compare-switch
{
float
:
none
;
}
}
.compare-ellipsis
{
display
:
block
;
text-align
:
center
;
padding
:
0
0
$gl-padding
;
}
.commits-compare-btn
{
width
:
100%
;
}
}
}
.clearable-input
{
.clearable-input
{
...
@@ -779,4 +835,4 @@ pre.light-well {
...
@@ -779,4 +835,4 @@ pre.light-well {
border-top-right-radius
:
0
;
border-top-right-radius
:
0
;
border-bottom-right-radius
:
0
;
border-bottom-right-radius
:
0
;
}
}
}
}
\ No newline at end of file
app/controllers/concerns/authenticates_with_two_factor.rb
View file @
e646439e
...
@@ -23,15 +23,24 @@ module AuthenticatesWithTwoFactor
...
@@ -23,15 +23,24 @@ module AuthenticatesWithTwoFactor
#
#
# Returns nil
# Returns nil
def
prompt_for_two_factor
(
user
)
def
prompt_for_two_factor
(
user
)
return
locked_user_redirect
(
user
)
if
user
.
access_locked?
session
[
:otp_user_id
]
=
user
.
id
session
[
:otp_user_id
]
=
user
.
id
setup_u2f_authentication
(
user
)
setup_u2f_authentication
(
user
)
render
'devise/sessions/two_factor'
render
'devise/sessions/two_factor'
end
end
def
locked_user_redirect
(
user
)
flash
.
now
[
:alert
]
=
'Invalid Login or password'
render
'devise/sessions/new'
end
def
authenticate_with_two_factor
def
authenticate_with_two_factor
user
=
self
.
resource
=
find_user
user
=
self
.
resource
=
find_user
if
user_params
[
:otp_attempt
].
present?
&&
session
[
:otp_user_id
]
if
user
.
access_locked?
locked_user_redirect
(
user
)
elsif
user_params
[
:otp_attempt
].
present?
&&
session
[
:otp_user_id
]
authenticate_with_two_factor_via_otp
(
user
)
authenticate_with_two_factor_via_otp
(
user
)
elsif
user_params
[
:device_response
].
present?
&&
session
[
:otp_user_id
]
elsif
user_params
[
:device_response
].
present?
&&
session
[
:otp_user_id
]
authenticate_with_two_factor_via_u2f
(
user
)
authenticate_with_two_factor_via_u2f
(
user
)
...
@@ -50,8 +59,9 @@ module AuthenticatesWithTwoFactor
...
@@ -50,8 +59,9 @@ module AuthenticatesWithTwoFactor
remember_me
(
user
)
if
user_params
[
:remember_me
]
==
'1'
remember_me
(
user
)
if
user_params
[
:remember_me
]
==
'1'
sign_in
(
user
)
sign_in
(
user
)
else
else
user
.
increment_failed_attempts!
flash
.
now
[
:alert
]
=
'Invalid two-factor code.'
flash
.
now
[
:alert
]
=
'Invalid two-factor code.'
render
:two_factor
prompt_for_two_factor
(
user
)
end
end
end
end
...
@@ -65,6 +75,7 @@ module AuthenticatesWithTwoFactor
...
@@ -65,6 +75,7 @@ module AuthenticatesWithTwoFactor
remember_me
(
user
)
if
user_params
[
:remember_me
]
==
'1'
remember_me
(
user
)
if
user_params
[
:remember_me
]
==
'1'
sign_in
(
user
)
sign_in
(
user
)
else
else
user
.
increment_failed_attempts!
flash
.
now
[
:alert
]
=
'Authentication via U2F device failed.'
flash
.
now
[
:alert
]
=
'Authentication via U2F device failed.'
prompt_for_two_factor
(
user
)
prompt_for_two_factor
(
user
)
end
end
...
...
app/models/merge_request.rb
View file @
e646439e
...
@@ -507,9 +507,13 @@ class MergeRequest < ActiveRecord::Base
...
@@ -507,9 +507,13 @@ class MergeRequest < ActiveRecord::Base
# `MergeRequestsClosingIssues` model. This is a performance optimization.
# `MergeRequestsClosingIssues` model. This is a performance optimization.
# Calculating this information for a number of merge requests requires
# Calculating this information for a number of merge requests requires
# running `ReferenceExtractor` on each of them separately.
# running `ReferenceExtractor` on each of them separately.
# This optimization does not apply to issues from external sources.
def
cache_merge_request_closes_issues!
(
current_user
=
self
.
author
)
def
cache_merge_request_closes_issues!
(
current_user
=
self
.
author
)
return
if
project
.
has_external_issue_tracker?
transaction
do
transaction
do
self
.
merge_requests_closing_issues
.
delete_all
self
.
merge_requests_closing_issues
.
delete_all
closes_issues
(
current_user
).
each
do
|
issue
|
closes_issues
(
current_user
).
each
do
|
issue
|
self
.
merge_requests_closing_issues
.
create!
(
issue:
issue
)
self
.
merge_requests_closing_issues
.
create!
(
issue:
issue
)
end
end
...
...
app/models/project_feature.rb
View file @
e646439e
...
@@ -20,7 +20,10 @@ class ProjectFeature < ActiveRecord::Base
...
@@ -20,7 +20,10 @@ class ProjectFeature < ActiveRecord::Base
FEATURES
=
%i(issues merge_requests wiki snippets builds)
FEATURES
=
%i(issues merge_requests wiki snippets builds)
belongs_to
:project
# Default scopes force us to unscope here since a service may need to check
# permissions for a project in pending_delete
# http://stackoverflow.com/questions/1540645/how-to-disable-default-scope-for-a-belongs-to
belongs_to
:project
,
->
{
unscope
(
where: :pending_delete
)
}
default_value_for
:builds_access_level
,
value:
ENABLED
,
allows_nil:
false
default_value_for
:builds_access_level
,
value:
ENABLED
,
allows_nil:
false
default_value_for
:issues_access_level
,
value:
ENABLED
,
allows_nil:
false
default_value_for
:issues_access_level
,
value:
ENABLED
,
allows_nil:
false
...
...
app/models/service.rb
View file @
e646439e
...
@@ -136,6 +136,7 @@ class Service < ActiveRecord::Base
...
@@ -136,6 +136,7 @@ class Service < ActiveRecord::Base
end
end
def #{arg}=(value)
def #{arg}=(value)
self.properties ||= {}
updated_properties['#{arg}'] = #{arg} unless #{arg}_changed?
updated_properties['#{arg}'] = #{arg} unless #{arg}_changed?
self.properties['#{arg}'] = value
self.properties['#{arg}'] = value
end
end
...
...
app/models/user.rb
View file @
e646439e
...
@@ -827,6 +827,22 @@ class User < ActiveRecord::Base
...
@@ -827,6 +827,22 @@ class User < ActiveRecord::Base
todos_pending_count
(
force:
true
)
todos_pending_count
(
force:
true
)
end
end
# This is copied from Devise::Models::Lockable#valid_for_authentication?, as our auth
# flow means we don't call that automatically (and can't conveniently do so).
#
# See:
# <https://github.com/plataformatec/devise/blob/v4.0.0/lib/devise/models/lockable.rb#L92>
#
def
increment_failed_attempts!
self
.
failed_attempts
||=
0
self
.
failed_attempts
+=
1
if
attempts_exceeded?
lock_access!
unless
access_locked?
else
save
(
validate:
false
)
end
end
private
private
def
projects_union
(
min_access_level
=
nil
)
def
projects_union
(
min_access_level
=
nil
)
...
...
app/services/projects/create_service.rb
View file @
e646439e
...
@@ -7,6 +7,8 @@ module Projects
...
@@ -7,6 +7,8 @@ module Projects
def
execute
def
execute
forked_from_project_id
=
params
.
delete
(
:forked_from_project_id
)
forked_from_project_id
=
params
.
delete
(
:forked_from_project_id
)
import_data
=
params
.
delete
(
:import_data
)
import_data
=
params
.
delete
(
:import_data
)
@skip_wiki
=
params
.
delete
(
:skip_wiki
)
@project
=
Project
.
new
(
params
)
@project
=
Project
.
new
(
params
)
# Make sure that the user is allowed to use the specified visibility level
# Make sure that the user is allowed to use the specified visibility level
...
@@ -92,7 +94,7 @@ module Projects
...
@@ -92,7 +94,7 @@ module Projects
log_info
(
"
#{
@project
.
owner
.
name
}
created a new project
\"
#{
@project
.
name_with_namespace
}
\"
"
)
log_info
(
"
#{
@project
.
owner
.
name
}
created a new project
\"
#{
@project
.
name_with_namespace
}
\"
"
)
unless
@project
.
gitlab_project_import?
unless
@project
.
gitlab_project_import?
@project
.
create_wiki
if
@project
.
feature_available?
(
:wiki
,
current_user
)
@project
.
create_wiki
unless
skip_wiki?
@project
.
build_missing_services
@project
.
build_missing_services
@project
.
create_labels
@project
.
create_labels
...
@@ -106,6 +108,10 @@ module Projects
...
@@ -106,6 +108,10 @@ module Projects
end
end
end
end
def
skip_wiki?
!
@project
.
feature_available?
(
:wiki
,
current_user
)
||
@skip_wiki
end
def
save_project_and_import_data
(
import_data
)
def
save_project_and_import_data
(
import_data
)
Project
.
transaction
do
Project
.
transaction
do
@project
.
create_or_update_import_data
(
data:
import_data
[
:data
],
credentials:
import_data
[
:credentials
])
if
import_data
@project
.
create_or_update_import_data
(
data:
import_data
[
:data
],
credentials:
import_data
[
:credentials
])
if
import_data
...
...
app/views/projects/builds/_sidebar.html.haml
View file @
e646439e
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
%a
.gutter-toggle.pull-right.js-sidebar-build-toggle
{
href:
"#"
}
%a
.gutter-toggle.pull-right.js-sidebar-build-toggle
{
href:
"#"
}
=
icon
(
'angle-double-right'
)
=
icon
(
'angle-double-right'
)
-
if
@build
.
coverage
-
if
@build
.
coverage
.block.
block-first
.block.
coverage
.title
.title
Test coverage
Test coverage
%p
.build-detail-row
%p
.build-detail-row
...
@@ -95,7 +95,7 @@
...
@@ -95,7 +95,7 @@
-
@build
.
trigger_request
.
variables
.
each
do
|
key
,
value
|
-
@build
.
trigger_request
.
variables
.
each
do
|
key
,
value
|
.hide.js-build
.hide.js-build
.js-build-variable
=
key
.js-build-variable
=
key
.js-build-value
=
value
.js-build-value
=
value
.block
.block
...
...
app/views/projects/compare/_form.html.haml
View file @
e646439e
=
form_tag
namespace_project_compare_index_path
(
@project
.
namespace
,
@project
),
method: :post
,
class:
'form-inline js-requires-input'
do
=
form_tag
namespace_project_compare_index_path
(
@project
.
namespace
,
@project
),
method: :post
,
class:
'form-inline js-requires-input'
do
.clearfix
.clearfix
-
if
params
[
:to
]
&&
params
[
:from
]
-
if
params
[
:to
]
&&
params
[
:from
]
=
link_to
icon
(
'exchange'
),
{
from:
params
[
:to
],
to:
params
[
:from
]},
{
class:
'commits-compare-switch has-tooltip'
,
title:
'Switch base of comparison'
}
.compare-switch-container
.form-group.dropdown.compare-form-group.js-compare-from-dropdown
=
link_to
icon
(
'exchange'
),
{
from:
params
[
:to
],
to:
params
[
:from
]},
{
class:
'commits-compare-switch has-tooltip'
,
title:
'Switch base of comparison'
}
.form-group.dropdown.compare-form-group.from.js-compare-from-dropdown
.input-group.inline-input-group
.input-group.inline-input-group
%span
.input-group-addon
from
%span
.input-group-addon
from
=
text_field_tag
:from
,
params
[
:from
],
class:
"form-control js-compare-dropdown"
,
required:
true
,
data:
{
refs_url:
refs_namespace_project_path
(
@project
.
namespace
,
@project
),
toggle:
"dropdown"
,
target:
".js-compare-from-dropdown"
,
selected:
params
[
:from
].
presence
}
=
hidden_field_tag
:from
,
params
[
:from
]
=
button_tag
type:
'button'
,
class:
"form-control compare-dropdown-toggle js-compare-dropdown"
,
required:
true
,
data:
{
refs_url:
refs_namespace_project_path
(
@project
.
namespace
,
@project
),
toggle:
"dropdown"
,
target:
".js-compare-from-dropdown"
,
selected:
params
[
:from
],
field_name: :from
}
do
.dropdown-toggle-text
=
params
[
:from
]
||
'Select branch/tag'
=
render
"ref_dropdown"
=
render
"ref_dropdown"
=
"..."
.compare-ellipsis
...
.form-group.dropdown.compare-form-group.js-compare-to-dropdown
.form-group.dropdown.compare-form-group.
to.
js-compare-to-dropdown
.input-group.inline-input-group
.input-group.inline-input-group
%span
.input-group-addon
to
%span
.input-group-addon
to
=
text_field_tag
:to
,
params
[
:to
],
class:
"form-control js-compare-dropdown"
,
required:
true
,
data:
{
refs_url:
refs_namespace_project_path
(
@project
.
namespace
,
@project
),
toggle:
"dropdown"
,
target:
".js-compare-to-dropdown"
,
selected:
params
[
:to
].
presence
}
=
hidden_field_tag
:to
,
params
[
:to
]
=
button_tag
type:
'button'
,
class:
"form-control compare-dropdown-toggle js-compare-dropdown"
,
required:
true
,
data:
{
refs_url:
refs_namespace_project_path
(
@project
.
namespace
,
@project
),
toggle:
"dropdown"
,
target:
".js-compare-to-dropdown"
,
selected:
params
[
:to
],
field_name: :to
}
do
.dropdown-toggle-text
=
params
[
:to
]
||
'Select branch/tag'
=
render
"ref_dropdown"
=
render
"ref_dropdown"
=
button_tag
"Compare"
,
class:
"btn btn-create commits-compare-btn"
=
button_tag
"Compare"
,
class:
"btn btn-create commits-compare-btn"
...
...
app/views/projects/compare/_ref_dropdown.html.haml
View file @
e646439e
.dropdown-menu.dropdown-menu-selectable
.dropdown-menu.dropdown-menu-selectable
=
dropdown_title
"Select branch/tag"
=
dropdown_title
"Select branch/tag"
=
dropdown_filter
"Filter by branch/tag"
=
dropdown_content
=
dropdown_content
=
dropdown_loading
=
dropdown_loading
lib/gitlab/github_import/importer.rb
View file @
e646439e
...
@@ -165,10 +165,9 @@ module Gitlab
...
@@ -165,10 +165,9 @@ module Gitlab
end
end
def
import_wiki
def
import_wiki
unless
project
.
wiki
_enabled
?
unless
project
.
wiki
.
repository_exists
?
wiki
=
WikiFormatter
.
new
(
project
)
wiki
=
WikiFormatter
.
new
(
project
)
gitlab_shell
.
import_repository
(
project
.
repository_storage_path
,
wiki
.
path_with_namespace
,
wiki
.
import_url
)
gitlab_shell
.
import_repository
(
project
.
repository_storage_path
,
wiki
.
path_with_namespace
,
wiki
.
import_url
)
project
.
project
.
update_attribute
(
:wiki_access_level
,
ProjectFeature
::
ENABLED
)
end
end
rescue
Gitlab
::
Shell
::
Error
=>
e
rescue
Gitlab
::
Shell
::
Error
=>
e
# GitHub error message when the wiki repo has not been created,
# GitHub error message when the wiki repo has not been created,
...
...
lib/gitlab/github_import/project_creator.rb
View file @
e646439e
module
Gitlab
module
Gitlab
module
GithubImport
module
GithubImport
class
ProjectCreator
class
ProjectCreator
attr_reader
:repo
,
:namespace
,
:current_user
,
:session_data
attr_reader
:repo
,
:name
,
:name
space
,
:current_user
,
:session_data
def
initialize
(
repo
,
name
,
namespace
,
current_user
,
session_data
)
def
initialize
(
repo
,
name
,
namespace
,
current_user
,
session_data
)
@repo
=
repo
@repo
=
repo
...
@@ -12,24 +12,37 @@ module Gitlab
...
@@ -12,24 +12,37 @@ module Gitlab
end
end
def
execute
def
execute
project
=
::
Projects
::
CreateService
.
new
(
::
Projects
::
CreateService
.
new
(
current_user
,
current_user
,
name:
@
name
,
name:
name
,
path:
@
name
,
path:
name
,
description:
repo
.
description
,
description:
repo
.
description
,
namespace_id:
namespace
.
id
,
namespace_id:
namespace
.
id
,
visibility_level:
repo
.
private
?
Gitlab
::
VisibilityLevel
::
PRIVATE
:
ApplicationSetting
.
current
.
default_project_visibility
,
visibility_level:
visibility_level
,
import_type:
"github"
,
import_type:
"github"
,
import_source:
repo
.
full_name
,
import_source:
repo
.
full_name
,
import_url:
repo
.
clone_url
.
sub
(
"https://"
,
"https://
#{
@session_data
[
:github_access_token
]
}
@"
)
import_url:
import_url
,
skip_wiki:
skip_wiki
).
execute
).
execute
end
private
# If repo has wiki we'll import it later
def
import_url
if
repo
.
has_wiki?
&&
project
repo
.
clone_url
.
sub
(
'https://'
,
"https://
#{
session_data
[
:github_access_token
]
}
@"
)
project
.
project_feature
.
update_attribute
(
:wiki_access_level
,
ProjectFeature
::
DISABLED
)
end
end
def
visibility_level
repo
.
private
?
Gitlab
::
VisibilityLevel
::
PRIVATE
:
ApplicationSetting
.
current
.
default_project_visibility
end
project
#
# If the GitHub project repository has wiki, we should not create the
# default wiki. Otherwise the GitHub importer will fail because the wiki
# repository already exist.
#
def
skip_wiki
repo
.
has_wiki?
end
end
end
end
end
end
...
...
lib/gitlab/import_export/attribute_cleaner.rb
0 → 100644
View file @
e646439e
module
Gitlab
module
ImportExport
class
AttributeCleaner
ALLOWED_REFERENCES
=
RelationFactory
::
PROJECT_REFERENCES
+
RelationFactory
::
USER_REFERENCES
def
self
.
clean!
(
relation_hash
:)
relation_hash
.
reject!
do
|
key
,
_value
|
key
.
end_with?
(
'_id'
)
&&
!
ALLOWED_REFERENCES
.
include?
(
key
)
end
end
end
end
end
lib/gitlab/import_export/command_line_util.rb
View file @
e646439e
module
Gitlab
module
Gitlab
module
ImportExport
module
ImportExport
module
CommandLineUtil
module
CommandLineUtil
DEFAULT_MODE
=
0700
def
tar_czf
(
archive
:,
dir
:)
def
tar_czf
(
archive
:,
dir
:)
tar_with_options
(
archive:
archive
,
dir:
dir
,
options:
'czf'
)
tar_with_options
(
archive:
archive
,
dir:
dir
,
options:
'czf'
)
end
end
...
@@ -21,6 +23,11 @@ module Gitlab
...
@@ -21,6 +23,11 @@ module Gitlab
execute
(
%W(
#{
Gitlab
.
config
.
gitlab_shell
.
path
}
/bin/create-hooks)
+
repository_storage_paths_args
)
execute
(
%W(
#{
Gitlab
.
config
.
gitlab_shell
.
path
}
/bin/create-hooks)
+
repository_storage_paths_args
)
end
end
def
mkdir_p
(
path
)
FileUtils
.
mkdir_p
(
path
,
mode:
DEFAULT_MODE
)
FileUtils
.
chmod
(
DEFAULT_MODE
,
path
)
end
private
private
def
tar_with_options
(
archive
:,
dir
:,
options
:)
def
tar_with_options
(
archive
:,
dir
:,
options
:)
...
@@ -45,7 +52,7 @@ module Gitlab
...
@@ -45,7 +52,7 @@ module Gitlab
# if we are copying files, create the destination folder
# if we are copying files, create the destination folder
destination_folder
=
File
.
file?
(
source
)
?
File
.
dirname
(
destination
)
:
destination
destination_folder
=
File
.
file?
(
source
)
?
File
.
dirname
(
destination
)
:
destination
FileUtils
.
mkdir_p
(
destination_folder
)
mkdir_p
(
destination_folder
)
FileUtils
.
copy_entry
(
source
,
destination
)
FileUtils
.
copy_entry
(
source
,
destination
)
true
true
end
end
...
...
lib/gitlab/import_export/file_importer.rb
View file @
e646439e
...
@@ -15,7 +15,7 @@ module Gitlab
...
@@ -15,7 +15,7 @@ module Gitlab
end
end
def
import
def
import
FileUtils
.
mkdir_p
(
@shared
.
export_path
)
mkdir_p
(
@shared
.
export_path
)
wait_for_archived_file
do
wait_for_archived_file
do
decompress_archive
decompress_archive
...
...
lib/gitlab/import_export/project_tree_restorer.rb
View file @
e646439e
...
@@ -110,9 +110,10 @@ module Gitlab
...
@@ -110,9 +110,10 @@ module Gitlab
def
create_relation
(
relation
,
relation_hash_list
)
def
create_relation
(
relation
,
relation_hash_list
)
relation_array
=
[
relation_hash_list
].
flatten
.
map
do
|
relation_hash
|
relation_array
=
[
relation_hash_list
].
flatten
.
map
do
|
relation_hash
|
Gitlab
::
ImportExport
::
RelationFactory
.
create
(
relation_sym:
relation
.
to_sym
,
Gitlab
::
ImportExport
::
RelationFactory
.
create
(
relation_sym:
relation
.
to_sym
,
relation_hash:
relation_hash
.
merge
(
'project_id'
=>
restored_project
.
id
)
,
relation_hash:
relation_hash
,
members_mapper:
members_mapper
,
members_mapper:
members_mapper
,
user:
@user
)
user:
@user
,
project_id:
restored_project
.
id
)
end
end
relation_hash_list
.
is_a?
(
Array
)
?
relation_array
:
relation_array
.
first
relation_hash_list
.
is_a?
(
Array
)
?
relation_array
:
relation_array
.
first
...
...
lib/gitlab/import_export/project_tree_saver.rb
View file @
e646439e
module
Gitlab
module
Gitlab
module
ImportExport
module
ImportExport
class
ProjectTreeSaver
class
ProjectTreeSaver
include
Gitlab
::
ImportExport
::
CommandLineUtil
attr_reader
:full_path
attr_reader
:full_path
def
initialize
(
project
:,
shared
:)
def
initialize
(
project
:,
shared
:)
...
@@ -10,7 +12,7 @@ module Gitlab
...
@@ -10,7 +12,7 @@ module Gitlab
end
end
def
save
def
save
FileUtils
.
mkdir_p
(
@shared
.
export_path
)
mkdir_p
(
@shared
.
export_path
)
File
.
write
(
full_path
,
project_json_tree
)
File
.
write
(
full_path
,
project_json_tree
)
true
true
...
...
lib/gitlab/import_export/relation_factory.rb
View file @
e646439e
...
@@ -13,6 +13,8 @@ module Gitlab
...
@@ -13,6 +13,8 @@ module Gitlab
USER_REFERENCES
=
%w[author_id assignee_id updated_by_id user_id]
.
freeze
USER_REFERENCES
=
%w[author_id assignee_id updated_by_id user_id]
.
freeze
PROJECT_REFERENCES
=
%w[project_id source_project_id gl_project_id target_project_id]
.
freeze
BUILD_MODELS
=
%w[Ci::Build commit_status]
.
freeze
BUILD_MODELS
=
%w[Ci::Build commit_status]
.
freeze
IMPORTED_OBJECT_MAX_RETRIES
=
5
.
freeze
IMPORTED_OBJECT_MAX_RETRIES
=
5
.
freeze
...
@@ -25,9 +27,9 @@ module Gitlab
...
@@ -25,9 +27,9 @@ module Gitlab
new
(
*
args
).
create
new
(
*
args
).
create
end
end
def
initialize
(
relation_sym
:,
relation_hash
:,
members_mapper
:,
user
:)
def
initialize
(
relation_sym
:,
relation_hash
:,
members_mapper
:,
user
:
,
project_id
:
)
@relation_name
=
OVERRIDES
[
relation_sym
]
||
relation_sym
@relation_name
=
OVERRIDES
[
relation_sym
]
||
relation_sym
@relation_hash
=
relation_hash
.
except
(
'id'
,
'noteable_id'
)
@relation_hash
=
relation_hash
.
except
(
'id'
,
'noteable_id'
)
.
merge
(
'project_id'
=>
project_id
)
@members_mapper
=
members_mapper
@members_mapper
=
members_mapper
@user
=
user
@user
=
user
@imported_object_retries
=
0
@imported_object_retries
=
0
...
@@ -153,7 +155,11 @@ module Gitlab
...
@@ -153,7 +155,11 @@ module Gitlab
end
end
def
parsed_relation_hash
def
parsed_relation_hash
@parsed_relation_hash
||=
@relation_hash
.
reject
{
|
k
,
_v
|
!
relation_class
.
attribute_method?
(
k
)
}
@parsed_relation_hash
||=
begin
Gitlab
::
ImportExport
::
AttributeCleaner
.
clean!
(
relation_hash:
@relation_hash
)
@relation_hash
.
reject
{
|
k
,
_v
|
!
relation_class
.
attribute_method?
(
k
)
}
end
end
end
def
set_st_diffs
def
set_st_diffs
...
...
lib/gitlab/import_export/repo_restorer.rb
View file @
e646439e
...
@@ -12,7 +12,7 @@ module Gitlab
...
@@ -12,7 +12,7 @@ module Gitlab
def
restore
def
restore
return
true
unless
File
.
exist?
(
@path_to_bundle
)
return
true
unless
File
.
exist?
(
@path_to_bundle
)
FileUtils
.
mkdir_p
(
path_to_repo
)
mkdir_p
(
path_to_repo
)
git_unbundle
(
repo_path:
path_to_repo
,
bundle_path:
@path_to_bundle
)
&&
repo_restore_hooks
git_unbundle
(
repo_path:
path_to_repo
,
bundle_path:
@path_to_bundle
)
&&
repo_restore_hooks
rescue
=>
e
rescue
=>
e
...
...
lib/gitlab/import_export/repo_saver.rb
View file @
e646439e
...
@@ -20,7 +20,7 @@ module Gitlab
...
@@ -20,7 +20,7 @@ module Gitlab
private
private
def
bundle_to_disk
def
bundle_to_disk
FileUtils
.
mkdir_p
(
@shared
.
export_path
)
mkdir_p
(
@shared
.
export_path
)
git_bundle
(
repo_path:
path_to_repo
,
bundle_path:
@full_path
)
git_bundle
(
repo_path:
path_to_repo
,
bundle_path:
@full_path
)
rescue
=>
e
rescue
=>
e
@shared
.
error
(
e
)
@shared
.
error
(
e
)
...
...
lib/gitlab/import_export/version_saver.rb
View file @
e646439e
module
Gitlab
module
Gitlab
module
ImportExport
module
ImportExport
class
VersionSaver
class
VersionSaver
include
Gitlab
::
ImportExport
::
CommandLineUtil
def
initialize
(
shared
:)
def
initialize
(
shared
:)
@shared
=
shared
@shared
=
shared
end
end
def
save
def
save
FileUtils
.
mkdir_p
(
@shared
.
export_path
)
mkdir_p
(
@shared
.
export_path
)
File
.
write
(
version_file
,
Gitlab
::
ImportExport
.
version
,
mode:
'w'
)
File
.
write
(
version_file
,
Gitlab
::
ImportExport
.
version
,
mode:
'w'
)
rescue
=>
e
rescue
=>
e
...
...
lib/gitlab/import_export/wiki_repo_saver.rb
View file @
e646439e
...
@@ -9,7 +9,7 @@ module Gitlab
...
@@ -9,7 +9,7 @@ module Gitlab
end
end
def
bundle_to_disk
(
full_path
)
def
bundle_to_disk
(
full_path
)
FileUtils
.
mkdir_p
(
@shared
.
export_path
)
mkdir_p
(
@shared
.
export_path
)
git_bundle
(
repo_path:
path_to_repo
,
bundle_path:
full_path
)
git_bundle
(
repo_path:
path_to_repo
,
bundle_path:
full_path
)
rescue
=>
e
rescue
=>
e
@shared
.
error
(
e
)
@shared
.
error
(
e
)
...
...
lib/gitlab/lfs_token.rb
View file @
e646439e
...
@@ -20,13 +20,8 @@ module Gitlab
...
@@ -20,13 +20,8 @@ module Gitlab
def
token
def
token
Gitlab
::
Redis
.
with
do
|
redis
|
Gitlab
::
Redis
.
with
do
|
redis
|
token
=
redis
.
get
(
redis_key
)
token
=
redis
.
get
(
redis_key
)
token
||=
Devise
.
friendly_token
(
TOKEN_LENGTH
)
if
token
redis
.
set
(
redis_key
,
token
,
ex:
EXPIRY_TIME
)
redis
.
expire
(
redis_key
,
EXPIRY_TIME
)
else
token
=
Devise
.
friendly_token
(
TOKEN_LENGTH
)
redis
.
set
(
redis_key
,
token
,
ex:
EXPIRY_TIME
)
end
token
token
end
end
...
...
spec/controllers/sessions_controller_spec.rb
View file @
e646439e
...
@@ -109,6 +109,44 @@ describe SessionsController do
...
@@ -109,6 +109,44 @@ describe SessionsController do
end
end
end
end
context
'when the user is on their last attempt'
do
before
do
user
.
update
(
failed_attempts:
User
.
maximum_attempts
.
pred
)
end
context
'when OTP is valid'
do
it
'authenticates correctly'
do
authenticate_2fa
(
otp_attempt:
user
.
current_otp
)
expect
(
subject
.
current_user
).
to
eq
user
end
end
context
'when OTP is invalid'
do
before
{
authenticate_2fa
(
otp_attempt:
'invalid'
)
}
it
'does not authenticate'
do
expect
(
subject
.
current_user
).
not_to
eq
user
end
it
'warns about invalid login'
do
expect
(
response
).
to
set_flash
.
now
[
:alert
]
.
to
/Invalid Login or password/
end
it
'locks the user'
do
expect
(
user
.
reload
).
to
be_access_locked
end
it
'keeps the user locked on future login attempts'
do
post
(
:create
,
user:
{
login:
user
.
username
,
password:
user
.
password
})
expect
(
response
)
.
to
set_flash
.
now
[
:alert
].
to
/Invalid Login or password/
end
end
end
context
'when another user does not have 2FA enabled'
do
context
'when another user does not have 2FA enabled'
do
let
(
:another_user
)
{
create
(
:user
)
}
let
(
:another_user
)
{
create
(
:user
)
}
...
...
spec/features/compare_spec.rb
View file @
e646439e
...
@@ -12,15 +12,16 @@ describe "Compare", js: true do
...
@@ -12,15 +12,16 @@ describe "Compare", js: true do
describe
"branches"
do
describe
"branches"
do
it
"pre-populates fields"
do
it
"pre-populates fields"
do
expect
(
page
.
find_field
(
"from"
).
value
).
to
eq
(
"master"
)
expect
(
find
(
".js-compare-from-dropdown .dropdown-toggle-text"
)).
to
have_content
(
"master"
)
expect
(
find
(
".js-compare-to-dropdown .dropdown-toggle-text"
)).
to
have_content
(
"master"
)
end
end
it
"compares branches"
do
it
"compares branches"
do
fill_in
"from"
,
with:
"fea
"
select_using_dropdown
"from"
,
"feature
"
find
(
"#from"
).
click
expect
(
find
(
".js-compare-from-dropdown .dropdown-toggle-text"
)).
to
have_content
(
"feature"
)
click_link
"feature
"
select_using_dropdown
"to"
,
"binary-encoding
"
expect
(
page
.
find_field
(
"from"
).
value
).
to
eq
(
"feature
"
)
expect
(
find
(
".js-compare-to-dropdown .dropdown-toggle-text"
)).
to
have_content
(
"binary-encoding
"
)
click_button
"Compare"
click_button
"Compare"
expect
(
page
).
to
have_content
"Commits"
expect
(
page
).
to
have_content
"Commits"
...
@@ -29,14 +30,21 @@ describe "Compare", js: true do
...
@@ -29,14 +30,21 @@ describe "Compare", js: true do
describe
"tags"
do
describe
"tags"
do
it
"compares tags"
do
it
"compares tags"
do
fill_in
"from"
,
with:
"v1
.0"
select_using_dropdown
"from"
,
"v1.0
.0"
find
(
"#from"
).
click
expect
(
find
(
".js-compare-from-dropdown .dropdown-toggle-text"
)).
to
have_content
(
"v1.0.0"
)
click_link
"v1.0
.0"
select_using_dropdown
"to"
,
"v1.1
.0"
expect
(
page
.
find_field
(
"from"
).
value
).
to
eq
(
"v1.0
.0"
)
expect
(
find
(
".js-compare-to-dropdown .dropdown-toggle-text"
)).
to
have_content
(
"v1.1
.0"
)
click_button
"Compare"
click_button
"Compare"
expect
(
page
).
to
have_content
"Commits"
expect
(
page
).
to
have_content
"Commits"
end
end
end
end
def
select_using_dropdown
(
dropdown_type
,
selection
)
dropdown
=
find
(
".js-compare-
#{
dropdown_type
}
-dropdown"
)
dropdown
.
find
(
".compare-dropdown-toggle"
).
click
dropdown
.
fill_in
(
"Filter by branch/tag"
,
with:
selection
)
click_link
selection
end
end
end
spec/features/projects/import_export/export_file_spec.rb
View file @
e646439e
...
@@ -47,6 +47,8 @@ feature 'Import/Export - project export integration test', feature: true, js: tr
...
@@ -47,6 +47,8 @@ feature 'Import/Export - project export integration test', feature: true, js: tr
expect
(
page
).
to
have_content
(
'Download export'
)
expect
(
page
).
to
have_content
(
'Download export'
)
expect
(
file_permissions
(
project
.
export_path
)).
to
eq
(
0700
)
in_directory_with_expanded_export
(
project
)
do
|
exit_status
,
tmpdir
|
in_directory_with_expanded_export
(
project
)
do
|
exit_status
,
tmpdir
|
expect
(
exit_status
).
to
eq
(
0
)
expect
(
exit_status
).
to
eq
(
0
)
...
...
spec/lib/gitlab/github_import/project_creator_spec.rb
View file @
e646439e
...
@@ -33,7 +33,7 @@ describe Gitlab::GithubImport::ProjectCreator, lib: true do
...
@@ -33,7 +33,7 @@ describe Gitlab::GithubImport::ProjectCreator, lib: true do
expect
(
project
.
import_data
.
credentials
).
to
eq
(
user:
'asdffg'
,
password:
nil
)
expect
(
project
.
import_data
.
credentials
).
to
eq
(
user:
'asdffg'
,
password:
nil
)
end
end
context
'when Git
h
ub project is private'
do
context
'when Git
H
ub project is private'
do
it
'sets project visibility to private'
do
it
'sets project visibility to private'
do
repo
.
private
=
true
repo
.
private
=
true
...
@@ -43,7 +43,7 @@ describe Gitlab::GithubImport::ProjectCreator, lib: true do
...
@@ -43,7 +43,7 @@ describe Gitlab::GithubImport::ProjectCreator, lib: true do
end
end
end
end
context
'when Git
h
ub project is public'
do
context
'when Git
H
ub project is public'
do
before
do
before
do
allow_any_instance_of
(
ApplicationSetting
).
to
receive
(
:default_project_visibility
).
and_return
(
Gitlab
::
VisibilityLevel
::
INTERNAL
)
allow_any_instance_of
(
ApplicationSetting
).
to
receive
(
:default_project_visibility
).
and_return
(
Gitlab
::
VisibilityLevel
::
INTERNAL
)
end
end
...
@@ -56,5 +56,25 @@ describe Gitlab::GithubImport::ProjectCreator, lib: true do
...
@@ -56,5 +56,25 @@ describe Gitlab::GithubImport::ProjectCreator, lib: true do
expect
(
project
.
visibility_level
).
to
eq
(
Gitlab
::
VisibilityLevel
::
INTERNAL
)
expect
(
project
.
visibility_level
).
to
eq
(
Gitlab
::
VisibilityLevel
::
INTERNAL
)
end
end
end
end
context
'when GitHub project has wiki'
do
it
'does not create the wiki repository'
do
allow
(
repo
).
to
receive
(
:has_wiki?
).
and_return
(
true
)
project
=
service
.
execute
expect
(
project
.
wiki
.
repository_exists?
).
to
eq
false
end
end
context
'when GitHub project does not have wiki'
do
it
'creates the wiki repository'
do
allow
(
repo
).
to
receive
(
:has_wiki?
).
and_return
(
false
)
project
=
service
.
execute
expect
(
project
.
wiki
.
repository_exists?
).
to
eq
true
end
end
end
end
end
end
spec/lib/gitlab/import_export/attribute_cleaner_spec.rb
0 → 100644
View file @
e646439e
require
'spec_helper'
describe
Gitlab
::
ImportExport
::
AttributeCleaner
,
lib:
true
do
let
(
:unsafe_hash
)
do
{
'service_id'
=>
99
,
'moved_to_id'
=>
99
,
'namespace_id'
=>
99
,
'ci_id'
=>
99
,
'random_project_id'
=>
99
,
'random_id'
=>
99
,
'milestone_id'
=>
99
,
'project_id'
=>
99
,
'user_id'
=>
99
,
'random_id_in_the_middle'
=>
99
,
'notid'
=>
99
}
end
let
(
:post_safe_hash
)
do
{
'project_id'
=>
99
,
'user_id'
=>
99
,
'random_id_in_the_middle'
=>
99
,
'notid'
=>
99
}
end
it
'removes unwanted attributes from the hash'
do
described_class
.
clean!
(
relation_hash:
unsafe_hash
)
expect
(
unsafe_hash
).
to
eq
(
post_safe_hash
)
end
end
spec/lib/gitlab/import_export/relation_factory_spec.rb
0 → 100644
View file @
e646439e
require
'spec_helper'
describe
Gitlab
::
ImportExport
::
RelationFactory
,
lib:
true
do
let
(
:project
)
{
create
(
:empty_project
)
}
let
(
:members_mapper
)
{
double
(
'members_mapper'
).
as_null_object
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:created_object
)
do
described_class
.
create
(
relation_sym:
relation_sym
,
relation_hash:
relation_hash
,
members_mapper:
members_mapper
,
user:
user
,
project_id:
project
.
id
)
end
context
'hook object'
do
let
(
:relation_sym
)
{
:hooks
}
let
(
:id
)
{
999
}
let
(
:service_id
)
{
99
}
let
(
:original_project_id
)
{
8
}
let
(
:token
)
{
'secret'
}
let
(
:relation_hash
)
do
{
'id'
=>
id
,
'url'
=>
'https://example.json'
,
'project_id'
=>
original_project_id
,
'created_at'
=>
'2016-08-12T09:41:03.462Z'
,
'updated_at'
=>
'2016-08-12T09:41:03.462Z'
,
'service_id'
=>
service_id
,
'push_events'
=>
true
,
'issues_events'
=>
false
,
'merge_requests_events'
=>
true
,
'tag_push_events'
=>
false
,
'note_events'
=>
true
,
'enable_ssl_verification'
=>
true
,
'build_events'
=>
false
,
'wiki_page_events'
=>
true
,
'token'
=>
token
}
end
it
'does not have the original ID'
do
expect
(
created_object
.
id
).
not_to
eq
(
id
)
end
it
'does not have the original service_id'
do
expect
(
created_object
.
service_id
).
not_to
eq
(
service_id
)
end
it
'does not have the original project_id'
do
expect
(
created_object
.
project_id
).
not_to
eq
(
original_project_id
)
end
it
'has the new project_id'
do
expect
(
created_object
.
project_id
).
to
eq
(
project
.
id
)
end
it
'has a token'
do
expect
(
created_object
.
token
).
to
eq
(
token
)
end
context
'original service exists'
do
let
(
:service_id
)
{
Service
.
create
(
project:
project
).
id
}
it
'does not have the original service_id'
do
expect
(
created_object
.
service_id
).
not_to
eq
(
service_id
)
end
end
end
# Mocks an ActiveRecordish object with the dodgy columns
class
FooModel
include
ActiveModel
::
Model
def
initialize
(
params
)
params
.
each
{
|
key
,
value
|
send
(
"
#{
key
}
="
,
value
)
}
end
def
values
instance_variables
.
map
{
|
ivar
|
instance_variable_get
(
ivar
)
}
end
end
# `project_id`, `described_class.USER_REFERENCES`, noteable_id, target_id, and some project IDs are already
# re-assigned by described_class.
context
'Potentially hazardous foreign keys'
do
let
(
:relation_sym
)
{
:hazardous_foo_model
}
let
(
:relation_hash
)
do
{
'service_id'
=>
99
,
'moved_to_id'
=>
99
,
'namespace_id'
=>
99
,
'ci_id'
=>
99
,
'random_project_id'
=>
99
,
'random_id'
=>
99
,
'milestone_id'
=>
99
,
'project_id'
=>
99
,
'user_id'
=>
99
,
}
end
class
HazardousFooModel
<
FooModel
attr_accessor
:service_id
,
:moved_to_id
,
:namespace_id
,
:ci_id
,
:random_project_id
,
:random_id
,
:milestone_id
,
:project_id
end
it
'does not preserve any foreign key IDs'
do
expect
(
created_object
.
values
).
not_to
include
(
99
)
end
end
context
'Project references'
do
let
(
:relation_sym
)
{
:project_foo_model
}
let
(
:relation_hash
)
do
Gitlab
::
ImportExport
::
RelationFactory
::
PROJECT_REFERENCES
.
map
{
|
ref
|
{
ref
=>
99
}
}.
inject
(
:merge
)
end
class
ProjectFooModel
<
FooModel
attr_accessor
(
*
Gitlab
::
ImportExport
::
RelationFactory
::
PROJECT_REFERENCES
)
end
it
'does not preserve any project foreign key IDs'
do
expect
(
created_object
.
values
).
not_to
include
(
99
)
end
end
end
spec/models/merge_request_spec.rb
View file @
e646439e
...
@@ -86,6 +86,30 @@ describe MergeRequest, models: true do
...
@@ -86,6 +86,30 @@ describe MergeRequest, models: true do
end
end
end
end
describe
'#cache_merge_request_closes_issues!'
do
before
do
subject
.
project
.
team
<<
[
subject
.
author
,
:developer
]
subject
.
target_branch
=
subject
.
project
.
default_branch
end
it
'caches closed issues'
do
issue
=
create
:issue
,
project:
subject
.
project
commit
=
double
(
'commit1'
,
safe_message:
"Fixes
#{
issue
.
to_reference
}
"
)
allow
(
subject
).
to
receive
(
:commits
).
and_return
([
commit
])
expect
{
subject
.
cache_merge_request_closes_issues!
}.
to
change
(
subject
.
merge_requests_closing_issues
,
:count
).
by
(
1
)
end
it
'does not cache issues from external trackers'
do
subject
.
project
.
update_attribute
(
:has_external_issue_tracker
,
true
)
issue
=
ExternalIssue
.
new
(
'JIRA-123'
,
subject
.
project
)
commit
=
double
(
'commit1'
,
safe_message:
"Fixes
#{
issue
.
to_reference
}
"
)
allow
(
subject
).
to
receive
(
:commits
).
and_return
([
commit
])
expect
{
subject
.
cache_merge_request_closes_issues!
}.
not_to
change
(
subject
.
merge_requests_closing_issues
,
:count
)
end
end
describe
'#source_branch_sha'
do
describe
'#source_branch_sha'
do
let
(
:last_branch_commit
)
{
subject
.
source_project
.
repository
.
commit
(
subject
.
source_branch
)
}
let
(
:last_branch_commit
)
{
subject
.
source_project
.
repository
.
commit
(
subject
.
source_branch
)
}
...
...
spec/models/service_spec.rb
View file @
e646439e
...
@@ -203,6 +203,23 @@ describe Service, models: true do
...
@@ -203,6 +203,23 @@ describe Service, models: true do
end
end
end
end
describe
'initialize service with no properties'
do
let
(
:service
)
do
GitlabIssueTrackerService
.
create
(
project:
create
(
:project
),
title:
'random title'
)
end
it
'does not raise error'
do
expect
{
service
}.
not_to
raise_error
end
it
'creates the properties'
do
expect
(
service
.
properties
).
to
eq
({
"title"
=>
"random title"
})
end
end
describe
"callbacks"
do
describe
"callbacks"
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let!
(
:service
)
do
let!
(
:service
)
do
...
...
spec/services/merge_requests/merge_service_spec.rb
View file @
e646439e
...
@@ -38,6 +38,42 @@ describe MergeRequests::MergeService, services: true do
...
@@ -38,6 +38,42 @@ describe MergeRequests::MergeService, services: true do
end
end
end
end
context
'closes related issues'
do
let
(
:service
)
{
described_class
.
new
(
project
,
user
,
commit_message:
'Awesome message'
)
}
before
do
allow
(
project
).
to
receive
(
:default_branch
).
and_return
(
merge_request
.
target_branch
)
end
it
'closes GitLab issue tracker issues'
do
issue
=
create
:issue
,
project:
project
commit
=
double
(
'commit'
,
safe_message:
"Fixes
#{
issue
.
to_reference
}
"
)
allow
(
merge_request
).
to
receive
(
:commits
).
and_return
([
commit
])
service
.
execute
(
merge_request
)
expect
(
issue
.
reload
.
closed?
).
to
be_truthy
end
context
'with JIRA integration'
do
include
JiraServiceHelper
let
(
:jira_tracker
)
{
project
.
create_jira_service
}
before
{
jira_service_settings
}
it
'closes issues on JIRA issue tracker'
do
jira_issue
=
ExternalIssue
.
new
(
'JIRA-123'
,
project
)
commit
=
double
(
'commit'
,
safe_message:
"Fixes
#{
jira_issue
.
to_reference
}
"
)
allow
(
merge_request
).
to
receive
(
:commits
).
and_return
([
commit
])
expect_any_instance_of
(
JiraService
).
to
receive
(
:close_issue
).
with
(
merge_request
,
jira_issue
).
once
service
.
execute
(
merge_request
)
end
end
end
context
'remove source branch by author'
do
context
'remove source branch by author'
do
let
(
:service
)
do
let
(
:service
)
do
merge_request
.
merge_params
[
'force_remove_source_branch'
]
=
'1'
merge_request
.
merge_params
[
'force_remove_source_branch'
]
=
'1'
...
...
spec/services/projects/destroy_service_spec.rb
View file @
e646439e
...
@@ -5,6 +5,7 @@ describe Projects::DestroyService, services: true do
...
@@ -5,6 +5,7 @@ describe Projects::DestroyService, services: true do
let!
(
:project
)
{
create
(
:project
,
namespace:
user
.
namespace
)
}
let!
(
:project
)
{
create
(
:project
,
namespace:
user
.
namespace
)
}
let!
(
:path
)
{
project
.
repository
.
path_to_repo
}
let!
(
:path
)
{
project
.
repository
.
path_to_repo
}
let!
(
:remove_path
)
{
path
.
sub
(
/\.git\Z/
,
"+
#{
project
.
id
}
+deleted.git"
)
}
let!
(
:remove_path
)
{
path
.
sub
(
/\.git\Z/
,
"+
#{
project
.
id
}
+deleted.git"
)
}
let!
(
:async
)
{
false
}
# execute or async_execute
context
'Sidekiq inline'
do
context
'Sidekiq inline'
do
before
do
before
do
...
@@ -28,6 +29,22 @@ describe Projects::DestroyService, services: true do
...
@@ -28,6 +29,22 @@ describe Projects::DestroyService, services: true do
it
{
expect
(
Dir
.
exist?
(
remove_path
)).
to
be_truthy
}
it
{
expect
(
Dir
.
exist?
(
remove_path
)).
to
be_truthy
}
end
end
context
'async delete of project with private issue visibility'
do
let!
(
:async
)
{
true
}
before
do
project
.
project_feature
.
update_attribute
(
"issues_access_level"
,
ProjectFeature
::
PRIVATE
)
# Run sidekiq immediately to check that renamed repository will be removed
Sidekiq
::
Testing
.
inline!
{
destroy_project
(
project
,
user
,
{})
}
end
it
'deletes the project'
do
expect
(
Project
.
all
).
not_to
include
(
project
)
expect
(
Dir
.
exist?
(
path
)).
to
be_falsey
expect
(
Dir
.
exist?
(
remove_path
)).
to
be_falsey
end
end
context
'container registry'
do
context
'container registry'
do
before
do
before
do
stub_container_registry_config
(
enabled:
true
)
stub_container_registry_config
(
enabled:
true
)
...
@@ -52,6 +69,10 @@ describe Projects::DestroyService, services: true do
...
@@ -52,6 +69,10 @@ describe Projects::DestroyService, services: true do
end
end
def
destroy_project
(
project
,
user
,
params
)
def
destroy_project
(
project
,
user
,
params
)
Projects
::
DestroyService
.
new
(
project
,
user
,
params
).
execute
if
async
Projects
::
DestroyService
.
new
(
project
,
user
,
params
).
async_execute
else
Projects
::
DestroyService
.
new
(
project
,
user
,
params
).
execute
end
end
end
end
end
spec/support/import_export/export_file_helper.rb
View file @
e646439e
...
@@ -130,4 +130,8 @@ module ExportFileHelper
...
@@ -130,4 +130,8 @@ module ExportFileHelper
(
parsed_model_attributes
-
parent
.
keys
-
excluded_attributes
).
empty?
(
parsed_model_attributes
-
parent
.
keys
-
excluded_attributes
).
empty?
end
end
def
file_permissions
(
file
)
File
.
stat
(
file
).
mode
&
0777
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