summaryrefslogtreecommitdiff
path: root/app/finders
diff options
context:
space:
mode:
Diffstat (limited to 'app/finders')
-rw-r--r--app/finders/ci/daily_build_group_report_results_finder.rb16
-rw-r--r--app/finders/concerns/merged_at_filter.rb33
-rw-r--r--app/finders/context_commits_finder.rb4
-rw-r--r--app/finders/design_management/designs_finder.rb7
-rw-r--r--app/finders/group_members_finder.rb2
-rw-r--r--app/finders/issues_finder.rb10
-rw-r--r--app/finders/members_finder.rb8
-rw-r--r--app/finders/merge_requests_finder.rb27
-rw-r--r--app/finders/milestones_finder.rb8
-rw-r--r--app/finders/personal_access_tokens_finder.rb13
-rw-r--r--app/finders/releases_finder.rb41
-rw-r--r--app/finders/template_finder.rb9
-rw-r--r--app/finders/todos_finder.rb10
13 files changed, 161 insertions, 27 deletions
diff --git a/app/finders/ci/daily_build_group_report_results_finder.rb b/app/finders/ci/daily_build_group_report_results_finder.rb
index 774f08d1ff2..ec41d9d2c45 100644
--- a/app/finders/ci/daily_build_group_report_results_finder.rb
+++ b/app/finders/ci/daily_build_group_report_results_finder.rb
@@ -14,17 +14,25 @@ module Ci
end
def execute
- return none unless can?(current_user, :read_build_report_results, project)
+ return none unless query_allowed?
+ query
+ end
+
+ protected
+
+ attr_reader :current_user, :project, :ref_path, :start_date, :end_date, :limit
+
+ def query
Ci::DailyBuildGroupReportResult.recent_results(
query_params,
limit: limit
)
end
- private
-
- attr_reader :current_user, :project, :ref_path, :start_date, :end_date, :limit
+ def query_allowed?
+ can?(current_user, :read_build_report_results, project)
+ end
def query_params
{
diff --git a/app/finders/concerns/merged_at_filter.rb b/app/finders/concerns/merged_at_filter.rb
new file mode 100644
index 00000000000..d2858ba2f88
--- /dev/null
+++ b/app/finders/concerns/merged_at_filter.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module MergedAtFilter
+ private
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def by_merged_at(items)
+ return items unless merged_after || merged_before
+
+ mr_metrics_scope = MergeRequest::Metrics
+ mr_metrics_scope = mr_metrics_scope.merged_after(merged_after) if merged_after.present?
+ mr_metrics_scope = mr_metrics_scope.merged_before(merged_before) if merged_before.present?
+
+ scope = items.joins(:metrics).merge(mr_metrics_scope)
+ scope = target_project_id_filter_on_metrics(scope) if Feature.enabled?(:improved_mr_merged_at_queries)
+ scope
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def merged_after
+ params[:merged_after]
+ end
+
+ def merged_before
+ params[:merged_before]
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def target_project_id_filter_on_metrics(scope)
+ scope.where(MergeRequest.arel_table[:target_project_id].eq(MergeRequest::Metrics.arel_table[:target_project_id]))
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+end
diff --git a/app/finders/context_commits_finder.rb b/app/finders/context_commits_finder.rb
index f1b3eb43e84..de89a556ee0 100644
--- a/app/finders/context_commits_finder.rb
+++ b/app/finders/context_commits_finder.rb
@@ -25,7 +25,7 @@ class ContextCommitsFinder
if search.present?
search_commits
else
- project.repository.commits(merge_request.source_branch, { limit: limit, offset: offset })
+ project.repository.commits(merge_request.target_branch, { limit: limit, offset: offset })
end
commits
@@ -47,7 +47,7 @@ class ContextCommitsFinder
commits = [commit_by_sha] if commit_by_sha
end
else
- commits = project.repository.find_commits_by_message(search, nil, nil, 20)
+ commits = project.repository.find_commits_by_message(search, merge_request.target_branch, nil, 20)
end
commits
diff --git a/app/finders/design_management/designs_finder.rb b/app/finders/design_management/designs_finder.rb
index 10f95520d1e..d9732f6b6f4 100644
--- a/app/finders/design_management/designs_finder.rb
+++ b/app/finders/design_management/designs_finder.rb
@@ -22,7 +22,9 @@ module DesignManagement
items = by_filename(items)
items = by_id(items)
- items
+ # TODO: We don't need to pass the project anymore after the feature flag is removed
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/34382
+ items.ordered(issue.project)
end
private
@@ -35,7 +37,8 @@ module DesignManagement
issue.designs
end
- # Returns all designs that existed at a particular design version
+ # Returns all designs that existed at a particular design version,
+ # where `nil` means `at-current-version`.
def by_visible_at_version(items)
items.visible_at_version(params[:visible_at_version])
end
diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb
index 949af103eb3..a4b00588368 100644
--- a/app/finders/group_members_finder.rb
+++ b/app/finders/group_members_finder.rb
@@ -57,7 +57,7 @@ class GroupMembersFinder < UnionFinder
members = members.search(params[:search]) if params[:search].present?
members = members.sort_by_attribute(params[:sort]) if params[:sort].present?
- if can_manage_members && params[:two_factor].present?
+ if params[:two_factor].present? && can_manage_members
members = members.filter_by_2fa(params[:two_factor])
end
diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb
index 2b2e6b377b4..bbb624f543b 100644
--- a/app/finders/issues_finder.rb
+++ b/app/finders/issues_finder.rb
@@ -25,6 +25,7 @@
# updated_after: datetime
# updated_before: datetime
# confidential: boolean
+# issue_type: array of strings (one of Issue.issue_types)
#
class IssuesFinder < IssuableFinder
CONFIDENTIAL_ACCESS_LEVEL = Gitlab::Access::REPORTER
@@ -73,6 +74,7 @@ class IssuesFinder < IssuableFinder
issues = super
issues = by_due_date(issues)
issues = by_confidential(issues)
+ issues = by_issue_types(issues)
issues
end
@@ -97,6 +99,14 @@ class IssuesFinder < IssuableFinder
items.due_between(Date.today - 2.weeks, (Date.today + 1.month).end_of_month)
end
end
+
+ def by_issue_types(items)
+ issue_type_params = Array(params[:issue_types]).map(&:to_s)
+ return items if issue_type_params.blank?
+ return Issue.none unless (Issue.issue_types.keys & issue_type_params).sort == issue_type_params.sort
+
+ items.with_issue_type(params[:issue_types])
+ end
end
IssuesFinder.prepend_if_ee('EE::IssuesFinder')
diff --git a/app/finders/members_finder.rb b/app/finders/members_finder.rb
index e08ed737ca6..ce9137f91bb 100644
--- a/app/finders/members_finder.rb
+++ b/app/finders/members_finder.rb
@@ -29,7 +29,12 @@ class MembersFinder
def find_members(include_relations)
project_members = project.project_members
- project_members = project_members.non_invite unless can?(current_user, :admin_project, project)
+
+ if params[:active_without_invites_and_requests].present?
+ project_members = project_members.active_without_invites_and_requests
+ else
+ project_members = project_members.non_invite unless can?(current_user, :admin_project, project)
+ end
return project_members if include_relations == [:direct]
@@ -44,6 +49,7 @@ class MembersFinder
def filter_members(members)
members = members.search(params[:search]) if params[:search].present?
members = members.sort_by_attribute(params[:sort]) if params[:sort].present?
+ members = members.owners_and_maintainers if params[:owners_and_maintainers].present?
members
end
diff --git a/app/finders/merge_requests_finder.rb b/app/finders/merge_requests_finder.rb
index d5e6c4783c1..b70d0b7a06a 100644
--- a/app/finders/merge_requests_finder.rb
+++ b/app/finders/merge_requests_finder.rb
@@ -30,8 +30,10 @@
# updated_before: datetime
#
class MergeRequestsFinder < IssuableFinder
+ include MergedAtFilter
+
def self.scalar_params
- @scalar_params ||= super + [:wip, :target_branch]
+ @scalar_params ||= super + [:wip, :draft, :target_branch, :merged_after, :merged_before]
end
def klass
@@ -42,8 +44,9 @@ class MergeRequestsFinder < IssuableFinder
items = by_commit(super)
items = by_deployment(items)
items = by_source_branch(items)
- items = by_wip(items)
+ items = by_draft(items)
items = by_target_branch(items)
+ items = by_merged_at(items)
by_source_project_id(items)
end
@@ -88,20 +91,32 @@ class MergeRequestsFinder < IssuableFinder
items.where(source_project_id: source_project_id)
end
- def by_wip(items)
- if params[:wip] == 'yes'
+ def by_draft(items)
+ draft_param = params[:draft] || params[:wip]
+
+ if draft_param == 'yes'
items.where(wip_match(items.arel_table))
- elsif params[:wip] == 'no'
+ elsif draft_param == 'no'
items.where.not(wip_match(items.arel_table))
else
items
end
end
+ # WIP is deprecated in favor of Draft. Currently both options are supported
def wip_match(table)
- table[:title].matches('WIP:%')
+ items =
+ table[:title].matches('WIP:%')
.or(table[:title].matches('WIP %'))
.or(table[:title].matches('[WIP]%'))
+
+ return items unless Feature.enabled?(:merge_request_draft_filter)
+
+ items
+ .or(table[:title].matches('Draft - %'))
+ .or(table[:title].matches('Draft:%'))
+ .or(table[:title].matches('[Draft]%'))
+ .or(table[:title].matches('(Draft)%'))
end
def by_deployment(items)
diff --git a/app/finders/milestones_finder.rb b/app/finders/milestones_finder.rb
index 8f0cdf3b255..16e59b31b36 100644
--- a/app/finders/milestones_finder.rb
+++ b/app/finders/milestones_finder.rb
@@ -3,6 +3,7 @@
# Search for milestones
#
# params - Hash
+# ids - filters by id.
# project_ids: Array of project ids or single project id or ActiveRecord relation.
# group_ids: Array of group ids or single group id or ActiveRecord relation.
# order - Orders by field default due date asc.
@@ -21,6 +22,7 @@ class MilestonesFinder
def execute
items = Milestone.all
+ items = by_ids(items)
items = by_groups_and_projects(items)
items = by_title(items)
items = by_search_title(items)
@@ -32,6 +34,12 @@ class MilestonesFinder
private
+ def by_ids(items)
+ return items unless params[:ids].present?
+
+ items.id_in(params[:ids])
+ end
+
def by_groups_and_projects(items)
items.for_projects_and_groups(params[:project_ids], params[:group_ids])
end
diff --git a/app/finders/personal_access_tokens_finder.rb b/app/finders/personal_access_tokens_finder.rb
index e3d5f2ae8de..93f8c520b63 100644
--- a/app/finders/personal_access_tokens_finder.rb
+++ b/app/finders/personal_access_tokens_finder.rb
@@ -5,12 +5,14 @@ class PersonalAccessTokensFinder
delegate :build, :find, :find_by_id, :find_by_token, to: :execute
- def initialize(params = {})
+ def initialize(params = {}, current_user = nil)
@params = params
+ @current_user = current_user
end
def execute
tokens = PersonalAccessToken.all
+ tokens = by_current_user(tokens)
tokens = by_user(tokens)
tokens = by_impersonation(tokens)
tokens = by_state(tokens)
@@ -20,6 +22,15 @@ class PersonalAccessTokensFinder
private
+ attr_reader :current_user
+
+ def by_current_user(tokens)
+ return tokens if current_user.nil? || current_user.admin?
+ return PersonalAccessToken.none unless Ability.allowed?(current_user, :read_user_personal_access_tokens, params[:user])
+
+ tokens
+ end
+
def by_user(tokens)
return tokens unless @params[:user]
diff --git a/app/finders/releases_finder.rb b/app/finders/releases_finder.rb
index 6a754fdb5a1..e961ad4c0ca 100644
--- a/app/finders/releases_finder.rb
+++ b/app/finders/releases_finder.rb
@@ -1,19 +1,20 @@
# frozen_string_literal: true
class ReleasesFinder
- attr_reader :project, :current_user, :params
+ include Gitlab::Utils::StrongMemoize
- def initialize(project, current_user = nil, params = {})
- @project = project
+ attr_reader :parent, :current_user, :params
+
+ def initialize(parent, current_user = nil, params = {})
+ @parent = parent
@current_user = current_user
@params = params
end
def execute(preload: true)
- return Release.none unless Ability.allowed?(current_user, :read_release, project)
+ return Release.none if projects.empty?
- # See https://gitlab.com/gitlab-org/gitlab/-/issues/211988
- releases = project.releases.where.not(tag: nil) # rubocop:disable CodeReuse/ActiveRecord
+ releases = get_releases
releases = by_tag(releases)
releases = releases.preloaded if preload
releases.sorted
@@ -21,6 +22,34 @@ class ReleasesFinder
private
+ def get_releases
+ Release.where(project_id: projects).where.not(tag: nil) # rubocop: disable CodeReuse/ActiveRecord
+ end
+
+ def include_subgroups?
+ params.fetch(:include_subgroups, false)
+ end
+
+ def projects
+ strong_memoize(:projects) do
+ if parent.is_a?(Project)
+ Ability.allowed?(current_user, :read_release, parent) ? [parent] : []
+ elsif parent.is_a?(Group)
+ accessible_projects
+ end
+ end
+ end
+
+ def accessible_projects
+ projects = if include_subgroups?
+ Project.for_group_and_its_subgroups(parent)
+ else
+ parent.projects
+ end
+
+ projects.select { |project| Ability.allowed?(current_user, :read_release, project) }
+ end
+
# rubocop: disable CodeReuse/ActiveRecord
def by_tag(releases)
return releases unless params[:tag].present?
diff --git a/app/finders/template_finder.rb b/app/finders/template_finder.rb
index 78c8392f1cd..a35376e905e 100644
--- a/app/finders/template_finder.rb
+++ b/app/finders/template_finder.rb
@@ -6,7 +6,10 @@ class TemplateFinder
VENDORED_TEMPLATES = HashWithIndifferentAccess.new(
dockerfiles: ::Gitlab::Template::DockerfileTemplate,
gitignores: ::Gitlab::Template::GitignoreTemplate,
- gitlab_ci_ymls: ::Gitlab::Template::GitlabCiYmlTemplate
+ gitlab_ci_ymls: ::Gitlab::Template::GitlabCiYmlTemplate,
+ metrics_dashboard_ymls: ::Gitlab::Template::MetricsDashboardTemplate,
+ issues: ::Gitlab::Template::IssueTemplate,
+ merge_requests: ::Gitlab::Template::MergeRequestTemplate
).freeze
class << self
@@ -34,9 +37,9 @@ class TemplateFinder
def execute
if params[:name]
- vendored_templates.find(params[:name])
+ vendored_templates.find(params[:name], project)
else
- vendored_templates.all
+ vendored_templates.all(project)
end
end
end
diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb
index a2054f73c9d..f28e1281488 100644
--- a/app/finders/todos_finder.rb
+++ b/app/finders/todos_finder.rb
@@ -10,6 +10,7 @@
# action_id: integer
# author_id: integer
# project_id; integer
+# target_id; integer
# state: 'pending' (default) or 'done'
# type: 'Issue' or 'MergeRequest' or ['Issue', 'MergeRequest']
#
@@ -23,7 +24,7 @@ class TodosFinder
NONE = '0'
- TODO_TYPES = Set.new(%w(Issue MergeRequest DesignManagement::Design)).freeze
+ TODO_TYPES = Set.new(%w(Issue MergeRequest DesignManagement::Design AlertManagement::Alert)).freeze
attr_accessor :current_user, :params
@@ -47,6 +48,7 @@ class TodosFinder
items = by_action(items)
items = by_author(items)
items = by_state(items)
+ items = by_target_id(items)
items = by_types(items)
items = by_group(items)
# Filtering by project HAS TO be the last because we use
@@ -198,6 +200,12 @@ class TodosFinder
items.with_states(params[:state])
end
+ def by_target_id(items)
+ return items if params[:target_id].blank?
+
+ items.for_target(params[:target_id])
+ end
+
def by_types(items)
if types.any?
items.for_type(types)