Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-11-19 11:27:35 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-11-19 11:27:35 +0300
commit7e9c479f7de77702622631cff2628a9c8dcbc627 (patch)
treec8f718a08e110ad7e1894510980d2155a6549197 /app/finders
parente852b0ae16db4052c1c567d9efa4facc81146e88 (diff)
Add latest changes from gitlab-org/gitlab@13-6-stable-eev13.6.0-rc42
Diffstat (limited to 'app/finders')
-rw-r--r--app/finders/alert_management/http_integrations_finder.rb54
-rw-r--r--app/finders/ci/commit_statuses_finder.rb40
-rw-r--r--app/finders/ci/jobs_finder.rb16
-rw-r--r--app/finders/concerns/finder_with_cross_project_access.rb2
-rw-r--r--app/finders/environment_names_finder.rb18
-rw-r--r--app/finders/feature_flags_user_lists_finder.rb34
-rw-r--r--app/finders/group_projects_finder.rb1
-rw-r--r--app/finders/issuable_finder.rb13
-rw-r--r--app/finders/issues_finder.rb2
-rw-r--r--app/finders/merge_requests_finder.rb30
-rw-r--r--app/finders/packages/group_packages_finder.rb9
-rw-r--r--app/finders/packages/npm/package_finder.rb2
-rw-r--r--app/finders/personal_access_tokens_finder.rb7
-rw-r--r--app/finders/security/jobs_finder.rb71
-rw-r--r--app/finders/security/license_compliance_jobs_finder.rb18
-rw-r--r--app/finders/security/security_jobs_finder.rb19
-rw-r--r--app/finders/user_groups_counter.rb30
17 files changed, 324 insertions, 42 deletions
diff --git a/app/finders/alert_management/http_integrations_finder.rb b/app/finders/alert_management/http_integrations_finder.rb
new file mode 100644
index 00000000000..9f511be0ace
--- /dev/null
+++ b/app/finders/alert_management/http_integrations_finder.rb
@@ -0,0 +1,54 @@
+# frozen_string_literal: true
+
+module AlertManagement
+ class HttpIntegrationsFinder
+ def initialize(project, params)
+ @project = project
+ @params = params
+ end
+
+ def execute
+ @collection = project.alert_management_http_integrations
+
+ filter_by_availability
+ filter_by_endpoint_identifier
+ filter_by_active
+
+ collection
+ end
+
+ private
+
+ attr_reader :project, :params, :collection
+
+ def filter_by_availability
+ return if multiple_alert_http_integrations?
+
+ first_id = project.alert_management_http_integrations
+ .ordered_by_id
+ .select(:id)
+ .at_most(1)
+
+ @collection = collection.id_in(first_id)
+ end
+
+ def filter_by_endpoint_identifier
+ return unless params[:endpoint_identifier]
+
+ @collection = collection.for_endpoint_identifier(params[:endpoint_identifier])
+ end
+
+ def filter_by_active
+ return unless params[:active]
+
+ @collection = collection.active
+ end
+
+ # Overridden in EE
+ def multiple_alert_http_integrations?
+ false
+ end
+ end
+end
+
+::AlertManagement::HttpIntegrationsFinder.prepend_if_ee('EE::AlertManagement::HttpIntegrationsFinder')
diff --git a/app/finders/ci/commit_statuses_finder.rb b/app/finders/ci/commit_statuses_finder.rb
new file mode 100644
index 00000000000..3c465eb88f3
--- /dev/null
+++ b/app/finders/ci/commit_statuses_finder.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Ci
+ class CommitStatusesFinder
+ include ::Gitlab::Utils::StrongMemoize
+
+ def initialize(project, repository, current_user, refs)
+ @project = project
+ @repository = repository
+ @current_user = current_user
+ @refs = refs
+ end
+
+ def execute
+ return [] unless Ability.allowed?(@current_user, :read_pipeline, @project)
+
+ commit_statuses
+ end
+
+ private
+
+ def latest_commits
+ strong_memoize(:latest_commits) do
+ refs.map do |ref|
+ [ref.name, @repository.commit(ref.dereferenced_target).sha]
+ end.to_h
+ end
+ end
+
+ def commit_statuses
+ latest_pipelines = project.ci_pipelines.latest_pipeline_per_commit(latest_commits.values)
+
+ latest_commits.transform_values do |commit_sha|
+ latest_pipelines[commit_sha]&.detailed_status(current_user)
+ end.compact
+ end
+
+ attr_reader :project, :repository, :current_user, :refs
+ end
+end
diff --git a/app/finders/ci/jobs_finder.rb b/app/finders/ci/jobs_finder.rb
index 40c610f8209..78791d737da 100644
--- a/app/finders/ci/jobs_finder.rb
+++ b/app/finders/ci/jobs_finder.rb
@@ -25,11 +25,7 @@ module Ci
attr_reader :current_user, :pipeline, :project, :params, :type
def init_collection
- if Feature.enabled?(:ci_jobs_finder_refactor, default_enabled: true)
- pipeline_jobs || project_jobs || all_jobs
- else
- project ? project_builds : all_jobs
- end
+ pipeline_jobs || project_jobs || all_jobs
end
def all_jobs
@@ -38,12 +34,6 @@ module Ci
type.all
end
- def project_builds
- raise Gitlab::Access::AccessDeniedError unless can?(current_user, :read_build, project)
-
- project.builds.relevant
- end
-
def project_jobs
return unless project
raise Gitlab::Access::AccessDeniedError unless can?(current_user, :read_build, project)
@@ -59,9 +49,7 @@ module Ci
end
def filter_by_scope(builds)
- if Feature.enabled?(:ci_jobs_finder_refactor, default_enabled: true)
- return filter_by_statuses!(params[:scope], builds) if params[:scope].is_a?(Array)
- end
+ return filter_by_statuses!(params[:scope], builds) if params[:scope].is_a?(Array)
case params[:scope]
when 'pending'
diff --git a/app/finders/concerns/finder_with_cross_project_access.rb b/app/finders/concerns/finder_with_cross_project_access.rb
index a55fb58a1bc..e63b868e470 100644
--- a/app/finders/concerns/finder_with_cross_project_access.rb
+++ b/app/finders/concerns/finder_with_cross_project_access.rb
@@ -32,7 +32,7 @@ module FinderWithCrossProjectAccess
end
override :execute
- def execute(*args)
+ def execute(*args, **kwargs)
check = Gitlab::CrossProjectAccess.find_check(self)
original = -> { super }
diff --git a/app/finders/environment_names_finder.rb b/app/finders/environment_names_finder.rb
index a92998921c7..e9063ef4c90 100644
--- a/app/finders/environment_names_finder.rb
+++ b/app/finders/environment_names_finder.rb
@@ -13,7 +13,7 @@
class EnvironmentNamesFinder
attr_reader :project_or_group, :current_user
- def initialize(project_or_group, current_user)
+ def initialize(project_or_group, current_user = nil)
@project_or_group = project_or_group
@current_user = current_user
end
@@ -31,14 +31,24 @@ class EnvironmentNamesFinder
end
def namespace_environments
- projects =
- project_or_group.all_projects.public_or_visible_to_user(current_user)
+ # We assume reporter access is needed for the :read_environment permission
+ # here. This expection is also present in
+ # IssuableFinder::Params#min_access_level, which is used for filtering out
+ # merge requests that don't have the right permissions.
+ #
+ # We use this approach so we don't need to load every project into memory
+ # just to verify if we can see their environments. Doing so would not be
+ # efficient, and possibly mess up pagination if certain projects are not
+ # meant to be visible.
+ projects = project_or_group
+ .all_projects
+ .public_or_visible_to_user(current_user, Gitlab::Access::REPORTER)
Environment.for_project(projects)
end
def project_environments
- if current_user.can?(:read_environment, project_or_group)
+ if Ability.allowed?(current_user, :read_environment, project_or_group)
project_or_group.environments
else
Environment.none
diff --git a/app/finders/feature_flags_user_lists_finder.rb b/app/finders/feature_flags_user_lists_finder.rb
new file mode 100644
index 00000000000..ebe60acd711
--- /dev/null
+++ b/app/finders/feature_flags_user_lists_finder.rb
@@ -0,0 +1,34 @@
+# frozen_string_literal: true
+
+class FeatureFlagsUserListsFinder
+ attr_reader :project, :current_user, :params
+
+ def initialize(project, current_user, params = {})
+ @project = project
+ @current_user = current_user
+ @params = params
+ end
+
+ def execute
+ unless Ability.allowed?(current_user, :read_feature_flag, project)
+ return Operations::FeatureFlagsUserList.none
+ end
+
+ items = feature_flags_user_lists
+ by_search(items)
+ end
+
+ private
+
+ def feature_flags_user_lists
+ project.operations_feature_flags_user_lists
+ end
+
+ def by_search(items)
+ if params[:search].present?
+ items.for_name_like(params[:search])
+ else
+ items
+ end
+ end
+end
diff --git a/app/finders/group_projects_finder.rb b/app/finders/group_projects_finder.rb
index 5f24b15156c..8362e782ad1 100644
--- a/app/finders/group_projects_finder.rb
+++ b/app/finders/group_projects_finder.rb
@@ -12,6 +12,7 @@
# only_owned: boolean
# only_shared: boolean
# limit: integer
+# include_subgroups: boolean
# params:
# sort: string
# visibility_level: int
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 9c4aecedd93..d431c3e3699 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -153,10 +153,8 @@ class IssuableFinder
end
def row_count
- fast_fail = Feature.enabled?(:soft_fail_count_by_state, params.group || params.project)
-
Gitlab::IssuablesCountForState
- .new(self, nil, fast_fail: fast_fail)
+ .new(self, nil, fast_fail: true)
.for_state_or_opened(params[:state])
end
@@ -341,6 +339,15 @@ class IssuableFinder
cte << items
items = klass.with(cte.to_arel).from(klass.table_name)
+ elsif Feature.enabled?(:pg_hint_plan_for_issuables, params.project)
+ items = items.optimizer_hints(<<~HINTS)
+ BitmapScan(
+ issues idx_issues_on_project_id_and_created_at_and_id_and_state_id
+ idx_issues_on_project_id_and_due_date_and_id_and_state_id
+ idx_issues_on_project_id_and_updated_at_and_id_and_state_id
+ index_issues_on_project_id_and_iid
+ )
+ HINTS
end
items.full_search(search, matched_columns: params[:in], use_minimum_char_limit: !use_cte_for_search?)
diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb
index 32be5bee0db..5c9010ee3e0 100644
--- a/app/finders/issues_finder.rb
+++ b/app/finders/issues_finder.rb
@@ -97,6 +97,8 @@ class IssuesFinder < IssuableFinder
items.due_between(Date.today.beginning_of_month, Date.today.end_of_month)
elsif params.filter_by_due_next_month_and_previous_two_weeks?
items.due_between(Date.today - 2.weeks, (Date.today + 1.month).end_of_month)
+ else
+ items.none
end
end
diff --git a/app/finders/merge_requests_finder.rb b/app/finders/merge_requests_finder.rb
index c998de75ab2..1f847b09752 100644
--- a/app/finders/merge_requests_finder.rb
+++ b/app/finders/merge_requests_finder.rb
@@ -66,6 +66,11 @@ class MergeRequestsFinder < IssuableFinder
by_source_project_id(items)
end
+ def filter_negated_items(items)
+ items = super(items)
+ by_negated_target_branch(items)
+ end
+
private
def by_commit(items)
@@ -98,6 +103,14 @@ class MergeRequestsFinder < IssuableFinder
end
# rubocop: enable CodeReuse/ActiveRecord
+ # rubocop: disable CodeReuse/ActiveRecord
+ def by_negated_target_branch(items)
+ return items unless not_params[:target_branch]
+
+ items.where.not(target_branch: not_params[:target_branch])
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
def source_project_id
@source_project_id ||= params[:source_project_id].presence
end
@@ -142,19 +155,6 @@ class MergeRequestsFinder < IssuableFinder
.or(table[:title].matches('(Draft)%'))
end
- # rubocop: disable CodeReuse/ActiveRecord
- def by_deployment(items)
- return items unless deployment_id
-
- items.includes(:deployment_merge_requests)
- .where(deployment_merge_requests: { deployment_id: deployment_id })
- end
- # rubocop: enable CodeReuse/ActiveRecord
-
- def deployment_id
- @deployment_id ||= params[:deployment_id].presence
- end
-
# Filter by merge requests that had been approved by specific users
# rubocop: disable CodeReuse/Finder
def by_approvals(items)
@@ -165,10 +165,6 @@ class MergeRequestsFinder < IssuableFinder
# rubocop: enable CodeReuse/Finder
def by_deployments(items)
- # Until this feature flag is enabled permanently, we retain the old
- # filtering behaviour/code.
- return by_deployment(items) unless Feature.enabled?(:deployment_filters)
-
env = params[:environment]
before = params[:deployed_before]
after = params[:deployed_after]
diff --git a/app/finders/packages/group_packages_finder.rb b/app/finders/packages/group_packages_finder.rb
index 8b948bb056d..a51057571f1 100644
--- a/app/finders/packages/group_packages_finder.rb
+++ b/app/finders/packages/group_packages_finder.rb
@@ -25,7 +25,7 @@ module Packages
.including_build_info
.including_project_route
.including_tags
- .for_projects(group_projects_visible_to_current_user)
+ .for_projects(group_projects_visible_to_current_user.select(:id))
.processed
.has_version
.sort_by_attribute("#{params[:order_by]}_#{params[:sort]}")
@@ -36,11 +36,14 @@ module Packages
end
def group_projects_visible_to_current_user
+ # according to project_policy.rb
+ # access to packages is ruled by:
+ # - project is public or the current user has access to it with at least the reporter level
+ # - the repository feature is available to the current_user
::Project
.in_namespace(groups)
.public_or_visible_to_user(current_user, Gitlab::Access::REPORTER)
- .with_project_feature
- .select { |project| Ability.allowed?(current_user, :read_package, project) }
+ .with_feature_available_for_user(:repository, current_user)
end
def package_type
diff --git a/app/finders/packages/npm/package_finder.rb b/app/finders/packages/npm/package_finder.rb
index 8599fd07e7f..2854226e178 100644
--- a/app/finders/packages/npm/package_finder.rb
+++ b/app/finders/packages/npm/package_finder.rb
@@ -12,6 +12,8 @@ module Packages
end
def execute
+ return Packages::Package.none unless project
+
packages
end
diff --git a/app/finders/personal_access_tokens_finder.rb b/app/finders/personal_access_tokens_finder.rb
index 93f8c520b63..4a6eed8f5ee 100644
--- a/app/finders/personal_access_tokens_finder.rb
+++ b/app/finders/personal_access_tokens_finder.rb
@@ -14,6 +14,7 @@ class PersonalAccessTokensFinder
tokens = PersonalAccessToken.all
tokens = by_current_user(tokens)
tokens = by_user(tokens)
+ tokens = by_users(tokens)
tokens = by_impersonation(tokens)
tokens = by_state(tokens)
@@ -37,6 +38,12 @@ class PersonalAccessTokensFinder
tokens.for_user(@params[:user])
end
+ def by_users(tokens)
+ return tokens unless @params[:users]
+
+ tokens.for_users(@params[:users])
+ end
+
def sort(tokens)
available_sort_orders = PersonalAccessToken.simple_sorts.keys
diff --git a/app/finders/security/jobs_finder.rb b/app/finders/security/jobs_finder.rb
new file mode 100644
index 00000000000..e2efb2e18c9
--- /dev/null
+++ b/app/finders/security/jobs_finder.rb
@@ -0,0 +1,71 @@
+# frozen_string_literal: true
+
+# Security::JobsFinder
+#
+# Abstract class encapsulating common logic for finding jobs (builds) that are related to the Secure products
+# SAST, DAST, Dependency Scanning, Container Scanning and License Management, Coverage Fuzzing
+#
+# Arguments:
+# params:
+# pipeline: required, only jobs for the specified pipeline will be found
+# job_types: required, array of job types that should be returned, defaults to all job types
+
+module Security
+ class JobsFinder
+ attr_reader :pipeline
+
+ def self.allowed_job_types
+ # Example return: [:sast, :dast, :dependency_scanning, :container_scanning, :license_management, :coverage_fuzzing]
+ raise NotImplementedError, 'allowed_job_types must be overwritten to return an array of job types'
+ end
+
+ def initialize(pipeline:, job_types: [])
+ if self.class == Security::JobsFinder
+ raise NotImplementedError, 'This is an abstract class, please instantiate its descendants'
+ end
+
+ if job_types.empty?
+ @job_types = self.class.allowed_job_types
+ elsif valid_job_types?(job_types)
+ @job_types = job_types
+ else
+ raise ArgumentError, "job_types must be from the following: #{self.class.allowed_job_types}"
+ end
+
+ @pipeline = pipeline
+ end
+
+ def execute
+ return [] if @job_types.empty?
+
+ if Feature.enabled?(:ci_build_metadata_config)
+ find_jobs
+ else
+ find_jobs_legacy
+ end
+ end
+
+ private
+
+ def find_jobs
+ @pipeline.builds.with_secure_reports_from_config_options(@job_types)
+ end
+
+ def find_jobs_legacy
+ # the query doesn't guarantee accuracy, so we verify it here
+ legacy_jobs_query.select do |job|
+ @job_types.find { |job_type| job.options.dig(:artifacts, :reports, job_type) }
+ end
+ end
+
+ def legacy_jobs_query
+ @job_types.map do |job_type|
+ @pipeline.builds.with_secure_reports_from_options(job_type)
+ end.reduce(&:or)
+ end
+
+ def valid_job_types?(job_types)
+ (job_types - self.class.allowed_job_types).empty?
+ end
+ end
+end
diff --git a/app/finders/security/license_compliance_jobs_finder.rb b/app/finders/security/license_compliance_jobs_finder.rb
new file mode 100644
index 00000000000..100f94b2cc7
--- /dev/null
+++ b/app/finders/security/license_compliance_jobs_finder.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+# Security::LicenseScanningJobsFinder
+#
+# Used to find jobs (builds) that are related to the License Management.
+#
+# Arguments:
+# params:
+# pipeline: required, only jobs for the specified pipeline will be found
+# job_types: required, array of job types that should be returned, defaults to all job types
+
+module Security
+ class LicenseComplianceJobsFinder < JobsFinder
+ def self.allowed_job_types
+ [:license_management, :license_scanning]
+ end
+ end
+end
diff --git a/app/finders/security/security_jobs_finder.rb b/app/finders/security/security_jobs_finder.rb
new file mode 100644
index 00000000000..2352e19c7da
--- /dev/null
+++ b/app/finders/security/security_jobs_finder.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+# Security::SecurityJobsFinder
+#
+# Used to find jobs (builds) that are related to the Secure products:
+# SAST, DAST, Dependency Scanning and Container Scanning
+#
+# Arguments:
+# params:
+# pipeline: required, only jobs for the specified pipeline will be found
+# job_types: required, array of job types that should be returned, defaults to all job types
+
+module Security
+ class SecurityJobsFinder < JobsFinder
+ def self.allowed_job_types
+ [:sast, :dast, :dependency_scanning, :container_scanning, :secret_detection, :coverage_fuzzing, :api_fuzzing]
+ end
+ end
+end
diff --git a/app/finders/user_groups_counter.rb b/app/finders/user_groups_counter.rb
new file mode 100644
index 00000000000..7dbc8502be2
--- /dev/null
+++ b/app/finders/user_groups_counter.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+class UserGroupsCounter
+ def initialize(user_ids)
+ @user_ids = user_ids
+ end
+
+ def execute
+ Namespace.unscoped do
+ Namespace.from_union([
+ groups,
+ project_groups
+ ]).group(:user_id).count # rubocop: disable CodeReuse/ActiveRecord
+ end
+ end
+
+ private
+
+ attr_reader :user_ids
+
+ def groups
+ Group.for_authorized_group_members(user_ids)
+ .select('namespaces.*, members.user_id as user_id')
+ end
+
+ def project_groups
+ Group.for_authorized_project_members(user_ids)
+ .select('namespaces.*, project_authorizations.user_id as user_id')
+ end
+end