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
1
Merge Requests
1
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
nexedi
gitlab-ce
Commits
1ea8d32d
Commit
1ea8d32d
authored
Oct 02, 2019
by
Marin Jankovski
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of dev.gitlab.org:gitlab/gitlab-ee
parents
96ba082d
9a9755d6
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
566 additions
and
28 deletions
+566
-28
CHANGELOG-EE.md
CHANGELOG-EE.md
+7
-0
CHANGELOG.md
CHANGELOG.md
+7
-0
app/models/project.rb
app/models/project.rb
+6
-1
app/models/project_feature.rb
app/models/project_feature.rb
+2
-1
changelogs/unreleased/security-29491.yml
changelogs/unreleased/security-29491.yml
+5
-0
ee/lib/elastic/latest/application_class_proxy.rb
ee/lib/elastic/latest/application_class_proxy.rb
+26
-6
ee/lib/gitlab/elastic/search_results.rb
ee/lib/gitlab/elastic/search_results.rb
+12
-6
ee/spec/lib/gitlab/elastic/project_search_results_spec.rb
ee/spec/lib/gitlab/elastic/project_search_results_spec.rb
+1
-1
ee/spec/lib/gitlab/elastic/search_results_spec.rb
ee/spec/lib/gitlab/elastic/search_results_spec.rb
+16
-9
ee/spec/models/concerns/elastic/issue_spec.rb
ee/spec/models/concerns/elastic/issue_spec.rb
+3
-2
ee/spec/models/concerns/elastic/merge_request_spec.rb
ee/spec/models/concerns/elastic/merge_request_spec.rb
+4
-2
ee/spec/services/search/global_service_spec.rb
ee/spec/services/search/global_service_spec.rb
+89
-0
ee/spec/services/search/group_service_spec.rb
ee/spec/services/search/group_service_spec.rb
+93
-0
ee/spec/services/search/project_service_spec.rb
ee/spec/services/search/project_service_spec.rb
+66
-0
ee/spec/support/helpers/search_results_helpers.rb
ee/spec/support/helpers/search_results_helpers.rb
+32
-0
spec/models/project_feature_spec.rb
spec/models/project_feature_spec.rb
+24
-0
spec/models/project_spec.rb
spec/models/project_spec.rb
+30
-0
spec/support/helpers/project_helpers.rb
spec/support/helpers/project_helpers.rb
+25
-0
spec/support/shared_contexts/policies/project_policy_table_shared_context.rb
..._contexts/policies/project_policy_table_shared_context.rb
+118
-0
No files found.
CHANGELOG-EE.md
View file @
1ea8d32d
...
@@ -195,6 +195,13 @@ Please view this file on the master branch, on stable branches it's out of date.
...
@@ -195,6 +195,13 @@ Please view this file on the master branch, on stable branches it's out of date.
-
Fixes style-lint errors and warnings for EE builds.scss file.
-
Fixes style-lint errors and warnings for EE builds.scss file.
## 12.2.7
### Security (1 change)
-
Restrict access for security reports in MR widget.
## 12.2.6
## 12.2.6
### Security (3 changes)
### Security (3 changes)
...
...
CHANGELOG.md
View file @
1ea8d32d
...
@@ -299,6 +299,13 @@ entry.
...
@@ -299,6 +299,13 @@ entry.
-
Updates tooltip of 'detached' label/state.
-
Updates tooltip of 'detached' label/state.
## 12.2.7
### Security (1 change)
-
Fix private feature Elasticsearch leak.
## 12.2.6
## 12.2.6
### Security (11 changes)
### Security (11 changes)
...
...
app/models/project.rb
View file @
1ea8d32d
...
@@ -482,7 +482,7 @@ class Project < ApplicationRecord
...
@@ -482,7 +482,7 @@ class Project < ApplicationRecord
# the feature is either public, enabled, or internal with permission for the user.
# the feature is either public, enabled, or internal with permission for the user.
# Note: this scope doesn't enforce that the user has access to the projects, it just checks
# Note: this scope doesn't enforce that the user has access to the projects, it just checks
# that the user has access to the feature. It's important to use this scope with others
# that the user has access to the feature. It's important to use this scope with others
# that checks project authorizations first.
# that checks project authorizations first
(e.g. `filter_by_feature_visibility`)
.
#
#
# This method uses an optimised version of `with_feature_access_level` for
# This method uses an optimised version of `with_feature_access_level` for
# logged in users to more efficiently get private projects with the given
# logged in users to more efficiently get private projects with the given
...
@@ -510,6 +510,11 @@ class Project < ApplicationRecord
...
@@ -510,6 +510,11 @@ class Project < ApplicationRecord
end
end
end
end
# This scope returns projects where user has access to both the project and the feature.
def
self
.
filter_by_feature_visibility
(
feature
,
user
)
with_feature_available_for_user
(
feature
,
user
).
public_or_visible_to_user
(
user
)
end
scope
:active
,
->
{
joins
(
:issues
,
:notes
,
:merge_requests
).
order
(
'issues.created_at, notes.created_at, merge_requests.created_at DESC'
)
}
scope
:active
,
->
{
joins
(
:issues
,
:notes
,
:merge_requests
).
order
(
'issues.created_at, notes.created_at, merge_requests.created_at DESC'
)
}
scope
:abandoned
,
->
{
where
(
'projects.last_activity_at < ?'
,
6
.
months
.
ago
)
}
scope
:abandoned
,
->
{
where
(
'projects.last_activity_at < ?'
,
6
.
months
.
ago
)
}
...
...
app/models/project_feature.rb
View file @
1ea8d32d
...
@@ -62,7 +62,8 @@ class ProjectFeature < ApplicationRecord
...
@@ -62,7 +62,8 @@ class ProjectFeature < ApplicationRecord
private
private
def
ensure_feature!
(
feature
)
def
ensure_feature!
(
feature
)
feature
=
feature
.
model_name
.
plural
.
to_sym
if
feature
.
respond_to?
(
:model_name
)
feature
=
feature
.
model_name
.
plural
if
feature
.
respond_to?
(
:model_name
)
feature
=
feature
.
to_sym
raise
ArgumentError
,
"invalid project feature:
#{
feature
}
"
unless
FEATURES
.
include?
(
feature
)
raise
ArgumentError
,
"invalid project feature:
#{
feature
}
"
unless
FEATURES
.
include?
(
feature
)
feature
feature
...
...
ee/changelogs/unreleased/restrict-access-for-sec-reports
.yml
→
changelogs/unreleased/security-29491
.yml
View file @
1ea8d32d
---
---
title
:
Restrict access for security reports in MR widget
title
:
Fix private feature Elasticsearch leak
merge_request
:
merge_request
:
author
:
author
:
type
:
security
type
:
security
ee/lib/elastic/latest/application_class_proxy.rb
View file @
1ea8d32d
...
@@ -128,7 +128,7 @@ module Elastic
...
@@ -128,7 +128,7 @@ module Elastic
# anonymous users.
# anonymous users.
# Pick private, internal and public projects the user is a member of.
# Pick private, internal and public projects the user is a member of.
# Pick all private projects for admins & auditors.
# Pick all private projects for admins & auditors.
conditions
=
[
pick_projects_by_membership
(
project_ids
,
features
)]
conditions
=
[
pick_projects_by_membership
(
project_ids
,
user
,
features
)]
if
public_and_internal_projects
if
public_and_internal_projects
# Skip internal projects for anonymous and external users.
# Skip internal projects for anonymous and external users.
...
@@ -152,15 +152,28 @@ module Elastic
...
@@ -152,15 +152,28 @@ module Elastic
# Admins & auditors are given access to all private projects. Access to
# Admins & auditors are given access to all private projects. Access to
# internal or public projects where the project feature is private is not
# internal or public projects where the project feature is private is not
# granted here.
# granted here.
def
pick_projects_by_membership
(
project_ids
,
features
=
nil
)
def
pick_projects_by_membership
(
project_ids
,
user
,
features
=
nil
)
condition
=
if
features
.
nil?
if
project_ids
==
:any
if
project_ids
==
:any
{
term:
{
visibility_level:
Project
::
PRIVATE
}
}
return
{
term:
{
visibility_level:
Project
::
PRIVATE
}
}
else
else
{
terms:
{
id:
project_ids
}
}
return
{
terms:
{
id:
project_ids
}
}
end
end
end
Array
(
features
).
map
do
|
feature
|
condition
=
if
project_ids
==
:any
{
term:
{
visibility_level:
Project
::
PRIVATE
}
}
else
{
terms:
{
id:
filter_ids_by_feature
(
project_ids
,
user
,
feature
)
}
}
end
limit
=
{
terms:
{
"
#{
feature
}
_access_level"
=>
[
::
ProjectFeature
::
ENABLED
,
::
ProjectFeature
::
PRIVATE
]
}
}
limit_by_feature
(
condition
,
features
,
include_members_only:
true
)
{
bool:
{
filter:
[
condition
,
limit
]
}
}
end
end
end
# Grant access to projects of the specified visibility level to the user.
# Grant access to projects of the specified visibility level to the user.
...
@@ -198,6 +211,13 @@ module Elastic
...
@@ -198,6 +211,13 @@ module Elastic
{
bool:
{
filter:
[
condition
,
limit
]
}
}
{
bool:
{
filter:
[
condition
,
limit
]
}
}
end
end
end
end
def
filter_ids_by_feature
(
project_ids
,
user
,
feature
)
Project
.
id_in
(
project_ids
)
.
filter_by_feature_visibility
(
feature
,
user
)
.
pluck_primary_key
end
end
end
end
end
end
end
ee/lib/gitlab/elastic/search_results.rb
View file @
1ea8d32d
...
@@ -278,20 +278,26 @@ module Gitlab
...
@@ -278,20 +278,26 @@ module Gitlab
end
end
def
wiki_filter
def
wiki_filter
blob_filter
(
:wiki
_access_level
,
visible_for_guests:
true
)
blob_filter
(
:wiki
,
visible_for_guests:
true
)
end
end
def
repository_filter
def
repository_filter
blob_filter
(
:repository
_access_level
)
blob_filter
(
:repository
)
end
end
def
blob_filter
(
project_feature_nam
e
,
visible_for_guests:
false
)
def
blob_filter
(
featur
e
,
visible_for_guests:
false
)
project_ids
=
visible_for_guests
?
limit_project_ids
:
non_guest_project_ids
project_ids
=
visible_for_guests
?
limit_project_ids
:
non_guest_project_ids
key_name
=
"
#{
feature
}
_access_level"
conditions
=
conditions
=
if
project_ids
==
:any
if
project_ids
==
:any
[{
exists:
{
field:
"id"
}
}]
[{
exists:
{
field:
"id"
}
}]
else
else
project_ids
=
Project
.
id_in
(
project_ids
)
.
filter_by_feature_visibility
(
feature
,
current_user
)
.
pluck_primary_key
[{
terms:
{
id:
project_ids
}
}]
[{
terms:
{
id:
project_ids
}
}]
end
end
...
@@ -300,7 +306,7 @@ module Gitlab
...
@@ -300,7 +306,7 @@ module Gitlab
bool:
{
bool:
{
filter:
[
filter:
[
{
term:
{
visibility_level:
Project
::
PUBLIC
}
},
{
term:
{
visibility_level:
Project
::
PUBLIC
}
},
{
term:
{
project_feature
_name
=>
ProjectFeature
::
ENABLED
}
}
{
term:
{
key
_name
=>
ProjectFeature
::
ENABLED
}
}
]
]
}
}
}
}
...
@@ -310,7 +316,7 @@ module Gitlab
...
@@ -310,7 +316,7 @@ module Gitlab
bool:
{
bool:
{
filter:
[
filter:
[
{
term:
{
visibility_level:
Project
::
INTERNAL
}
},
{
term:
{
visibility_level:
Project
::
INTERNAL
}
},
{
term:
{
project_feature
_name
=>
ProjectFeature
::
ENABLED
}
}
{
term:
{
key
_name
=>
ProjectFeature
::
ENABLED
}
}
]
]
}
}
}
}
...
@@ -323,7 +329,7 @@ module Gitlab
...
@@ -323,7 +329,7 @@ module Gitlab
query:
{
query:
{
bool:
{
bool:
{
should:
conditions
,
should:
conditions
,
must_not:
{
term:
{
project_feature
_name
=>
ProjectFeature
::
DISABLED
}
}
must_not:
{
term:
{
key
_name
=>
ProjectFeature
::
DISABLED
}
}
}
}
}
}
}
}
...
...
ee/spec/lib/gitlab/elastic/project_search_results_spec.rb
View file @
1ea8d32d
...
@@ -4,7 +4,7 @@ require 'spec_helper'
...
@@ -4,7 +4,7 @@ require 'spec_helper'
describe
Gitlab
::
Elastic
::
ProjectSearchResults
,
:elastic
do
describe
Gitlab
::
Elastic
::
ProjectSearchResults
,
:elastic
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
,
:repository
)
}
let
(
:project
)
{
create
(
:project
,
:
public
,
:
repository
)
}
let
(
:query
)
{
'hello world'
}
let
(
:query
)
{
'hello world'
}
before
do
before
do
...
...
ee/spec/lib/gitlab/elastic/search_results_spec.rb
View file @
1ea8d32d
...
@@ -8,8 +8,8 @@ describe Gitlab::Elastic::SearchResults, :elastic do
...
@@ -8,8 +8,8 @@ describe Gitlab::Elastic::SearchResults, :elastic do
end
end
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:project_1
)
{
create
(
:project
,
:repository
,
:wiki_repo
)
}
let
(
:project_1
)
{
create
(
:project
,
:
public
,
:
repository
,
:wiki_repo
)
}
let
(
:project_2
)
{
create
(
:project
,
:repository
,
:wiki_repo
)
}
let
(
:project_2
)
{
create
(
:project
,
:
public
,
:
repository
,
:wiki_repo
)
}
let
(
:limit_project_ids
)
{
[
project_1
.
id
]
}
let
(
:limit_project_ids
)
{
[
project_1
.
id
]
}
describe
'counts'
do
describe
'counts'
do
...
@@ -154,7 +154,7 @@ describe Gitlab::Elastic::SearchResults, :elastic do
...
@@ -154,7 +154,7 @@ describe Gitlab::Elastic::SearchResults, :elastic do
end
end
it
'lists issue when search by a valid iid'
do
it
'lists issue when search by a valid iid'
do
results
=
described_class
.
new
(
user
,
'#2'
,
limit_project_ids
)
results
=
described_class
.
new
(
user
,
'#2'
,
limit_project_ids
,
nil
,
false
)
issues
=
results
.
objects
(
'issues'
)
issues
=
results
.
objects
(
'issues'
)
expect
(
issues
).
not_to
include
@issue_1
expect
(
issues
).
not_to
include
@issue_1
...
@@ -218,8 +218,8 @@ describe Gitlab::Elastic::SearchResults, :elastic do
...
@@ -218,8 +218,8 @@ describe Gitlab::Elastic::SearchResults, :elastic do
end
end
describe
'confidential issues'
do
describe
'confidential issues'
do
let
(
:project_3
)
{
create
(
:project
)
}
let
(
:project_3
)
{
create
(
:project
,
:public
)
}
let
(
:project_4
)
{
create
(
:project
)
}
let
(
:project_4
)
{
create
(
:project
,
:public
)
}
let
(
:limit_project_ids
)
{
[
project_1
.
id
,
project_2
.
id
,
project_3
.
id
]
}
let
(
:limit_project_ids
)
{
[
project_1
.
id
,
project_2
.
id
,
project_3
.
id
]
}
let
(
:author
)
{
create
(
:user
)
}
let
(
:author
)
{
create
(
:user
)
}
let
(
:assignee
)
{
create
(
:user
)
}
let
(
:assignee
)
{
create
(
:user
)
}
...
@@ -318,8 +318,8 @@ describe Gitlab::Elastic::SearchResults, :elastic do
...
@@ -318,8 +318,8 @@ describe Gitlab::Elastic::SearchResults, :elastic do
expect
(
issues
).
to
include
@security_issue_2
expect
(
issues
).
to
include
@security_issue_2
expect
(
issues
).
to
include
@security_issue_3
expect
(
issues
).
to
include
@security_issue_3
expect
(
issues
).
to
include
@security_issue_4
expect
(
issues
).
to
include
@security_issue_4
expect
(
issues
).
not_
to
include
@security_issue_5
expect
(
issues
).
to
include
@security_issue_5
expect
(
results
.
issues_count
).
to
eq
5
expect
(
results
.
issues_count
).
to
eq
6
end
end
end
end
...
@@ -403,8 +403,8 @@ describe Gitlab::Elastic::SearchResults, :elastic do
...
@@ -403,8 +403,8 @@ describe Gitlab::Elastic::SearchResults, :elastic do
expect
(
issues
).
not_to
include
@security_issue_2
expect
(
issues
).
not_to
include
@security_issue_2
expect
(
issues
).
to
include
@security_issue_3
expect
(
issues
).
to
include
@security_issue_3
expect
(
issues
).
to
include
@security_issue_4
expect
(
issues
).
to
include
@security_issue_4
expect
(
issues
).
not_
to
include
@security_issue_5
expect
(
issues
).
to
include
@security_issue_5
expect
(
results
.
issues_count
).
to
eq
3
expect
(
results
.
issues_count
).
to
eq
4
end
end
end
end
end
end
...
@@ -539,6 +539,7 @@ describe Gitlab::Elastic::SearchResults, :elastic do
...
@@ -539,6 +539,7 @@ describe Gitlab::Elastic::SearchResults, :elastic do
it
'finds blobs from public projects only'
do
it
'finds blobs from public projects only'
do
project_2
=
create
:project
,
:repository
,
:private
project_2
=
create
:project
,
:repository
,
:private
project_2
.
repository
.
index_commits_and_blobs
project_2
.
repository
.
index_commits_and_blobs
project_2
.
add_reporter
(
user
)
Gitlab
::
Elastic
::
Helper
.
refresh_index
Gitlab
::
Elastic
::
Helper
.
refresh_index
results
=
described_class
.
new
(
user
,
'def'
,
[
project_1
.
id
])
results
=
described_class
.
new
(
user
,
'def'
,
[
project_1
.
id
])
...
@@ -670,6 +671,7 @@ describe Gitlab::Elastic::SearchResults, :elastic do
...
@@ -670,6 +671,7 @@ describe Gitlab::Elastic::SearchResults, :elastic do
project_2
=
create
:project
,
:repository
,
:private
,
:wiki_repo
project_2
=
create
:project
,
:repository
,
:private
,
:wiki_repo
project_2
.
wiki
.
create_page
(
'index_page'
,
'term'
)
project_2
.
wiki
.
create_page
(
'index_page'
,
'term'
)
project_2
.
wiki
.
index_wiki_blobs
project_2
.
wiki
.
index_wiki_blobs
project_2
.
add_guest
(
user
)
Gitlab
::
Elastic
::
Helper
.
refresh_index
Gitlab
::
Elastic
::
Helper
.
refresh_index
expect
(
results
.
wiki_blobs_count
).
to
eq
1
expect
(
results
.
wiki_blobs_count
).
to
eq
1
...
@@ -706,6 +708,10 @@ describe Gitlab::Elastic::SearchResults, :elastic do
...
@@ -706,6 +708,10 @@ describe Gitlab::Elastic::SearchResults, :elastic do
context
'search by member'
do
context
'search by member'
do
let
(
:limit_project_ids
)
{
[
project_1
.
id
]
}
let
(
:limit_project_ids
)
{
[
project_1
.
id
]
}
before
do
project_1
.
add_guest
(
user
)
end
it
{
is_expected
.
not_to
be_empty
}
it
{
is_expected
.
not_to
be_empty
}
end
end
...
@@ -736,6 +742,7 @@ describe Gitlab::Elastic::SearchResults, :elastic do
...
@@ -736,6 +742,7 @@ describe Gitlab::Elastic::SearchResults, :elastic do
it
'finds commits from public projects only'
do
it
'finds commits from public projects only'
do
project_2
=
create
:project
,
:private
,
:repository
project_2
=
create
:project
,
:private
,
:repository
project_2
.
repository
.
index_commits_and_blobs
project_2
.
repository
.
index_commits_and_blobs
project_2
.
add_reporter
(
user
)
Gitlab
::
Elastic
::
Helper
.
refresh_index
Gitlab
::
Elastic
::
Helper
.
refresh_index
results
=
described_class
.
new
(
user
,
'add'
,
[
project_1
.
id
])
results
=
described_class
.
new
(
user
,
'add'
,
[
project_1
.
id
])
...
...
ee/spec/models/concerns/elastic/issue_spec.rb
View file @
1ea8d32d
...
@@ -7,7 +7,8 @@ describe Issue, :elastic do
...
@@ -7,7 +7,8 @@ describe Issue, :elastic do
stub_ee_application_setting
(
elasticsearch_search:
true
,
elasticsearch_indexing:
true
)
stub_ee_application_setting
(
elasticsearch_search:
true
,
elasticsearch_indexing:
true
)
end
end
let
(
:project
)
{
create
:project
}
let
(
:project
)
{
create
:project
,
:public
}
let
(
:admin
)
{
create
:user
,
:admin
}
context
'when limited indexing is on'
do
context
'when limited indexing is on'
do
set
(
:project
)
{
create
:project
,
name:
'test1'
}
set
(
:project
)
{
create
:project
,
name:
'test1'
}
...
@@ -71,7 +72,7 @@ describe Issue, :elastic do
...
@@ -71,7 +72,7 @@ describe Issue, :elastic do
expect
(
described_class
.
elastic_search
(
'(term1 | term2 | term3) +bla-bla'
,
options:
options
).
total_count
).
to
eq
(
2
)
expect
(
described_class
.
elastic_search
(
'(term1 | term2 | term3) +bla-bla'
,
options:
options
).
total_count
).
to
eq
(
2
)
expect
(
described_class
.
elastic_search
(
Issue
.
last
.
to_reference
,
options:
options
).
total_count
).
to
eq
(
1
)
expect
(
described_class
.
elastic_search
(
Issue
.
last
.
to_reference
,
options:
options
).
total_count
).
to
eq
(
1
)
expect
(
described_class
.
elastic_search
(
'bla-bla'
,
options:
{
project_ids: :any
}).
total_count
).
to
eq
(
3
)
expect
(
described_class
.
elastic_search
(
'bla-bla'
,
options:
{
project_ids: :any
,
public_and_internal_projects:
true
}).
total_count
).
to
eq
(
3
)
end
end
it
"returns json with all needed elements"
do
it
"returns json with all needed elements"
do
...
...
ee/spec/models/concerns/elastic/merge_request_spec.rb
View file @
1ea8d32d
...
@@ -7,6 +7,8 @@ describe MergeRequest, :elastic do
...
@@ -7,6 +7,8 @@ describe MergeRequest, :elastic do
stub_ee_application_setting
(
elasticsearch_search:
true
,
elasticsearch_indexing:
true
)
stub_ee_application_setting
(
elasticsearch_search:
true
,
elasticsearch_indexing:
true
)
end
end
let
(
:admin
)
{
create
(
:user
,
:admin
)
}
it_behaves_like
'limited indexing is enabled'
do
it_behaves_like
'limited indexing is enabled'
do
set
(
:object
)
{
create
:merge_request
,
source_project:
project
}
set
(
:object
)
{
create
:merge_request
,
source_project:
project
}
set
(
:group
)
{
create
(
:group
)
}
set
(
:group
)
{
create
(
:group
)
}
...
@@ -17,7 +19,7 @@ describe MergeRequest, :elastic do
...
@@ -17,7 +19,7 @@ describe MergeRequest, :elastic do
end
end
it
"searches merge requests"
do
it
"searches merge requests"
do
project
=
create
:project
,
:repository
project
=
create
:project
,
:
public
,
:
repository
Sidekiq
::
Testing
.
inline!
do
Sidekiq
::
Testing
.
inline!
do
create
:merge_request
,
title:
'bla-bla term1'
,
source_project:
project
create
:merge_request
,
title:
'bla-bla term1'
,
source_project:
project
...
@@ -35,7 +37,7 @@ describe MergeRequest, :elastic do
...
@@ -35,7 +37,7 @@ describe MergeRequest, :elastic do
expect
(
described_class
.
elastic_search
(
'term1 | term2 | term3'
,
options:
options
).
total_count
).
to
eq
(
2
)
expect
(
described_class
.
elastic_search
(
'term1 | term2 | term3'
,
options:
options
).
total_count
).
to
eq
(
2
)
expect
(
described_class
.
elastic_search
(
MergeRequest
.
last
.
to_reference
,
options:
options
).
total_count
).
to
eq
(
1
)
expect
(
described_class
.
elastic_search
(
MergeRequest
.
last
.
to_reference
,
options:
options
).
total_count
).
to
eq
(
1
)
expect
(
described_class
.
elastic_search
(
'term3'
,
options:
options
).
total_count
).
to
eq
(
0
)
expect
(
described_class
.
elastic_search
(
'term3'
,
options:
options
).
total_count
).
to
eq
(
0
)
expect
(
described_class
.
elastic_search
(
'term3'
,
options:
{
project_ids: :any
}).
total_count
).
to
eq
(
1
)
expect
(
described_class
.
elastic_search
(
'term3'
,
options:
{
project_ids: :any
,
public_and_internal_projects:
true
}).
total_count
).
to
eq
(
1
)
end
end
it
"returns json with all needed elements"
do
it
"returns json with all needed elements"
do
...
...
ee/spec/services/search/global_service_spec.rb
View file @
1ea8d32d
...
@@ -3,10 +3,99 @@
...
@@ -3,10 +3,99 @@
require
'spec_helper'
require
'spec_helper'
describe
Search
::
GlobalService
do
describe
Search
::
GlobalService
do
include
SearchResultHelpers
include
ProjectHelpers
using
RSpec
::
Parameterized
::
TableSyntax
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
before
do
stub_ee_application_setting
(
elasticsearch_search:
true
,
elasticsearch_indexing:
true
)
end
it_behaves_like
'EE search service shared examples'
,
::
Gitlab
::
SearchResults
,
::
Gitlab
::
Elastic
::
SearchResults
do
it_behaves_like
'EE search service shared examples'
,
::
Gitlab
::
SearchResults
,
::
Gitlab
::
Elastic
::
SearchResults
do
let
(
:scope
)
{
nil
}
let
(
:scope
)
{
nil
}
let
(
:service
)
{
described_class
.
new
(
user
,
search:
'*'
)
}
let
(
:service
)
{
described_class
.
new
(
user
,
search:
'*'
)
}
end
end
context
'visibility'
,
:elastic
do
include_context
'ProjectPolicyTable context'
set
(
:group
)
{
create
(
:group
)
}
let
(
:project
)
{
create
(
:project
,
project_level
,
namespace:
group
)
}
let
(
:project2
)
{
create
(
:project
,
project_level
)
}
let
(
:user
)
{
create_user_from_membership
(
project
,
membership
)
}
context
'merge request'
do
let!
(
:merge_request
)
{
create
:merge_request
,
target_project:
project
,
source_project:
project
}
where
(
:project_level
,
:feature_access_level
,
:membership
,
:expected_count
)
do
permission_table_for_reporter_feature_access
end
with_them
do
it
"respects visibility"
do
[
project
,
project2
].
each
do
|
project
|
update_feature_access_level
(
project
,
feature_access_level
)
end
Gitlab
::
Elastic
::
Helper
.
refresh_index
expect_search_results
(
user
,
'merge_requests'
,
expected_count:
expected_count
)
do
|
user
|
described_class
.
new
(
user
,
search:
merge_request
.
title
).
execute
end
end
end
end
context
'code'
do
let!
(
:project
)
{
create
(
:project
,
project_level
,
:repository
,
namespace:
group
)
}
let!
(
:project2
)
{
create
(
:project
,
project_level
,
:repository
)
}
where
(
:project_level
,
:feature_access_level
,
:membership
,
:expected_count
)
do
permission_table_for_guest_feature_access
end
with_them
do
it
"respects visibility"
do
[
project
,
project2
].
each
do
|
project
|
update_feature_access_level
(
project
,
feature_access_level
)
ElasticCommitIndexerWorker
.
new
.
perform
(
project
.
id
)
end
Gitlab
::
Elastic
::
Helper
.
refresh_index
expect_search_results
(
user
,
'commits'
,
expected_count:
expected_count
)
do
|
user
|
described_class
.
new
(
user
,
search:
'initial'
).
execute
end
expect_search_results
(
user
,
'blobs'
,
expected_count:
expected_count
)
do
|
user
|
described_class
.
new
(
user
,
search:
'.gitmodules'
).
execute
end
end
end
end
context
'project'
do
where
(
:project_level
,
:membership
,
:expected_count
)
do
permission_table_for_project_access
end
with_them
do
it
"respects visibility"
do
ElasticCommitIndexerWorker
.
new
.
perform
(
project
.
id
)
Gitlab
::
Elastic
::
Helper
.
refresh_index
expected_objects
=
expected_count
==
1
?
[
project
]
:
[]
expect_search_results
(
user
,
'projects'
,
expected_count:
expected_count
,
expected_objects:
expected_objects
)
do
|
user
|
described_class
.
new
(
user
,
search:
project
.
name
).
execute
end
end
end
end
end
end
end
ee/spec/services/search/group_service_spec.rb
View file @
1ea8d32d
...
@@ -3,7 +3,16 @@
...
@@ -3,7 +3,16 @@
require
'spec_helper'
require
'spec_helper'
describe
Search
::
GroupService
,
:elastic
do
describe
Search
::
GroupService
,
:elastic
do
include
SearchResultHelpers
include
ProjectHelpers
using
RSpec
::
Parameterized
::
TableSyntax
let
(
:user
)
{
create
(
:user
)
}
let
(
:user
)
{
create
(
:user
)
}
let
(
:group
)
{
create
(
:group
)
}
before
do
stub_ee_application_setting
(
elasticsearch_search:
true
,
elasticsearch_indexing:
true
)
end
it_behaves_like
'EE search service shared examples'
,
::
Gitlab
::
GroupSearchResults
,
::
Gitlab
::
Elastic
::
GroupSearchResults
do
it_behaves_like
'EE search service shared examples'
,
::
Gitlab
::
GroupSearchResults
,
::
Gitlab
::
Elastic
::
GroupSearchResults
do
let
(
:scope
)
{
create
(
:group
)
}
let
(
:scope
)
{
create
(
:group
)
}
...
@@ -57,4 +66,88 @@ describe Search::GroupService, :elastic do
...
@@ -57,4 +66,88 @@ describe Search::GroupService, :elastic do
end
end
end
end
end
end
context
'visibility'
do
include_context
'ProjectPolicyTable context'
set
(
:group
)
{
create
(
:group
)
}
let!
(
:project
)
{
create
(
:project
,
project_level
,
namespace:
group
)
}
let!
(
:project2
)
{
create
(
:project
,
project_level
)
}
let
(
:user
)
{
create_user_from_membership
(
project
,
membership
)
}
context
'merge request'
do
let!
(
:merge_request
)
{
create
:merge_request
,
target_project:
project
,
source_project:
project
}
let!
(
:merge_request2
)
{
create
:merge_request
,
target_project:
project2
,
source_project:
project2
,
title:
merge_request
.
title
}
where
(
:project_level
,
:feature_access_level
,
:membership
,
:expected_count
)
do
permission_table_for_reporter_feature_access
end
with_them
do
it
"respects visibility"
do
[
project
,
project2
].
each
do
|
project
|
update_feature_access_level
(
project
,
feature_access_level
)
end
Gitlab
::
Elastic
::
Helper
.
refresh_index
expect_search_results
(
user
,
'merge_requests'
,
expected_count:
expected_count
)
do
|
user
|
described_class
.
new
(
user
,
group
,
search:
merge_request
.
title
).
execute
end
end
end
end
context
'code'
do
let!
(
:project
)
{
create
(
:project
,
project_level
,
:repository
,
namespace:
group
)
}
where
(
:project_level
,
:feature_access_level
,
:membership
,
:expected_count
)
do
permission_table_for_guest_feature_access
end
with_them
do
it
"respects visibility"
do
[
project
,
project2
].
each
do
|
project
|
update_feature_access_level
(
project
,
feature_access_level
)
ElasticCommitIndexerWorker
.
new
.
perform
(
project
.
id
)
end
ElasticCommitIndexerWorker
.
new
.
perform
(
project
.
id
)
Gitlab
::
Elastic
::
Helper
.
refresh_index
expect_search_results
(
user
,
'commits'
,
expected_count:
expected_count
)
do
|
user
|
described_class
.
new
(
user
,
group
,
search:
'initial'
).
execute
end
expect_search_results
(
user
,
'blobs'
,
expected_count:
expected_count
)
do
|
user
|
described_class
.
new
(
user
,
group
,
search:
'.gitmodules'
).
execute
end
end
end
end
context
'project search'
do
let
(
:project
)
{
create
(
:project
,
project_level
,
namespace:
group
)
}
where
(
:project_level
,
:membership
,
:expected_count
)
do
permission_table_for_project_access
end
with_them
do
it
"respects visibility"
do
ElasticCommitIndexerWorker
.
new
.
perform
(
project
.
id
)
Gitlab
::
Elastic
::
Helper
.
refresh_index
expected_objects
=
expected_count
==
1
?
[
project
]
:
[]
expect_search_results
(
user
,
'projects'
,
expected_count:
expected_count
,
expected_objects:
expected_objects
)
do
|
user
|
described_class
.
new
(
user
,
group
,
search:
project
.
name
).
execute
end
end
end
end
end
end
end
ee/spec/services/search/project_service_spec.rb
View file @
1ea8d32d
...
@@ -3,9 +3,75 @@
...
@@ -3,9 +3,75 @@
require
'spec_helper'
require
'spec_helper'
describe
Search
::
ProjectService
do
describe
Search
::
ProjectService
do
include
SearchResultHelpers
include
ProjectHelpers
using
RSpec
::
Parameterized
::
TableSyntax
before
do
stub_ee_application_setting
(
elasticsearch_search:
true
,
elasticsearch_indexing:
true
)
end
it_behaves_like
'EE search service shared examples'
,
::
Gitlab
::
ProjectSearchResults
,
::
Gitlab
::
Elastic
::
ProjectSearchResults
do
it_behaves_like
'EE search service shared examples'
,
::
Gitlab
::
ProjectSearchResults
,
::
Gitlab
::
Elastic
::
ProjectSearchResults
do
let
(
:user
)
{
scope
.
owner
}
let
(
:user
)
{
scope
.
owner
}
let
(
:scope
)
{
create
(
:project
)
}
let
(
:scope
)
{
create
(
:project
)
}
let
(
:service
)
{
described_class
.
new
(
scope
,
user
,
search:
'*'
)
}
let
(
:service
)
{
described_class
.
new
(
scope
,
user
,
search:
'*'
)
}
end
end
context
'visibility'
,
:elastic
do
include_context
'ProjectPolicyTable context'
set
(
:group
)
{
create
(
:group
)
}
let!
(
:project
)
{
create
(
:project
,
project_level
,
namespace:
group
)
}
let!
(
:project2
)
{
create
(
:project
,
project_level
)
}
let
(
:user
)
{
create_user_from_membership
(
project
,
membership
)
}
context
'merge request'
do
let!
(
:merge_request
)
{
create
:merge_request
,
target_project:
project
,
source_project:
project
}
let!
(
:merge_request2
)
{
create
:merge_request
,
target_project:
project2
,
source_project:
project2
,
title:
merge_request
.
title
}
where
(
:project_level
,
:feature_access_level
,
:membership
,
:expected_count
)
do
permission_table_for_reporter_feature_access
end
with_them
do
it
"respects visibility"
do
[
project
,
project2
].
each
do
|
project
|
update_feature_access_level
(
project
,
feature_access_level
)
end
Gitlab
::
Elastic
::
Helper
.
refresh_index
expect_search_results
(
user
,
'merge_requests'
,
expected_count:
expected_count
)
do
|
user
|
described_class
.
new
(
project
,
user
,
search:
merge_request
.
title
).
execute
end
end
end
end
context
'code'
do
let!
(
:project
)
{
create
(
:project
,
project_level
,
:repository
,
namespace:
group
)
}
let!
(
:project2
)
{
create
(
:project
,
project_level
,
:repository
)
}
where
(
:project_level
,
:feature_access_level
,
:membership
,
:expected_count
)
do
permission_table_for_guest_feature_access
end
with_them
do
it
"respects visibility"
do
[
project
,
project2
].
each
do
|
project
|
update_feature_access_level
(
project
,
feature_access_level
)
ElasticCommitIndexerWorker
.
new
.
perform
(
project
.
id
)
end
Gitlab
::
Elastic
::
Helper
.
refresh_index
expect_search_results
(
user
,
'commits'
,
expected_count:
expected_count
)
do
|
user
|
described_class
.
new
(
project
,
user
,
search:
'initial'
).
execute
end
expect_search_results
(
user
,
'blobs'
,
expected_count:
expected_count
)
do
|
user
|
described_class
.
new
(
project
,
user
,
search:
'.gitmodules'
).
execute
end
end
end
end
end
end
end
ee/spec/support/helpers/search_results_helpers.rb
0 → 100644
View file @
1ea8d32d
# frozen_string_literal: true
module
SearchResultHelpers
# @param target [Symbol] search target, e.g. "merge_requests", "blobs"
def
expect_search_results
(
users
,
target
,
expected_count:
nil
,
expected_objects:
nil
)
# TODO: https://gitlab.com/gitlab-org/gitlab/issues/32645
return
if
expected_count
&&
expected_count
>
0
users
=
Array
(
users
)
target
=
target
.
to_s
users
.
each
do
|
user
|
user_name
=
user
&
.
name
||
'anonymous user'
results
=
yield
(
user
)
objects
=
results
.
objects
(
target
)
if
expected_count
actual_count
=
results
.
public_send
(
"
#{
target
}
_count"
)
expect
(
actual_count
).
to
eq
(
expected_count
),
"expected count to be
#{
expected_count
}
for
#{
user_name
}
, got
#{
actual_count
}
"
end
if
expected_objects
if
expected_objects
.
empty?
expect
(
objects
.
empty?
).
to
eq
(
true
)
else
expect
(
objects
).
to
contain_exactly
(
*
expected_objects
)
end
end
end
end
end
spec/models/project_feature_spec.rb
View file @
1ea8d32d
...
@@ -228,4 +228,28 @@ describe ProjectFeature do
...
@@ -228,4 +228,28 @@ describe ProjectFeature do
end
end
end
end
end
end
describe
'.required_minimum_access_level'
do
it
'handles reporter level'
do
expect
(
described_class
.
required_minimum_access_level
(
:merge_requests
)).
to
eq
(
Gitlab
::
Access
::
REPORTER
)
end
it
'handles guest level'
do
expect
(
described_class
.
required_minimum_access_level
(
:issues
)).
to
eq
(
Gitlab
::
Access
::
GUEST
)
end
it
'accepts ActiveModel'
do
expect
(
described_class
.
required_minimum_access_level
(
MergeRequest
)).
to
eq
(
Gitlab
::
Access
::
REPORTER
)
end
it
'accepts string'
do
expect
(
described_class
.
required_minimum_access_level
(
'merge_requests'
)).
to
eq
(
Gitlab
::
Access
::
REPORTER
)
end
it
'raises error if feature is invalid'
do
expect
do
described_class
.
required_minimum_access_level
(
:foos
)
end
.
to
raise_error
end
end
end
end
spec/models/project_spec.rb
View file @
1ea8d32d
...
@@ -3469,6 +3469,36 @@ describe Project do
...
@@ -3469,6 +3469,36 @@ describe Project do
end
end
end
end
describe
'.filter_by_feature_visibility'
do
include_context
'ProjectPolicyTable context'
include
ProjectHelpers
using
RSpec
::
Parameterized
::
TableSyntax
set
(
:group
)
{
create
(
:group
)
}
let!
(
:project
)
{
create
(
:project
,
project_level
,
namespace:
group
)
}
let
(
:user
)
{
create_user_from_membership
(
project
,
membership
)
}
context
'reporter level access'
do
let
(
:feature
)
{
MergeRequest
}
where
(
:project_level
,
:feature_access_level
,
:membership
,
:expected_count
)
do
permission_table_for_reporter_feature_access
end
with_them
do
it
"respects visibility"
do
update_feature_access_level
(
project
,
feature_access_level
)
expected_objects
=
expected_count
==
1
?
[
project
]
:
[]
expect
(
described_class
.
filter_by_feature_visibility
(
feature
,
user
)
).
to
eq
(
expected_objects
)
end
end
end
end
describe
'#pages_available?'
do
describe
'#pages_available?'
do
let
(
:project
)
{
create
(
:project
,
group:
group
)
}
let
(
:project
)
{
create
(
:project
,
group:
group
)
}
...
...
spec/support/helpers/project_helpers.rb
0 → 100644
View file @
1ea8d32d
# frozen_string_literal: true
module
ProjectHelpers
# @params target [Project] membership target
# @params membership [Symbol] accepts the membership levels :guest, :reporter...
# and phony levels :non_member and :anonymous
def
create_user_from_membership
(
target
,
membership
)
case
membership
when
:anonymous
nil
when
:non_member
create
(
:user
,
name:
membership
)
else
create
(
:user
,
name:
membership
).
tap
{
|
u
|
target
.
add_user
(
u
,
membership
)
}
end
end
def
update_feature_access_level
(
project
,
access_level
)
project
.
update!
(
repository_access_level:
access_level
,
merge_requests_access_level:
access_level
,
builds_access_level:
access_level
)
end
end
spec/support/shared_contexts/policies/project_policy_table_shared_context.rb
0 → 100644
View file @
1ea8d32d
# frozen_string_literal: true
RSpec
.
shared_context
'ProjectPolicyTable context'
do
using
RSpec
::
Parameterized
::
TableSyntax
# rubocop:disable Metrics/AbcSize
def
permission_table_for_reporter_feature_access
:public
|
:enabled
|
:reporter
|
1
:public
|
:enabled
|
:guest
|
1
:public
|
:enabled
|
:non_member
|
1
:public
|
:enabled
|
:anonymous
|
1
:public
|
:private
|
:reporter
|
1
:public
|
:private
|
:guest
|
0
:public
|
:private
|
:non_member
|
0
:public
|
:private
|
:anonymous
|
0
:public
|
:disabled
|
:reporter
|
0
:public
|
:disabled
|
:guest
|
0
:public
|
:disabled
|
:non_member
|
0
:public
|
:disabled
|
:anonymous
|
0
:internal
|
:enabled
|
:reporter
|
1
:internal
|
:enabled
|
:guest
|
1
:internal
|
:enabled
|
:non_member
|
1
:internal
|
:enabled
|
:anonymous
|
0
:internal
|
:private
|
:reporter
|
1
:internal
|
:private
|
:guest
|
0
:internal
|
:private
|
:non_member
|
0
:internal
|
:private
|
:anonymous
|
0
:internal
|
:disabled
|
:reporter
|
0
:internal
|
:disabled
|
:guest
|
0
:internal
|
:disabled
|
:non_member
|
0
:internal
|
:disabled
|
:anonymous
|
0
:private
|
:enabled
|
:reporter
|
1
:private
|
:enabled
|
:guest
|
1
:private
|
:enabled
|
:non_member
|
0
:private
|
:enabled
|
:anonymous
|
0
:private
|
:private
|
:reporter
|
1
:private
|
:private
|
:guest
|
0
:private
|
:private
|
:non_member
|
0
:private
|
:private
|
:anonymous
|
0
:private
|
:disabled
|
:reporter
|
0
:private
|
:disabled
|
:guest
|
0
:private
|
:disabled
|
:non_member
|
0
:private
|
:disabled
|
:anonymous
|
0
end
def
permission_table_for_guest_feature_access
:public
|
:enabled
|
:reporter
|
1
:public
|
:enabled
|
:guest
|
1
:public
|
:enabled
|
:non_member
|
1
:public
|
:enabled
|
:anonymous
|
1
:public
|
:private
|
:reporter
|
1
:public
|
:private
|
:guest
|
1
:public
|
:private
|
:non_member
|
0
:public
|
:private
|
:anonymous
|
0
:public
|
:disabled
|
:reporter
|
0
:public
|
:disabled
|
:guest
|
0
:public
|
:disabled
|
:non_member
|
0
:public
|
:disabled
|
:anonymous
|
0
:internal
|
:enabled
|
:reporter
|
1
:internal
|
:enabled
|
:guest
|
1
:internal
|
:enabled
|
:non_member
|
1
:internal
|
:enabled
|
:anonymous
|
0
:internal
|
:private
|
:reporter
|
1
:internal
|
:private
|
:guest
|
1
:internal
|
:private
|
:non_member
|
0
:internal
|
:private
|
:anonymous
|
0
:internal
|
:disabled
|
:reporter
|
0
:internal
|
:disabled
|
:guest
|
0
:internal
|
:disabled
|
:non_member
|
0
:internal
|
:disabled
|
:anonymous
|
0
:private
|
:enabled
|
:reporter
|
1
:private
|
:enabled
|
:guest
|
1
:private
|
:enabled
|
:non_member
|
0
:private
|
:enabled
|
:anonymous
|
0
:private
|
:private
|
:reporter
|
1
:private
|
:private
|
:guest
|
1
:private
|
:private
|
:non_member
|
0
:private
|
:private
|
:anonymous
|
0
:private
|
:disabled
|
:reporter
|
0
:private
|
:disabled
|
:guest
|
0
:private
|
:disabled
|
:non_member
|
0
:private
|
:disabled
|
:anonymous
|
0
end
def
permission_table_for_project_access
:public
|
:reporter
|
1
:public
|
:guest
|
1
:public
|
:non_member
|
1
:public
|
:anonymous
|
1
:internal
|
:reporter
|
1
:internal
|
:guest
|
1
:internal
|
:non_member
|
1
:internal
|
:anonymous
|
0
:private
|
:reporter
|
1
:private
|
:guest
|
1
:private
|
:non_member
|
0
:private
|
:anonymous
|
0
end
# rubocop:enable Metrics/AbcSize
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