Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
李少辉-开发者
gitlab-foss
提交
a5b13534
G
gitlab-foss
项目概览
李少辉-开发者
/
gitlab-foss
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gitlab-foss
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a5b13534
编写于
2月 28, 2020
作者:
G
GitLab Bot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add latest changes from gitlab-org/security/gitlab@12-8-stable-ee
上级
557577fb
变更
45
隐藏空白更改
内联
并排
Showing
45 changed file
with
678 addition
and
114 deletion
+678
-114
app/assets/javascripts/error_tracking/components/error_details.vue
...s/javascripts/error_tracking/components/error_details.vue
+11
-11
app/controllers/groups/group_links_controller.rb
app/controllers/groups/group_links_controller.rb
+1
-1
app/graphql/types/diff_refs_type.rb
app/graphql/types/diff_refs_type.rb
+1
-1
app/models/group.rb
app/models/group.rb
+11
-0
app/presenters/ci/pipeline_presenter.rb
app/presenters/ci/pipeline_presenter.rb
+5
-1
app/services/groups/group_links/destroy_service.rb
app/services/groups/group_links/destroy_service.rb
+6
-8
app/services/groups/group_links/update_service.rb
app/services/groups/group_links/update_service.rb
+29
-0
app/services/projects/lfs_pointers/lfs_download_service.rb
app/services/projects/lfs_pointers/lfs_download_service.rb
+13
-6
app/services/projects/lfs_pointers/lfs_object_download_list_service.rb
...projects/lfs_pointers/lfs_object_download_list_service.rb
+6
-6
app/services/web_hook_service.rb
app/services/web_hook_service.rb
+7
-1
changelogs/unreleased/199035-sharing_group_to_update_project_authorization.yml
.../199035-sharing_group_to_update_project_authorization.yml
+5
-0
changelogs/unreleased/199415-sharing_group_to_respect_member_access_level.yml
...d/199415-sharing_group_to_respect_member_access_level.yml
+5
-0
changelogs/unreleased/36805-confidential-issue.yml
changelogs/unreleased/36805-confidential-issue.yml
+5
-0
changelogs/unreleased/security-check-mr-permissions-for-pipeline-widget.yml
...sed/security-check-mr-permissions-for-pipeline-widget.yml
+5
-0
changelogs/unreleased/security-deprecate-lfs-link-service.yml
...gelogs/unreleased/security-deprecate-lfs-link-service.yml
+5
-0
changelogs/unreleased/security-disable-pipeline-webhook-recursion.yml
...nreleased/security-disable-pipeline-webhook-recursion.yml
+5
-0
changelogs/unreleased/security-graphql-diff-refs-empty-base-sha.yml
.../unreleased/security-graphql-diff-refs-empty-base-sha.yml
+5
-0
changelogs/unreleased/security-pb-fix-xss-dependency-link.yml
...gelogs/unreleased/security-pb-fix-xss-dependency-link.yml
+5
-0
changelogs/unreleased/security-recalculate_project_authorizations_run_2.yml
...sed/security-recalculate_project_authorizations_run_2.yml
+5
-0
changelogs/unreleased/security-safe-sentry-error-culprit.yml
changelogs/unreleased/security-safe-sentry-error-culprit.yml
+5
-0
db/post_migrate/20200204113224_schedule_recalculate_project_authorizations_second_run.rb
...schedule_recalculate_project_authorizations_second_run.rb
+32
-0
doc/api/graphql/reference/gitlab_schema.graphql
doc/api/graphql/reference/gitlab_schema.graphql
+1
-1
doc/api/graphql/reference/gitlab_schema.json
doc/api/graphql/reference/gitlab_schema.json
+3
-7
doc/api/graphql/reference/index.md
doc/api/graphql/reference/index.md
+1
-1
lib/api/triggers.rb
lib/api/triggers.rb
+10
-0
lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id.rb
...ecalculate_project_authorizations_with_min_max_user_id.rb
+38
-0
lib/gitlab/dependency_linker/base_linker.rb
lib/gitlab/dependency_linker/base_linker.rb
+6
-1
lib/gitlab/project_authorizations.rb
lib/gitlab/project_authorizations.rb
+5
-1
lib/gitlab/user_access.rb
lib/gitlab/user_access.rb
+7
-1
spec/controllers/groups/group_links_controller_spec.rb
spec/controllers/groups/group_links_controller_spec.rb
+22
-4
spec/frontend/error_tracking/components/error_details_spec.js
.../frontend/error_tracking/components/error_details_spec.js
+22
-0
spec/graphql/types/diff_refs_type_spec.rb
spec/graphql/types/diff_refs_type_spec.rb
+5
-1
spec/lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id_spec.rb
...ulate_project_authorizations_with_min_max_user_id_spec.rb
+38
-0
spec/lib/gitlab/dependency_linker/base_linker_spec.rb
spec/lib/gitlab/dependency_linker/base_linker_spec.rb
+53
-0
spec/lib/gitlab/project_authorizations_spec.rb
spec/lib/gitlab/project_authorizations_spec.rb
+14
-0
spec/lib/gitlab/user_access_spec.rb
spec/lib/gitlab/user_access_spec.rb
+11
-0
spec/migrations/schedule_recalculate_project_authorizations_second_run_spec.rb
...ule_recalculate_project_authorizations_second_run_spec.rb
+28
-0
spec/models/group_spec.rb
spec/models/group_spec.rb
+39
-0
spec/models/project_spec.rb
spec/models/project_spec.rb
+32
-0
spec/presenters/ci/pipeline_presenter_spec.rb
spec/presenters/ci/pipeline_presenter_spec.rb
+84
-3
spec/requests/api/triggers_spec.rb
spec/requests/api/triggers_spec.rb
+12
-0
spec/services/groups/group_links/destroy_service_spec.rb
spec/services/groups/group_links/destroy_service_spec.rb
+1
-14
spec/services/groups/group_links/update_service_spec.rb
spec/services/groups/group_links/update_service_spec.rb
+59
-0
spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
...rvices/projects/lfs_pointers/lfs_download_service_spec.rb
+15
-12
spec/services/projects/lfs_pointers/lfs_object_download_list_service_spec.rb
...cts/lfs_pointers/lfs_object_download_list_service_spec.rb
+0
-33
未找到文件。
app/assets/javascripts/error_tracking/components/error_details.vue
浏览文件 @
a5b13534
...
@@ -104,16 +104,6 @@ export default {
...
@@ -104,16 +104,6 @@ export default {
'
errorStatus
'
,
'
errorStatus
'
,
]),
]),
...
mapGetters
(
'
details
'
,
[
'
stacktrace
'
]),
...
mapGetters
(
'
details
'
,
[
'
stacktrace
'
]),
reported
()
{
return
sprintf
(
__
(
'
Reported %{timeAgo} by %{reportedBy}
'
),
{
reportedBy
:
`<strong>
${
this
.
error
.
culprit
}
</strong>`
,
timeAgo
:
this
.
timeFormatted
(
this
.
stacktraceData
.
date_received
),
},
false
,
);
},
firstReleaseLink
()
{
firstReleaseLink
()
{
return
`
${
this
.
error
.
externalBaseUrl
}
/releases/
${
this
.
error
.
firstReleaseShortVersion
}
`
;
return
`
${
this
.
error
.
externalBaseUrl
}
/releases/
${
this
.
error
.
firstReleaseShortVersion
}
`
;
},
},
...
@@ -218,7 +208,17 @@ export default {
...
@@ -218,7 +208,17 @@ export default {
</gl-alert>
</gl-alert>
<div
class=
"top-area align-items-center justify-content-between py-3"
>
<div
class=
"top-area align-items-center justify-content-between py-3"
>
<span
v-if=
"!loadingStacktrace && stacktrace"
v-html=
"reported"
></span>
<div
v-if=
"!loadingStacktrace && stacktrace"
data-qa-selector=
"reported_text"
>
<gl-sprintf
:message=
"__('Reported %{timeAgo} by %{reportedBy}')"
>
<
template
#reportedBy
>
<strong>
{{
error
.
culprit
}}
</strong>
</
template
>
<
template
#timeAgo
>
{{
timeFormatted
(
stacktraceData
.
date_received
)
}}
</
template
>
</gl-sprintf>
</div>
<div
class=
"d-inline-flex ml-lg-auto"
>
<div
class=
"d-inline-flex ml-lg-auto"
>
<loading-button
<loading-button
:label=
"ignoreBtnLabel"
:label=
"ignoreBtnLabel"
...
...
app/controllers/groups/group_links_controller.rb
浏览文件 @
a5b13534
...
@@ -24,7 +24,7 @@ class Groups::GroupLinksController < Groups::ApplicationController
...
@@ -24,7 +24,7 @@ class Groups::GroupLinksController < Groups::ApplicationController
end
end
def
update
def
update
@group_link
.
upda
te
(
group_link_params
)
Groups
::
GroupLinks
::
UpdateService
.
new
(
@group_link
).
execu
te
(
group_link_params
)
end
end
def
destroy
def
destroy
...
...
app/graphql/types/diff_refs_type.rb
浏览文件 @
a5b13534
...
@@ -8,7 +8,7 @@ module Types
...
@@ -8,7 +8,7 @@ module Types
field
:head_sha
,
GraphQL
::
STRING_TYPE
,
null:
false
,
field
:head_sha
,
GraphQL
::
STRING_TYPE
,
null:
false
,
description:
'SHA of the HEAD at the time the comment was made'
description:
'SHA of the HEAD at the time the comment was made'
field
:base_sha
,
GraphQL
::
STRING_TYPE
,
null:
fals
e
,
field
:base_sha
,
GraphQL
::
STRING_TYPE
,
null:
tru
e
,
description:
'Merge base of the branch the comment was made on'
description:
'Merge base of the branch the comment was made on'
field
:start_sha
,
GraphQL
::
STRING_TYPE
,
null:
false
,
field
:start_sha
,
GraphQL
::
STRING_TYPE
,
null:
false
,
description:
'SHA of the branch being compared against'
description:
'SHA of the branch being compared against'
...
...
app/models/group.rb
浏览文件 @
a5b13534
...
@@ -509,18 +509,29 @@ class Group < Namespace
...
@@ -509,18 +509,29 @@ class Group < Namespace
group_group_links_query
=
GroupGroupLink
.
where
(
shared_group_id:
self_and_ancestors_ids
)
group_group_links_query
=
GroupGroupLink
.
where
(
shared_group_id:
self_and_ancestors_ids
)
cte
=
Gitlab
::
SQL
::
CTE
.
new
(
:group_group_links_cte
,
group_group_links_query
)
cte
=
Gitlab
::
SQL
::
CTE
.
new
(
:group_group_links_cte
,
group_group_links_query
)
cte_alias
=
cte
.
table
.
alias
(
GroupGroupLink
.
table_name
)
link
=
GroupGroupLink
link
=
GroupGroupLink
.
with
(
cte
.
to_arel
)
.
with
(
cte
.
to_arel
)
.
select
(
smallest_value_arel
([
cte_alias
[
:group_access
],
group_member_table
[
:access_level
]],
'group_access'
))
.
from
([
group_member_table
,
cte
.
alias_to
(
group_group_link_table
)])
.
from
([
group_member_table
,
cte
.
alias_to
(
group_group_link_table
)])
.
where
(
group_member_table
[
:user_id
].
eq
(
user
.
id
))
.
where
(
group_member_table
[
:user_id
].
eq
(
user
.
id
))
.
where
(
group_member_table
[
:requested_at
].
eq
(
nil
))
.
where
(
group_member_table
[
:source_id
].
eq
(
group_group_link_table
[
:shared_with_group_id
]))
.
where
(
group_member_table
[
:source_id
].
eq
(
group_group_link_table
[
:shared_with_group_id
]))
.
where
(
group_member_table
[
:source_type
].
eq
(
'Namespace'
))
.
reorder
(
Arel
::
Nodes
::
Descending
.
new
(
group_group_link_table
[
:group_access
]))
.
reorder
(
Arel
::
Nodes
::
Descending
.
new
(
group_group_link_table
[
:group_access
]))
.
first
.
first
link
&
.
group_access
link
&
.
group_access
end
end
def
smallest_value_arel
(
args
,
column_alias
)
Arel
::
Nodes
::
As
.
new
(
Arel
::
Nodes
::
NamedFunction
.
new
(
'LEAST'
,
args
),
Arel
::
Nodes
::
SqlLiteral
.
new
(
column_alias
))
end
def
self
.
groups_including_descendants_by
(
group_ids
)
def
self
.
groups_including_descendants_by
(
group_ids
)
Gitlab
::
ObjectHierarchy
Gitlab
::
ObjectHierarchy
.
new
(
Group
.
where
(
id:
group_ids
))
.
new
(
Group
.
where
(
id:
group_ids
))
...
...
app/presenters/ci/pipeline_presenter.rb
浏览文件 @
a5b13534
...
@@ -134,7 +134,11 @@ module Ci
...
@@ -134,7 +134,11 @@ module Ci
def
all_related_merge_requests
def
all_related_merge_requests
strong_memoize
(
:all_related_merge_requests
)
do
strong_memoize
(
:all_related_merge_requests
)
do
pipeline
.
ref
?
pipeline
.
all_merge_requests_by_recency
.
to_a
:
[]
if
pipeline
.
ref
&&
can?
(
current_user
,
:read_merge_request
,
pipeline
.
project
)
pipeline
.
all_merge_requests_by_recency
.
to_a
else
[]
end
end
end
end
end
end
end
...
...
app/services/groups/group_links/destroy_service.rb
浏览文件 @
a5b13534
...
@@ -6,19 +6,17 @@ module Groups
...
@@ -6,19 +6,17 @@ module Groups
def
execute
(
one_or_more_links
)
def
execute
(
one_or_more_links
)
links
=
Array
(
one_or_more_links
)
links
=
Array
(
one_or_more_links
)
GroupGroupLink
.
transaction
do
if
GroupGroupLink
.
delete
(
links
)
GroupGroupLink
.
delete
(
links
)
Gitlab
::
AppLogger
.
info
(
"GroupGroupLinks with ids:
#{
links
.
map
(
&
:id
)
}
have been deleted."
)
groups_to_refresh
=
links
.
map
(
&
:shared_with_group
)
groups_to_refresh
=
links
.
map
(
&
:shared_with_group
)
groups_to_refresh
.
uniq
.
each
do
|
group
|
groups_to_refresh
.
uniq
.
each
do
|
group
|
group
.
refresh_members_authorized_projects
group
.
refresh_members_authorized_projects
end
end
else
Gitlab
::
AppLogger
.
info
(
"GroupGroupLinks with ids:
#{
links
.
map
(
&
:id
)
}
have been deleted."
)
Gitlab
::
AppLogger
.
info
(
rescue
=>
ex
"Failed to delete GroupGroupLinks with ids:
#{
links
.
map
(
&
:id
)
}
."
)
Gitlab
::
AppLogger
.
error
(
ex
)
raise
end
end
end
end
end
end
...
...
app/services/groups/group_links/update_service.rb
0 → 100644
浏览文件 @
a5b13534
# frozen_string_literal: true
module
Groups
module
GroupLinks
class
UpdateService
<
BaseService
def
initialize
(
group_link
,
user
=
nil
)
super
(
group_link
.
shared_group
,
user
)
@group_link
=
group_link
end
def
execute
(
group_link_params
)
group_link
.
update!
(
group_link_params
)
if
requires_authorization_refresh?
(
group_link_params
)
group_link
.
shared_with_group
.
refresh_members_authorized_projects
end
end
private
attr_accessor
:group_link
def
requires_authorization_refresh?
(
params
)
params
.
include?
(
:group_access
)
end
end
end
end
app/services/projects/lfs_pointers/lfs_download_service.rb
浏览文件 @
a5b13534
...
@@ -16,17 +16,14 @@ module Projects
...
@@ -16,17 +16,14 @@ module Projects
@lfs_download_object
=
lfs_download_object
@lfs_download_object
=
lfs_download_object
end
end
# rubocop: disable CodeReuse/ActiveRecord
def
execute
def
execute
return
unless
project
&
.
lfs_enabled?
&&
lfs_download_object
return
unless
project
&
.
lfs_enabled?
&&
lfs_download_object
return
error
(
"LFS file with oid
#{
lfs_oid
}
has invalid attributes"
)
unless
lfs_download_object
.
valid?
return
error
(
"LFS file with oid
#{
lfs_oid
}
has invalid attributes"
)
unless
lfs_download_object
.
valid?
return
if
LfsObject
.
exists?
(
oid:
lfs_oid
)
wrap_download_errors
do
wrap_download_errors
do
download_lfs_file!
download_lfs_file!
end
end
end
end
# rubocop: enable CodeReuse/ActiveRecord
private
private
...
@@ -39,14 +36,24 @@ module Projects
...
@@ -39,14 +36,24 @@ module Projects
def
download_lfs_file!
def
download_lfs_file!
with_tmp_file
do
|
tmp_file
|
with_tmp_file
do
|
tmp_file
|
download_and_save_file!
(
tmp_file
)
download_and_save_file!
(
tmp_file
)
project
.
lfs_objects
<<
LfsObject
.
new
(
oid:
lfs_oid
,
size:
lfs_size
,
project
.
lfs_objects
<<
find_or_create_lfs_object
(
tmp_file
)
file:
tmp_file
)
success
success
end
end
end
end
def
find_or_create_lfs_object
(
tmp_file
)
lfs_obj
=
LfsObject
.
safe_find_or_create_by!
(
oid:
lfs_oid
,
size:
lfs_size
)
lfs_obj
.
update!
(
file:
tmp_file
)
unless
lfs_obj
.
file
.
file
lfs_obj
end
def
download_and_save_file!
(
file
)
def
download_and_save_file!
(
file
)
digester
=
Digest
::
SHA256
.
new
digester
=
Digest
::
SHA256
.
new
response
=
Gitlab
::
HTTP
.
get
(
lfs_sanitized_url
,
download_headers
)
do
|
fragment
|
response
=
Gitlab
::
HTTP
.
get
(
lfs_sanitized_url
,
download_headers
)
do
|
fragment
|
...
...
app/services/projects/lfs_pointers/lfs_object_download_list_service.rb
浏览文件 @
a5b13534
...
@@ -26,12 +26,12 @@ module Projects
...
@@ -26,12 +26,12 @@ module Projects
return
[]
return
[]
end
end
#
Getting all Lfs pointers already in the database and linking them to the project
#
Downloading the required information and gathering it inside an
linked_oids
=
LfsLinkService
.
new
(
project
).
execute
(
lfs_pointers_in_repository
.
keys
)
# LfsDownloadObject for each oid
#
Retrieving those oids not present in the database which we need to download
#
missing_oids
=
lfs_pointers_in_repository
.
except
(
*
linked_oids
)
LfsDownloadLinkListService
# Downloading the required information and gathering it inside a LfsDownloadObject for each oid
.
new
(
project
,
remote_uri:
current_endpoint_uri
)
LfsDownloadLinkListService
.
new
(
project
,
remote_uri:
current_endpoint_uri
).
execute
(
missing_oids
)
.
execute
(
lfs_pointers_in_repository
)
rescue
LfsDownloadLinkListService
::
DownloadLinksError
=>
e
rescue
LfsDownloadLinkListService
::
DownloadLinksError
=>
e
raise
LfsObjectDownloadListError
,
"The LFS objects download list couldn't be imported. Error:
#{
e
.
message
}
"
raise
LfsObjectDownloadListError
,
"The LFS objects download list couldn't be imported. Error:
#{
e
.
message
}
"
end
end
...
...
app/services/web_hook_service.rb
浏览文件 @
a5b13534
...
@@ -13,8 +13,14 @@ class WebHookService
...
@@ -13,8 +13,14 @@ class WebHookService
end
end
end
end
GITLAB_EVENT_HEADER
=
'X-Gitlab-Event'
attr_accessor
:hook
,
:data
,
:hook_name
,
:request_options
attr_accessor
:hook
,
:data
,
:hook_name
,
:request_options
def
self
.
hook_to_event
(
hook_name
)
hook_name
.
to_s
.
singularize
.
titleize
end
def
initialize
(
hook
,
data
,
hook_name
)
def
initialize
(
hook
,
data
,
hook_name
)
@hook
=
hook
@hook
=
hook
@data
=
data
@data
=
data
...
@@ -112,7 +118,7 @@ class WebHookService
...
@@ -112,7 +118,7 @@ class WebHookService
@headers
||=
begin
@headers
||=
begin
{
{
'Content-Type'
=>
'application/json'
,
'Content-Type'
=>
'application/json'
,
'X-Gitlab-Event'
=>
hook_name
.
singularize
.
titleize
GITLAB_EVENT_HEADER
=>
self
.
class
.
hook_to_event
(
hook_name
)
}.
tap
do
|
hash
|
}.
tap
do
|
hash
|
hash
[
'X-Gitlab-Token'
]
=
Gitlab
::
Utils
.
remove_line_breaks
(
hook
.
token
)
if
hook
.
token
.
present?
hash
[
'X-Gitlab-Token'
]
=
Gitlab
::
Utils
.
remove_line_breaks
(
hook
.
token
)
if
hook
.
token
.
present?
end
end
...
...
changelogs/unreleased/199035-sharing_group_to_update_project_authorization.yml
0 → 100644
浏览文件 @
a5b13534
---
title
:
Update ProjectAuthorization when deleting or updating GroupGroupLink
merge_request
:
author
:
type
:
security
changelogs/unreleased/199415-sharing_group_to_respect_member_access_level.yml
0 → 100644
浏览文件 @
a5b13534
---
title
:
Respect member access level for group shares
merge_request
:
author
:
type
:
security
changelogs/unreleased/36805-confidential-issue.yml
0 → 100644
浏览文件 @
a5b13534
---
title
:
Prevent an endless checking loop for two merge requests targeting each other
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-check-mr-permissions-for-pipeline-widget.yml
0 → 100644
浏览文件 @
a5b13534
---
title
:
Check merge requests read permissions before showing them in the pipeline widget
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-deprecate-lfs-link-service.yml
0 → 100644
浏览文件 @
a5b13534
---
title
:
Remove OID filtering during LFS imports
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-disable-pipeline-webhook-recursion.yml
0 → 100644
浏览文件 @
a5b13534
---
title
:
Protect against denial of service using pipeline webhook recursion
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-graphql-diff-refs-empty-base-sha.yml
0 → 100644
浏览文件 @
a5b13534
---
title
:
Don't require base_sha in DiffRefsType
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-pb-fix-xss-dependency-link.yml
0 → 100644
浏览文件 @
a5b13534
---
title
:
Sanitize output by dependency linkers
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-recalculate_project_authorizations_run_2.yml
0 → 100644
浏览文件 @
a5b13534
---
title
:
Recalculate ProjectAuthorizations for all users
merge_request
:
author
:
type
:
security
changelogs/unreleased/security-safe-sentry-error-culprit.yml
0 → 100644
浏览文件 @
a5b13534
---
title
:
Escape special chars in Sentry error header
merge_request
:
author
:
type
:
security
db/post_migrate/20200204113224_schedule_recalculate_project_authorizations_second_run.rb
0 → 100644
浏览文件 @
a5b13534
# frozen_string_literal: true
class
ScheduleRecalculateProjectAuthorizationsSecondRun
<
ActiveRecord
::
Migration
[
5.1
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
MIGRATION
=
'RecalculateProjectAuthorizationsWithMinMaxUserId'
BATCH_SIZE
=
2_500
DELAY_INTERVAL
=
2
.
minutes
.
to_i
disable_ddl_transaction!
class
User
<
ActiveRecord
::
Base
include
::
EachBatch
self
.
table_name
=
'users'
end
def
up
say
"Scheduling
#{
MIGRATION
}
jobs"
User
.
each_batch
(
of:
BATCH_SIZE
)
do
|
batch
,
index
|
delay
=
index
*
DELAY_INTERVAL
range
=
batch
.
pluck
(
'MIN(id)'
,
'MAX(id)'
).
first
BackgroundMigrationWorker
.
perform_in
(
delay
,
MIGRATION
,
range
)
end
end
def
down
end
end
doc/api/graphql/reference/gitlab_schema.graphql
浏览文件 @
a5b13534
...
@@ -1530,7 +1530,7 @@ type DiffRefs {
...
@@ -1530,7 +1530,7 @@ type DiffRefs {
"""
"""
Merge
base
of
the
branch
the
comment
was
made
on
Merge
base
of
the
branch
the
comment
was
made
on
"""
"""
baseSha
:
String
!
baseSha
:
String
"""
"""
SHA
of
the
HEAD
at
the
time
the
comment
was
made
SHA
of
the
HEAD
at
the
time
the
comment
was
made
...
...
doc/api/graphql/reference/gitlab_schema.json
浏览文件 @
a5b13534
...
@@ -8105,13 +8105,9 @@
...
@@ -8105,13 +8105,9 @@
],
],
"type": {
"type": {
"kind": "NON_NULL",
"kind": "SCALAR",
"name": null,
"name": "String",
"ofType": {
"ofType": null
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
},
"isDeprecated": false,
"isDeprecated": false,
"deprecationReason": null
"deprecationReason": null
...
...
doc/api/graphql/reference/index.md
浏览文件 @
a5b13534
...
@@ -253,7 +253,7 @@ Autogenerated return type of DestroySnippet
...
@@ -253,7 +253,7 @@ Autogenerated return type of DestroySnippet
| Name | Type | Description |
| Name | Type | Description |
| --- | ---- | ---------- |
| --- | ---- | ---------- |
|
`baseSha`
| String
!
| Merge base of the branch the comment was made on |
|
`baseSha`
| String | Merge base of the branch the comment was made on |
|
`headSha`
| String! | SHA of the HEAD at the time the comment was made |
|
`headSha`
| String! | SHA of the HEAD at the time the comment was made |
|
`startSha`
| String! | SHA of the branch being compared against |
|
`startSha`
| String! | SHA of the branch being compared against |
...
...
lib/api/triggers.rb
浏览文件 @
a5b13534
...
@@ -4,6 +4,8 @@ module API
...
@@ -4,6 +4,8 @@ module API
class
Triggers
<
Grape
::
API
class
Triggers
<
Grape
::
API
include
PaginationParams
include
PaginationParams
HTTP_GITLAB_EVENT_HEADER
=
"HTTP_
#{
WebHookService
::
GITLAB_EVENT_HEADER
}
"
.
underscore
.
upcase
params
do
params
do
requires
:id
,
type:
String
,
desc:
'The ID of a project'
requires
:id
,
type:
String
,
desc:
'The ID of a project'
end
end
...
@@ -19,6 +21,8 @@ module API
...
@@ -19,6 +21,8 @@ module API
post
":id/(ref/:ref/)trigger/pipeline"
,
requirements:
{
ref:
/.+/
}
do
post
":id/(ref/:ref/)trigger/pipeline"
,
requirements:
{
ref:
/.+/
}
do
Gitlab
::
QueryLimiting
.
whitelist
(
'https://gitlab.com/gitlab-org/gitlab-foss/issues/42283'
)
Gitlab
::
QueryLimiting
.
whitelist
(
'https://gitlab.com/gitlab-org/gitlab-foss/issues/42283'
)
forbidden!
if
gitlab_pipeline_hook_request?
# validate variables
# validate variables
params
[
:variables
]
=
params
[
:variables
].
to_h
params
[
:variables
]
=
params
[
:variables
].
to_h
unless
params
[
:variables
].
all?
{
|
key
,
value
|
key
.
is_a?
(
String
)
&&
value
.
is_a?
(
String
)
}
unless
params
[
:variables
].
all?
{
|
key
,
value
|
key
.
is_a?
(
String
)
&&
value
.
is_a?
(
String
)
}
...
@@ -128,5 +132,11 @@ module API
...
@@ -128,5 +132,11 @@ module API
destroy_conditionally!
(
trigger
)
destroy_conditionally!
(
trigger
)
end
end
end
end
helpers
do
def
gitlab_pipeline_hook_request?
request
.
get_header
(
HTTP_GITLAB_EVENT_HEADER
)
==
WebHookService
.
hook_to_event
(
:pipeline_hooks
)
end
end
end
end
end
end
lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id.rb
0 → 100644
浏览文件 @
a5b13534
# frozen_string_literal: true
module
Gitlab
module
BackgroundMigration
# rubocop:disable Style/Documentation
class
RecalculateProjectAuthorizationsWithMinMaxUserId
def
perform
(
min_user_id
,
max_user_id
)
User
.
where
(
id:
min_user_id
..
max_user_id
).
find_each
do
|
user
|
service
=
Users
::
RefreshAuthorizedProjectsService
.
new
(
user
,
incorrect_auth_found_callback:
->
(
project_id
,
access_level
)
do
logger
.
info
(
message:
'Removing ProjectAuthorizations'
,
user_id:
user
.
id
,
project_id:
project_id
,
access_level:
access_level
)
end
,
missing_auth_found_callback:
->
(
project_id
,
access_level
)
do
logger
.
info
(
message:
'Creating ProjectAuthorizations'
,
user_id:
user
.
id
,
project_id:
project_id
,
access_level:
access_level
)
end
)
service
.
execute
end
end
private
def
logger
@logger
||=
Gitlab
::
BackgroundMigration
::
Logger
.
build
end
end
end
end
lib/gitlab/dependency_linker/base_linker.rb
浏览文件 @
a5b13534
...
@@ -7,6 +7,8 @@ module Gitlab
...
@@ -7,6 +7,8 @@ module Gitlab
GIT_INVALID_URL_REGEX
=
/^git\+
#{
URL_REGEX
}
/
.
freeze
GIT_INVALID_URL_REGEX
=
/^git\+
#{
URL_REGEX
}
/
.
freeze
REPO_REGEX
=
%r{[^/'" ]+/[^/'" ]+}
.
freeze
REPO_REGEX
=
%r{[^/'" ]+/[^/'" ]+}
.
freeze
include
ActionView
::
Helpers
::
SanitizeHelper
class_attribute
:file_type
class_attribute
:file_type
def
self
.
support?
(
blob_name
)
def
self
.
support?
(
blob_name
)
...
@@ -62,7 +64,10 @@ module Gitlab
...
@@ -62,7 +64,10 @@ module Gitlab
end
end
def
link_tag
(
name
,
url
)
def
link_tag
(
name
,
url
)
%{<a href="#{ERB::Util.html_escape_once(url)}" rel="nofollow noreferrer noopener" target="_blank">#{ERB::Util.html_escape_once(name)}</a>}
.
html_safe
sanitize
(
%{<a href="#{ERB::Util.html_escape_once(url)}" rel="nofollow noreferrer noopener" target="_blank">#{ERB::Util.html_escape_once(name)}</a>}
,
attributes:
%w[href rel target]
)
end
end
# Links package names based on regex.
# Links package names based on regex.
...
...
lib/gitlab/project_authorizations.rb
浏览文件 @
a5b13534
...
@@ -62,6 +62,7 @@ module Gitlab
...
@@ -62,6 +62,7 @@ module Gitlab
cte
=
Gitlab
::
SQL
::
RecursiveCTE
.
new
(
:namespaces_cte
)
cte
=
Gitlab
::
SQL
::
RecursiveCTE
.
new
(
:namespaces_cte
)
members
=
Member
.
arel_table
members
=
Member
.
arel_table
namespaces
=
Namespace
.
arel_table
namespaces
=
Namespace
.
arel_table
group_group_links
=
GroupGroupLink
.
arel_table
# Namespaces the user is a member of.
# Namespaces the user is a member of.
cte
<<
user
.
groups
cte
<<
user
.
groups
...
@@ -69,7 +70,10 @@ module Gitlab
...
@@ -69,7 +70,10 @@ module Gitlab
.
except
(
:order
)
.
except
(
:order
)
# Namespaces shared with any of the group
# Namespaces shared with any of the group
cte
<<
Group
.
select
([
namespaces
[
:id
],
'group_group_links.group_access AS access_level'
])
cte
<<
Group
.
select
([
namespaces
[
:id
],
least
(
members
[
:access_level
],
group_group_links
[
:group_access
],
'access_level'
)])
.
joins
(
join_group_group_links
)
.
joins
(
join_group_group_links
)
.
joins
(
join_members_on_group_group_links
)
.
joins
(
join_members_on_group_group_links
)
...
...
lib/gitlab/user_access.rb
浏览文件 @
a5b13534
...
@@ -67,7 +67,13 @@ module Gitlab
...
@@ -67,7 +67,13 @@ module Gitlab
return
false
unless
can_access_git?
return
false
unless
can_access_git?
return
false
unless
project
return
false
unless
project
return
false
if
!
user
.
can?
(
:push_code
,
project
)
&&
!
project
.
branch_allows_collaboration?
(
user
,
ref
)
# Checking for an internal project to prevent an infinite loop:
# https://gitlab.com/gitlab-org/gitlab/issues/36805
if
project
.
internal?
return
false
unless
user
.
can?
(
:push_code
,
project
)
else
return
false
if
!
user
.
can?
(
:push_code
,
project
)
&&
!
project
.
branch_allows_collaboration?
(
user
,
ref
)
end
if
protected
?(
ProtectedBranch
,
project
,
ref
)
if
protected
?(
ProtectedBranch
,
project
,
ref
)
protected_branch_accessible_to?
(
ref
,
action:
:
push
)
protected_branch_accessible_to?
(
ref
,
action:
:
push
)
...
...
spec/controllers/groups/group_links_controller_spec.rb
浏览文件 @
a5b13534
...
@@ -6,9 +6,13 @@ describe Groups::GroupLinksController do
...
@@ -6,9 +6,13 @@ describe Groups::GroupLinksController do
let
(
:shared_with_group
)
{
create
(
:group
,
:private
)
}
let
(
:shared_with_group
)
{
create
(
:group
,
:private
)
}
let
(
:shared_group
)
{
create
(
:group
,
:private
)
}
let
(
:shared_group
)
{
create
(
:group
,
:private
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:group_member
)
{
create
(
:user
)
}
let!
(
:project
)
{
create
(
:project
,
group:
shared_group
)
}
before
do
before
do
sign_in
(
user
)
sign_in
(
user
)
shared_with_group
.
add_developer
(
group_member
)
end
end
describe
'#create'
do
describe
'#create'
do
...
@@ -40,13 +44,9 @@ describe Groups::GroupLinksController do
...
@@ -40,13 +44,9 @@ describe Groups::GroupLinksController do
end
end
context
'when user has correct access to both groups'
do
context
'when user has correct access to both groups'
do
let
(
:group_member
)
{
create
(
:user
)
}
before
do
before
do
shared_with_group
.
add_developer
(
user
)
shared_with_group
.
add_developer
(
user
)
shared_group
.
add_owner
(
user
)
shared_group
.
add_owner
(
user
)
shared_with_group
.
add_developer
(
group_member
)
end
end
context
'when default access level is requested'
do
context
'when default access level is requested'
do
...
@@ -56,6 +56,10 @@ describe Groups::GroupLinksController do
...
@@ -56,6 +56,10 @@ describe Groups::GroupLinksController do
context
'when owner access is requested'
do
context
'when owner access is requested'
do
let
(
:shared_group_access
)
{
Gitlab
::
Access
::
OWNER
}
let
(
:shared_group_access
)
{
Gitlab
::
Access
::
OWNER
}
before
do
shared_with_group
.
add_owner
(
group_member
)
end
include_examples
'creates group group link'
include_examples
'creates group group link'
it
'allows admin access for group member'
do
it
'allows admin access for group member'
do
...
@@ -64,6 +68,10 @@ describe Groups::GroupLinksController do
...
@@ -64,6 +68,10 @@ describe Groups::GroupLinksController do
end
end
end
end
it
'updates project permissions'
do
expect
{
subject
}.
to
change
{
group_member
.
can?
(
:read_project
,
project
)
}.
from
(
false
).
to
(
true
)
end
context
'when shared with group id is not present'
do
context
'when shared with group id is not present'
do
let
(
:shared_with_group_id
)
{
nil
}
let
(
:shared_with_group_id
)
{
nil
}
...
@@ -149,6 +157,7 @@ describe Groups::GroupLinksController do
...
@@ -149,6 +157,7 @@ describe Groups::GroupLinksController do
context
'when user has admin access to the shared group'
do
context
'when user has admin access to the shared group'
do
before
do
before
do
shared_group
.
add_owner
(
user
)
shared_group
.
add_owner
(
user
)
shared_with_group
.
refresh_members_authorized_projects
end
end
it
'updates existing link'
do
it
'updates existing link'
do
...
@@ -162,6 +171,10 @@ describe Groups::GroupLinksController do
...
@@ -162,6 +171,10 @@ describe Groups::GroupLinksController do
expect
(
link
.
group_access
).
to
eq
(
Gitlab
::
Access
::
GUEST
)
expect
(
link
.
group_access
).
to
eq
(
Gitlab
::
Access
::
GUEST
)
expect
(
link
.
expires_at
).
to
eq
(
expiry_date
)
expect
(
link
.
expires_at
).
to
eq
(
expiry_date
)
end
end
it
'updates project permissions'
do
expect
{
subject
}.
to
change
{
group_member
.
can?
(
:create_release
,
project
)
}.
from
(
true
).
to
(
false
)
end
end
end
context
'when user does not have admin access to the shared group'
do
context
'when user does not have admin access to the shared group'
do
...
@@ -199,11 +212,16 @@ describe Groups::GroupLinksController do
...
@@ -199,11 +212,16 @@ describe Groups::GroupLinksController do
context
'when user has admin access to the shared group'
do
context
'when user has admin access to the shared group'
do
before
do
before
do
shared_group
.
add_owner
(
user
)
shared_group
.
add_owner
(
user
)
shared_with_group
.
refresh_members_authorized_projects
end
end
it
'deletes existing link'
do
it
'deletes existing link'
do
expect
{
subject
}.
to
change
(
GroupGroupLink
,
:count
).
by
(
-
1
)
expect
{
subject
}.
to
change
(
GroupGroupLink
,
:count
).
by
(
-
1
)
end
end
it
'updates project permissions'
do
expect
{
subject
}.
to
change
{
group_member
.
can?
(
:create_release
,
project
)
}.
from
(
true
).
to
(
false
)
end
end
end
context
'when user does not have admin access to the shared group'
do
context
'when user does not have admin access to the shared group'
do
...
...
spec/frontend/error_tracking/components/error_details_spec.js
浏览文件 @
a5b13534
...
@@ -130,6 +130,28 @@ describe('ErrorDetails', () => {
...
@@ -130,6 +130,28 @@ describe('ErrorDetails', () => {
expect
(
wrapper
.
findAll
(
'
button
'
).
length
).
toBe
(
3
);
expect
(
wrapper
.
findAll
(
'
button
'
).
length
).
toBe
(
3
);
});
});
describe
(
'
unsafe chars for culprit field
'
,
()
=>
{
const
findReportedText
=
()
=>
wrapper
.
find
(
'
[data-qa-selector="reported_text"]
'
);
const
culprit
=
'
<script>console.log("surprise!")</script>
'
;
beforeEach
(()
=>
{
store
.
state
.
details
.
loadingStacktrace
=
false
;
wrapper
.
setData
({
error
:
{
culprit
,
},
});
});
it
(
'
should not convert interpolated text to html entities
'
,
()
=>
{
expect
(
findReportedText
().
findAll
(
'
script
'
).
length
).
toEqual
(
0
);
expect
(
findReportedText
().
findAll
(
'
strong
'
).
length
).
toEqual
(
1
);
});
it
(
'
should render text instead of converting to html entities
'
,
()
=>
{
expect
(
findReportedText
().
text
()).
toContain
(
culprit
);
});
});
describe
(
'
Badges
'
,
()
=>
{
describe
(
'
Badges
'
,
()
=>
{
it
(
'
should show language and error level badges
'
,
()
=>
{
it
(
'
should show language and error level badges
'
,
()
=>
{
wrapper
.
setData
({
wrapper
.
setData
({
...
...
spec/graphql/types/diff_refs_type_spec.rb
浏览文件 @
a5b13534
...
@@ -5,5 +5,9 @@ require 'spec_helper'
...
@@ -5,5 +5,9 @@ require 'spec_helper'
describe
GitlabSchema
.
types
[
'DiffRefs'
]
do
describe
GitlabSchema
.
types
[
'DiffRefs'
]
do
it
{
expect
(
described_class
.
graphql_name
).
to
eq
(
'DiffRefs'
)
}
it
{
expect
(
described_class
.
graphql_name
).
to
eq
(
'DiffRefs'
)
}
it
{
expect
(
described_class
).
to
have_graphql_fields
(
:base_sha
,
:head_sha
,
:start_sha
)
}
it
{
is_expected
.
to
have_graphql_fields
(
:head_sha
,
:base_sha
,
:start_sha
).
only
}
it
{
expect
(
described_class
.
fields
[
'headSha'
].
type
).
to
be_non_null
}
it
{
expect
(
described_class
.
fields
[
'baseSha'
].
type
).
not_to
be_non_null
}
it
{
expect
(
described_class
.
fields
[
'startSha'
].
type
).
to
be_non_null
}
end
end
spec/lib/gitlab/background_migration/recalculate_project_authorizations_with_min_max_user_id_spec.rb
0 → 100644
浏览文件 @
a5b13534
# frozen_string_literal: true
require
'spec_helper'
describe
Gitlab
::
BackgroundMigration
::
RecalculateProjectAuthorizationsWithMinMaxUserId
,
:migration
,
schema:
20200204113224
do
let
(
:users_table
)
{
table
(
:users
)
}
let
(
:min
)
{
1
}
let
(
:max
)
{
5
}
before
do
min
.
upto
(
max
)
do
|
i
|
users_table
.
create!
(
id:
i
,
email:
"user
#{
i
}
@example.com"
,
projects_limit:
10
)
end
end
describe
'#perform'
do
it
'initializes Users::RefreshAuthorizedProjectsService with correct users'
do
min
.
upto
(
max
)
do
|
i
|
user
=
User
.
find
(
i
)
expect
(
Users
::
RefreshAuthorizedProjectsService
).
to
(
receive
(
:new
).
with
(
user
,
any_args
).
and_call_original
)
end
described_class
.
new
.
perform
(
min
,
max
)
end
it
'executes Users::RefreshAuthorizedProjectsService'
do
expected_call_counts
=
max
-
min
+
1
service
=
instance_double
(
Users
::
RefreshAuthorizedProjectsService
)
expect
(
Users
::
RefreshAuthorizedProjectsService
).
to
(
receive
(
:new
).
exactly
(
expected_call_counts
).
times
.
and_return
(
service
))
expect
(
service
).
to
receive
(
:execute
).
exactly
(
expected_call_counts
).
times
described_class
.
new
.
perform
(
min
,
max
)
end
end
end
spec/lib/gitlab/dependency_linker/base_linker_spec.rb
0 → 100644
浏览文件 @
a5b13534
# frozen_string_literal: true
require
'spec_helper'
describe
Gitlab
::
DependencyLinker
::
BaseLinker
do
let
(
:linker_class
)
do
Class
.
new
(
described_class
)
do
def
link_dependencies
link_regex
(
%r{^(?<name>https?://[^ ]+)}
,
&
:itself
)
end
end
end
let
(
:plain_content
)
do
<<~
CONTENT
http://
\\
njavascript:alert(1)
https://gitlab.com/gitlab-org/gitlab
CONTENT
end
let
(
:highlighted_content
)
do
<<~
CONTENT
<span><span>http://</span><span>
\\
n</span><span>javascript:alert(1)</span></span>
<span><span>https://gitlab.com/gitlab-org/gitlab</span></span>
CONTENT
end
let
(
:linker
)
{
linker_class
.
new
(
plain_content
,
highlighted_content
)
}
describe
'#link'
do
subject
{
linker
.
link
}
it
'only converts valid links'
do
expect
(
subject
).
to
eq
(
<<~
CONTENT
<span><span>
#{
link
(
'http://'
)
}
</span><span>
#{
link
(
'\n'
,
url:
'%5Cn'
)
}
</span><span>
#{
link
(
'javascript:alert(1)'
,
url:
nil
)
}
</span></span>
<span><span>
#{
link
(
'https://gitlab.com/gitlab-org/gitlab'
)
}
</span></span>
CONTENT
)
end
end
def
link
(
text
,
url:
text
)
attrs
=
[
'rel="nofollow noreferrer noopener"'
,
'target="_blank"'
]
attrs
.
unshift
(
%{href="#{url}"}
)
if
url
%{<a #{attrs.join(' ')}>#{text}</a>}
end
end
spec/lib/gitlab/project_authorizations_spec.rb
浏览文件 @
a5b13534
...
@@ -109,6 +109,20 @@ describe Gitlab::ProjectAuthorizations do
...
@@ -109,6 +109,20 @@ describe Gitlab::ProjectAuthorizations do
end
end
end
end
context
'with lower group access level than max access level for share'
do
let
(
:user
)
{
create
(
:user
)
}
it
'creates proper authorizations'
do
group
.
add_reporter
(
user
)
mapping
=
map_access_levels
(
authorizations
)
expect
(
mapping
[
project_parent
.
id
]).
to
be_nil
expect
(
mapping
[
project
.
id
]).
to
eq
(
Gitlab
::
Access
::
REPORTER
)
expect
(
mapping
[
project_child
.
id
]).
to
eq
(
Gitlab
::
Access
::
REPORTER
)
end
end
context
'parent group user'
do
context
'parent group user'
do
let
(
:user
)
{
parent_group_user
}
let
(
:user
)
{
parent_group_user
}
...
...
spec/lib/gitlab/user_access_spec.rb
浏览文件 @
a5b13534
...
@@ -30,6 +30,17 @@ describe Gitlab::UserAccess do
...
@@ -30,6 +30,17 @@ describe Gitlab::UserAccess do
end
end
end
end
describe
'push to branch in an internal project'
do
it
'will not infinitely loop when a project is internal'
do
project
.
visibility_level
=
Gitlab
::
VisibilityLevel
::
INTERNAL
project
.
save!
expect
(
project
).
not_to
receive
(
:branch_allows_collaboration?
)
access
.
can_push_to_branch?
(
'master'
)
end
end
describe
'push to empty project'
do
describe
'push to empty project'
do
let
(
:empty_project
)
{
create
(
:project_empty_repo
)
}
let
(
:empty_project
)
{
create
(
:project_empty_repo
)
}
let
(
:project_access
)
{
described_class
.
new
(
user
,
project:
empty_project
)
}
let
(
:project_access
)
{
described_class
.
new
(
user
,
project:
empty_project
)
}
...
...
spec/migrations/schedule_recalculate_project_authorizations_second_run_spec.rb
0 → 100644
浏览文件 @
a5b13534
# frozen_string_literal: true
require
'spec_helper'
require
Rails
.
root
.
join
(
'db'
,
'post_migrate'
,
'20200204113224_schedule_recalculate_project_authorizations_second_run.rb'
)
describe
ScheduleRecalculateProjectAuthorizationsSecondRun
,
:migration
do
let
(
:users_table
)
{
table
(
:users
)
}
before
do
stub_const
(
"
#{
described_class
}
::BATCH_SIZE"
,
2
)
1
.
upto
(
4
)
do
|
i
|
users_table
.
create!
(
id:
i
,
name:
"user
#{
i
}
"
,
email:
"user
#{
i
}
@example.com"
,
projects_limit:
1
)
end
end
it
'schedules background migration'
do
Sidekiq
::
Testing
.
fake!
do
Timecop
.
freeze
do
migrate!
expect
(
BackgroundMigrationWorker
.
jobs
.
size
).
to
eq
(
2
)
expect
(
described_class
::
MIGRATION
).
to
be_scheduled_migration
(
1
,
2
)
expect
(
described_class
::
MIGRATION
).
to
be_scheduled_migration
(
3
,
4
)
end
end
end
end
spec/models/group_spec.rb
浏览文件 @
a5b13534
...
@@ -563,6 +563,18 @@ describe Group do
...
@@ -563,6 +563,18 @@ describe Group do
expect
(
shared_group
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
DEVELOPER
)
expect
(
shared_group
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
DEVELOPER
)
expect
(
shared_group_child
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
DEVELOPER
)
expect
(
shared_group_child
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
DEVELOPER
)
end
end
context
'with lower group access level than max access level for share'
do
let
(
:user
)
{
create
(
:user
)
}
it
'returns correct access level'
do
group
.
add_reporter
(
user
)
expect
(
shared_group_parent
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
NO_ACCESS
)
expect
(
shared_group
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
REPORTER
)
expect
(
shared_group_child
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
REPORTER
)
end
end
end
end
context
'with user in the parent group'
do
context
'with user in the parent group'
do
...
@@ -584,6 +596,33 @@ describe Group do
...
@@ -584,6 +596,33 @@ describe Group do
expect
(
shared_group_child
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
NO_ACCESS
)
expect
(
shared_group_child
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
NO_ACCESS
)
end
end
end
end
context
'unrelated project owner'
do
let
(
:common_id
)
{
[
Project
.
maximum
(
:id
).
to_i
,
Namespace
.
maximum
(
:id
).
to_i
].
max
+
999
}
let!
(
:group
)
{
create
(
:group
,
id:
common_id
)
}
let!
(
:unrelated_project
)
{
create
(
:project
,
id:
common_id
)
}
let
(
:user
)
{
unrelated_project
.
owner
}
it
'returns correct access level'
do
expect
(
shared_group_parent
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
NO_ACCESS
)
expect
(
shared_group
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
NO_ACCESS
)
expect
(
shared_group_child
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
NO_ACCESS
)
end
end
context
'user without accepted access request'
do
let!
(
:user
)
{
create
(
:user
)
}
before
do
create
(
:group_member
,
:developer
,
:access_request
,
user:
user
,
group:
group
)
end
it
'returns correct access level'
do
expect
(
shared_group_parent
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
NO_ACCESS
)
expect
(
shared_group
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
NO_ACCESS
)
expect
(
shared_group_child
.
max_member_access_for_user
(
user
)).
to
eq
(
Gitlab
::
Access
::
NO_ACCESS
)
end
end
end
end
context
'when feature flag share_group_with_group is disabled'
do
context
'when feature flag share_group_with_group is disabled'
do
...
...
spec/models/project_spec.rb
浏览文件 @
a5b13534
...
@@ -4793,6 +4793,38 @@ describe Project do
...
@@ -4793,6 +4793,38 @@ describe Project do
end
end
end
end
context
'with cross internal project merge requests'
do
let
(
:project
)
{
create
(
:project
,
:repository
,
:internal
)
}
let
(
:forked_project
)
{
fork_project
(
project
,
nil
,
repository:
true
)
}
let
(
:user
)
{
double
(
:user
)
}
it
"does not endlessly loop for internal projects with MRs to each other"
,
:sidekiq_inline
do
allow
(
user
).
to
receive
(
:can?
).
and_return
(
true
,
false
,
true
)
allow
(
user
).
to
receive
(
:id
).
and_return
(
1
)
create
(
:merge_request
,
target_project:
project
,
target_branch:
'merge-test'
,
source_project:
forked_project
,
source_branch:
'merge-test'
,
allow_collaboration:
true
)
create
(
:merge_request
,
target_project:
forked_project
,
target_branch:
'merge-test'
,
source_project:
project
,
source_branch:
'merge-test'
,
allow_collaboration:
true
)
expect
(
user
).
to
receive
(
:can?
).
at_most
(
5
).
times
project
.
branch_allows_collaboration?
(
user
,
"merge-test"
)
end
end
context
'with cross project merge requests'
do
context
'with cross project merge requests'
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:target_project
)
{
create
(
:project
,
:repository
)
}
let
(
:target_project
)
{
create
(
:project
,
:repository
)
}
...
...
spec/presenters/ci/pipeline_presenter_spec.rb
浏览文件 @
a5b13534
...
@@ -6,6 +6,7 @@ describe Ci::PipelinePresenter do
...
@@ -6,6 +6,7 @@ describe Ci::PipelinePresenter do
include
Gitlab
::
Routing
include
Gitlab
::
Routing
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:current_user
)
{
user
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:pipeline
)
{
create
(
:ci_pipeline
,
project:
project
)
}
let
(
:pipeline
)
{
create
(
:ci_pipeline
,
project:
project
)
}
...
@@ -15,7 +16,7 @@ describe Ci::PipelinePresenter do
...
@@ -15,7 +16,7 @@ describe Ci::PipelinePresenter do
before
do
before
do
project
.
add_developer
(
user
)
project
.
add_developer
(
user
)
allow
(
presenter
).
to
receive
(
:current_user
)
{
user
}
allow
(
presenter
).
to
receive
(
:current_user
)
{
current_
user
}
end
end
it
'inherits from Gitlab::View::Presenter::Delegated'
do
it
'inherits from Gitlab::View::Presenter::Delegated'
do
...
@@ -224,10 +225,90 @@ describe Ci::PipelinePresenter do
...
@@ -224,10 +225,90 @@ describe Ci::PipelinePresenter do
describe
'#all_related_merge_requests'
do
describe
'#all_related_merge_requests'
do
it
'memoizes the returned relation'
do
it
'memoizes the returned relation'
do
query_count
=
ActiveRecord
::
QueryRecorder
.
new
do
query_count
=
ActiveRecord
::
QueryRecorder
.
new
do
2
.
times
{
presenter
.
send
(
:all_related_merge_requests
).
count
}
3
.
times
{
presenter
.
send
(
:all_related_merge_requests
).
count
}
end
.
count
end
.
count
expect
(
query_count
).
to
eq
(
1
)
expect
(
query_count
).
to
eq
(
2
)
end
context
'permissions'
do
let!
(
:merge_request
)
do
create
(
:merge_request
,
project:
project
,
source_project:
project
)
end
subject
(
:all_related_merge_requests
)
do
presenter
.
send
(
:all_related_merge_requests
)
end
shared_examples
'private merge requests'
do
context
'when not logged in'
do
let
(
:current_user
)
{}
it
{
is_expected
.
to
be_empty
}
end
context
'when logged in as a non_member'
do
let
(
:current_user
)
{
create
(
:user
)
}
it
{
is_expected
.
to
be_empty
}
end
context
'when logged in as a guest'
do
let
(
:current_user
)
{
create
(
:user
)
}
before
do
project
.
add_guest
(
current_user
)
end
it
{
is_expected
.
to
be_empty
}
end
context
'when logged in as a developer'
do
it
{
is_expected
.
to
contain_exactly
(
merge_request
)
}
end
context
'when logged in as a maintainer'
do
let
(
:current_user
)
{
create
(
:user
)
}
before
do
project
.
add_maintainer
(
current_user
)
end
it
{
is_expected
.
to
contain_exactly
(
merge_request
)
}
end
end
context
'with a private project'
do
it_behaves_like
'private merge requests'
end
context
'with a public project with private merge requests'
do
before
do
project
.
update!
(
visibility_level:
Gitlab
::
VisibilityLevel
::
PUBLIC
)
project
.
project_feature
.
update!
(
merge_requests_access_level:
ProjectFeature
::
PRIVATE
)
end
it_behaves_like
'private merge requests'
end
context
'with a public project with public merge requests'
do
before
do
project
.
update!
(
visibility_level:
Gitlab
::
VisibilityLevel
::
PUBLIC
)
project
.
project_feature
.
update!
(
merge_requests_access_level:
ProjectFeature
::
ENABLED
)
end
context
'when not logged in'
do
let
(
:current_user
)
{}
it
{
is_expected
.
to
contain_exactly
(
merge_request
)
}
end
end
end
end
end
end
...
...
spec/requests/api/triggers_spec.rb
浏览文件 @
a5b13534
...
@@ -116,6 +116,18 @@ describe API::Triggers do
...
@@ -116,6 +116,18 @@ describe API::Triggers do
end
end
end
end
end
end
context
'when is triggered by a pipeline hook'
do
it
'does not create a new pipeline'
do
expect
do
post
api
(
"/projects/
#{
project
.
id
}
/ref/master/trigger/pipeline?token=
#{
trigger_token
}
"
),
params:
{
ref:
'refs/heads/other-branch'
},
headers:
{
WebHookService
::
GITLAB_EVENT_HEADER
=>
'Pipeline Hook'
}
end
.
not_to
change
(
Ci
::
Pipeline
,
:count
)
expect
(
response
).
to
have_gitlab_http_status
(
:forbidden
)
end
end
end
end
describe
'GET /projects/:id/triggers'
do
describe
'GET /projects/:id/triggers'
do
...
...
spec/services/groups/group_links/destroy_service_spec.rb
浏览文件 @
a5b13534
...
@@ -40,24 +40,11 @@ describe Groups::GroupLinks::DestroyService, '#execute' do
...
@@ -40,24 +40,11 @@ describe Groups::GroupLinks::DestroyService, '#execute' do
end
end
it
'updates project authorization once per group'
do
it
'updates project authorization once per group'
do
expect
(
GroupGroupLink
).
to
receive
(
:delete
)
expect
(
GroupGroupLink
).
to
receive
(
:delete
)
.
and_call_original
expect
(
group
).
to
receive
(
:refresh_members_authorized_projects
).
once
expect
(
group
).
to
receive
(
:refresh_members_authorized_projects
).
once
expect
(
another_group
).
to
receive
(
:refresh_members_authorized_projects
).
once
expect
(
another_group
).
to
receive
(
:refresh_members_authorized_projects
).
once
subject
.
execute
(
links
)
subject
.
execute
(
links
)
end
end
it
'rolls back changes when error happens'
do
group
.
add_developer
(
user
)
expect
(
group
).
to
receive
(
:refresh_members_authorized_projects
).
once
.
and_call_original
expect
(
another_group
).
to
(
receive
(
:refresh_members_authorized_projects
).
and_raise
(
'boom'
))
expect
{
subject
.
execute
(
links
)
}.
to
raise_error
(
'boom'
)
expect
(
GroupGroupLink
.
count
).
to
eq
(
links
.
length
)
expect
(
Ability
.
allowed?
(
user
,
:read_project
,
project
)).
to
be_truthy
end
end
end
end
end
spec/services/groups/group_links/update_service_spec.rb
0 → 100644
浏览文件 @
a5b13534
# frozen_string_literal: true
require
'spec_helper'
describe
Groups
::
GroupLinks
::
UpdateService
,
'#execute'
do
let
(
:user
)
{
create
(
:user
)
}
let_it_be
(
:group
)
{
create
(
:group
,
:private
)
}
let_it_be
(
:shared_group
)
{
create
(
:group
,
:private
)
}
let_it_be
(
:project
)
{
create
(
:project
,
group:
shared_group
)
}
let
(
:group_member
)
{
create
(
:user
)
}
let!
(
:link
)
{
create
(
:group_group_link
,
shared_group:
shared_group
,
shared_with_group:
group
)
}
let
(
:expiry_date
)
{
1
.
month
.
from_now
.
to_date
}
let
(
:group_link_params
)
do
{
group_access:
Gitlab
::
Access
::
GUEST
,
expires_at:
expiry_date
}
end
subject
{
described_class
.
new
(
link
).
execute
(
group_link_params
)
}
before
do
group
.
add_developer
(
group_member
)
end
it
'updates existing link'
do
expect
(
link
.
group_access
).
to
eq
(
Gitlab
::
Access
::
DEVELOPER
)
expect
(
link
.
expires_at
).
to
be_nil
subject
link
.
reload
expect
(
link
.
group_access
).
to
eq
(
Gitlab
::
Access
::
GUEST
)
expect
(
link
.
expires_at
).
to
eq
(
expiry_date
)
end
it
'updates project permissions'
do
expect
{
subject
}.
to
change
{
group_member
.
can?
(
:create_release
,
project
)
}.
from
(
true
).
to
(
false
)
end
it
'executes UserProjectAccessChangedService'
do
expect_next_instance_of
(
UserProjectAccessChangedService
)
do
|
service
|
expect
(
service
).
to
receive
(
:execute
)
end
subject
end
context
'with only param not requiring authorization refresh'
do
let
(
:group_link_params
)
{
{
expires_at:
Date
.
tomorrow
}
}
it
'does not execute UserProjectAccessChangedService'
do
expect
(
UserProjectAccessChangedService
).
not_to
receive
(
:new
)
subject
end
end
end
spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
浏览文件 @
a5b13534
...
@@ -134,6 +134,21 @@ describe Projects::LfsPointers::LfsDownloadService do
...
@@ -134,6 +134,21 @@ describe Projects::LfsPointers::LfsDownloadService do
end
end
end
end
context
'when an lfs object with the same oid already exists'
do
let!
(
:existing_lfs_object
)
{
create
(
:lfs_object
,
oid:
oid
)
}
before
do
stub_full_request
(
download_link
).
to_return
(
body:
lfs_content
)
end
it_behaves_like
'no lfs object is created'
it
'does not update the file attached to the existing LfsObject'
do
expect
{
subject
.
execute
}
.
not_to
change
{
existing_lfs_object
.
reload
.
file
.
file
.
file
}
end
end
context
'when credentials present'
do
context
'when credentials present'
do
let
(
:download_link_with_credentials
)
{
"http://user:password@gitlab.com/
#{
oid
}
"
}
let
(
:download_link_with_credentials
)
{
"http://user:password@gitlab.com/
#{
oid
}
"
}
let
(
:lfs_object
)
{
LfsDownloadObject
.
new
(
oid:
oid
,
size:
size
,
link:
download_link_with_credentials
)
}
let
(
:lfs_object
)
{
LfsDownloadObject
.
new
(
oid:
oid
,
size:
size
,
link:
download_link_with_credentials
)
}
...
@@ -211,17 +226,5 @@ describe Projects::LfsPointers::LfsDownloadService do
...
@@ -211,17 +226,5 @@ describe Projects::LfsPointers::LfsDownloadService do
subject
.
execute
subject
.
execute
end
end
end
end
context
'when an lfs object with the same oid already exists'
do
before
do
create
(
:lfs_object
,
oid:
oid
)
end
it
'does not download the file'
do
expect
(
subject
).
not_to
receive
(
:download_lfs_file!
)
subject
.
execute
end
end
end
end
end
end
spec/services/projects/lfs_pointers/lfs_object_download_list_service_spec.rb
浏览文件 @
a5b13534
...
@@ -24,7 +24,6 @@ describe Projects::LfsPointers::LfsObjectDownloadListService do
...
@@ -24,7 +24,6 @@ describe Projects::LfsPointers::LfsObjectDownloadListService do
describe
'#execute'
do
describe
'#execute'
do
context
'when no lfs pointer is linked'
do
context
'when no lfs pointer is linked'
do
before
do
before
do
allow_any_instance_of
(
Projects
::
LfsPointers
::
LfsLinkService
).
to
receive
(
:execute
).
and_return
([])
allow_any_instance_of
(
Projects
::
LfsPointers
::
LfsDownloadLinkListService
).
to
receive
(
:execute
).
and_return
(
oid_download_links
)
allow_any_instance_of
(
Projects
::
LfsPointers
::
LfsDownloadLinkListService
).
to
receive
(
:execute
).
and_return
(
oid_download_links
)
expect
(
Projects
::
LfsPointers
::
LfsDownloadLinkListService
).
to
receive
(
:new
).
with
(
project
,
remote_uri:
URI
.
parse
(
default_endpoint
)).
and_call_original
expect
(
Projects
::
LfsPointers
::
LfsDownloadLinkListService
).
to
receive
(
:new
).
with
(
project
,
remote_uri:
URI
.
parse
(
default_endpoint
)).
and_call_original
end
end
...
@@ -35,12 +34,6 @@ describe Projects::LfsPointers::LfsObjectDownloadListService do
...
@@ -35,12 +34,6 @@ describe Projects::LfsPointers::LfsObjectDownloadListService do
subject
.
execute
subject
.
execute
end
end
it
'links existent lfs objects to the project'
do
expect_any_instance_of
(
Projects
::
LfsPointers
::
LfsLinkService
).
to
receive
(
:execute
)
subject
.
execute
end
it
'retrieves the download links of non existent objects'
do
it
'retrieves the download links of non existent objects'
do
expect_any_instance_of
(
Projects
::
LfsPointers
::
LfsDownloadLinkListService
).
to
receive
(
:execute
).
with
(
all_oids
)
expect_any_instance_of
(
Projects
::
LfsPointers
::
LfsDownloadLinkListService
).
to
receive
(
:execute
).
with
(
all_oids
)
...
@@ -48,32 +41,6 @@ describe Projects::LfsPointers::LfsObjectDownloadListService do
...
@@ -48,32 +41,6 @@ describe Projects::LfsPointers::LfsObjectDownloadListService do
end
end
end
end
context
'when some lfs objects are linked'
do
before
do
allow_any_instance_of
(
Projects
::
LfsPointers
::
LfsLinkService
).
to
receive
(
:execute
).
and_return
(
existing_lfs_objects
.
keys
)
allow_any_instance_of
(
Projects
::
LfsPointers
::
LfsDownloadLinkListService
).
to
receive
(
:execute
).
and_return
(
oid_download_links
)
end
it
'retrieves the download links of non existent objects'
do
expect_any_instance_of
(
Projects
::
LfsPointers
::
LfsDownloadLinkListService
).
to
receive
(
:execute
).
with
(
oids
)
subject
.
execute
end
end
context
'when all lfs objects are linked'
do
before
do
allow_any_instance_of
(
Projects
::
LfsPointers
::
LfsLinkService
).
to
receive
(
:execute
).
and_return
(
all_oids
.
keys
)
allow_any_instance_of
(
Projects
::
LfsPointers
::
LfsDownloadLinkListService
).
to
receive
(
:execute
)
end
it
'retrieves no download links'
do
expect_any_instance_of
(
Projects
::
LfsPointers
::
LfsDownloadLinkListService
).
to
receive
(
:execute
).
with
({}).
and_call_original
expect
(
subject
.
execute
).
to
be_empty
end
end
context
'when lfsconfig file exists'
do
context
'when lfsconfig file exists'
do
before
do
before
do
allow
(
project
.
repository
).
to
receive
(
:lfsconfig_for
).
and_return
(
"[lfs]
\n\t
url =
#{
lfs_endpoint
}
\n
"
)
allow
(
project
.
repository
).
to
receive
(
:lfsconfig_for
).
and_return
(
"[lfs]
\n\t
url =
#{
lfs_endpoint
}
\n
"
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录