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-03-31 00:08:01 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-31 00:08:01 +0300
commit95ad46159e4cd93f2b31838199180d824e041994 (patch)
treed41880d3b6a0093463694978590e590efb08caef /app/finders/issuable_finder
parent2c72daf2f1744f2b8c8c6674c266907e9ef55558 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/finders/issuable_finder')
-rw-r--r--app/finders/issuable_finder/params.rb287
1 files changed, 287 insertions, 0 deletions
diff --git a/app/finders/issuable_finder/params.rb b/app/finders/issuable_finder/params.rb
new file mode 100644
index 00000000000..120ef364368
--- /dev/null
+++ b/app/finders/issuable_finder/params.rb
@@ -0,0 +1,287 @@
+# frozen_string_literal: true
+
+class IssuableFinder
+ class Params < SimpleDelegator
+ include Gitlab::Utils::StrongMemoize
+
+ # This is used as a common filter for None / Any
+ FILTER_NONE = 'none'
+ FILTER_ANY = 'any'
+
+ # This is used in unassigning users
+ NONE = '0'
+
+ alias_method :params, :__getobj__
+
+ attr_accessor :current_user, :klass
+
+ def initialize(params, current_user, klass)
+ @current_user = current_user
+ @klass = klass
+ # We turn the params into a HashWithIndifferentAccess. We must use #to_h first because sometimes
+ # we get ActionController::Params and IssuableFinder::Params objects here.
+ super(params.to_h.with_indifferent_access)
+ end
+
+ def present?
+ params.present?
+ end
+
+ def author_id?
+ params[:author_id].present? && params[:author_id] != NONE
+ end
+
+ def author_username?
+ params[:author_username].present? && params[:author_username] != NONE
+ end
+
+ def no_author?
+ # author_id takes precedence over author_username
+ params[:author_id] == NONE || params[:author_username] == NONE
+ end
+
+ def filter_by_no_assignee?
+ params[:assignee_id].to_s.downcase == FILTER_NONE
+ end
+
+ def filter_by_any_assignee?
+ params[:assignee_id].to_s.downcase == FILTER_ANY
+ end
+
+ def filter_by_no_label?
+ downcased = label_names.map(&:downcase)
+
+ downcased.include?(FILTER_NONE)
+ end
+
+ def filter_by_any_label?
+ label_names.map(&:downcase).include?(FILTER_ANY)
+ end
+
+ def labels?
+ params[:label_name].present?
+ end
+
+ def milestones?
+ params[:milestone_title].present?
+ end
+
+ def filter_by_no_milestone?
+ # Accepts `No Milestone` for compatibility
+ params[:milestone_title].to_s.downcase == FILTER_NONE || params[:milestone_title] == Milestone::None.title
+ end
+
+ def filter_by_any_milestone?
+ # Accepts `Any Milestone` for compatibility
+ params[:milestone_title].to_s.downcase == FILTER_ANY || params[:milestone_title] == Milestone::Any.title
+ end
+
+ def filter_by_upcoming_milestone?
+ params[:milestone_title] == Milestone::Upcoming.name
+ end
+
+ def filter_by_started_milestone?
+ params[:milestone_title] == Milestone::Started.name
+ end
+
+ def filter_by_no_release?
+ params[:release_tag].to_s.downcase == FILTER_NONE
+ end
+
+ def filter_by_any_release?
+ params[:release_tag].to_s.downcase == FILTER_ANY
+ end
+
+ def filter_by_no_reaction?
+ params[:my_reaction_emoji].to_s.downcase == FILTER_NONE
+ end
+
+ def filter_by_any_reaction?
+ params[:my_reaction_emoji].to_s.downcase == FILTER_ANY
+ end
+
+ def releases?
+ params[:release_tag].present?
+ end
+
+ def project?
+ params[:project_id].present?
+ end
+
+ def group
+ strong_memoize(:group) do
+ if params[:group_id].present?
+ Group.find(params[:group_id])
+ else
+ nil
+ end
+ end
+ end
+
+ def related_groups
+ if project? && project&.group && Ability.allowed?(current_user, :read_group, project.group)
+ project.group.self_and_ancestors
+ elsif group
+ [group]
+ elsif current_user
+ Gitlab::ObjectHierarchy.new(current_user.authorized_groups, current_user.groups).all_objects
+ else
+ []
+ end
+ end
+
+ def project
+ strong_memoize(:project) do
+ project = Project.find(params[:project_id])
+ project = nil unless Ability.allowed?(current_user, :"read_#{klass.to_ability_name}", project)
+
+ project
+ end
+ end
+
+ def projects
+ strong_memoize(:projects) do
+ next [project] if project?
+
+ projects =
+ if current_user && params[:authorized_only].presence && !current_user_related?
+ current_user.authorized_projects(min_access_level)
+ else
+ projects_public_or_visible_to_user
+ end
+
+ projects.with_feature_available_for_user(klass, current_user).reorder(nil) # rubocop: disable CodeReuse/ActiveRecord
+ end
+ end
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def author
+ strong_memoize(:author) do
+ if author_id?
+ User.find_by(id: params[:author_id])
+ elsif author_username?
+ User.find_by_username(params[:author_username])
+ else
+ nil
+ end
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ # rubocop: disable CodeReuse/ActiveRecord
+ def assignees
+ strong_memoize(:assignees) do
+ if assignee_id?
+ User.where(id: params[:assignee_id])
+ elsif assignee_username?
+ User.where(username: params[:assignee_username])
+ else
+ User.none
+ end
+ end
+ end
+ # rubocop: enable CodeReuse/ActiveRecord
+
+ def assignee
+ assignees.first
+ end
+
+ def label_names
+ if labels?
+ params[:label_name].is_a?(String) ? params[:label_name].split(',') : params[:label_name]
+ else
+ []
+ end
+ end
+
+ def labels
+ strong_memoize(:labels) do
+ if labels? && !filter_by_no_label?
+ LabelsFinder.new(current_user, project_ids: projects, title: label_names).execute(skip_authorization: true) # rubocop: disable CodeReuse/Finder
+ else
+ Label.none
+ end
+ end
+ end
+
+ def milestones
+ strong_memoize(:milestones) do
+ if milestones?
+ if project?
+ group_id = project.group&.id
+ project_id = project.id
+ end
+
+ group_id = group.id if group
+
+ search_params =
+ { title: params[:milestone_title], project_ids: project_id, group_ids: group_id }
+
+ MilestonesFinder.new(search_params).execute # rubocop: disable CodeReuse/Finder
+ else
+ Milestone.none
+ end
+ end
+ end
+
+ def current_user_related?
+ scope = params[:scope]
+ scope == 'created_by_me' || scope == 'authored' || scope == 'assigned_to_me'
+ end
+
+ def find_group_projects
+ return Project.none unless group
+
+ if params[:include_subgroups]
+ Project.where(namespace_id: group.self_and_descendants) # rubocop: disable CodeReuse/ActiveRecord
+ else
+ group.projects
+ end
+ end
+
+ # We use Hash#merge in a few places, so let's support it
+ def merge(other)
+ self.class.new(params.merge(other), current_user, klass)
+ end
+
+ # Just for symmetry, and in case someone tries to use it
+ def merge!(other)
+ params.merge!(other)
+ end
+
+ private
+
+ def projects_public_or_visible_to_user
+ projects =
+ if group
+ if params[:projects]
+ find_group_projects.id_in(params[:projects])
+ else
+ find_group_projects
+ end
+ elsif params[:projects]
+ Project.id_in(params[:projects])
+ else
+ Project
+ end
+
+ projects.public_or_visible_to_user(current_user, min_access_level)
+ end
+
+ def min_access_level
+ ProjectFeature.required_minimum_access_level(klass)
+ end
+
+ def method_missing(method_name, *args, &block)
+ if method_name[-1] == '?'
+ params[method_name[0..-2].to_sym].present?
+ else
+ super
+ end
+ end
+
+ def respond_to_missing?(method_name, include_private = false)
+ method_name[-1] == '?'
+ end
+ end
+end