summaryrefslogtreecommitdiff
path: root/app/finders
diff options
context:
space:
mode:
authorLuke "Jared" Bennett <lbennett@gitlab.com>2017-04-04 14:56:27 +0100
committerLuke "Jared" Bennett <lbennett@gitlab.com>2017-04-04 14:56:27 +0100
commitccca73d779ae0e22a86c9586fd52b15a8600b9f3 (patch)
tree7385d9a2019bfa98affe9bc83c0afd7da2fd730d /app/finders
parentc252c03401881fd7dbf7fab984285c402eb31d5f (diff)
parent5f7ebfb9aa023849b8b296bf9cf0f472b886d072 (diff)
downloadgitlab-ce-ccca73d779ae0e22a86c9586fd52b15a8600b9f3.tar.gz
Merge branch 'master' into add-sentry-js-again-with-vue
Diffstat (limited to 'app/finders')
-rw-r--r--app/finders/environments_finder.rb55
-rw-r--r--app/finders/group_finder.rb17
-rw-r--r--app/finders/group_members_finder.rb20
-rw-r--r--app/finders/group_projects_finder.rb2
-rw-r--r--app/finders/groups_finder.rb2
-rw-r--r--app/finders/issuable_finder.rb58
-rw-r--r--app/finders/issues_finder.rb8
-rw-r--r--app/finders/labels_finder.rb13
-rw-r--r--app/finders/members_finder.rb40
-rw-r--r--app/finders/merge_requests_finder.rb8
-rw-r--r--app/finders/notes_finder.rb11
-rw-r--r--app/finders/personal_access_tokens_finder.rb45
-rw-r--r--app/finders/pipelines_finder.rb6
-rw-r--r--app/finders/projects_finder.rb2
-rw-r--r--app/finders/todos_finder.rb4
15 files changed, 235 insertions, 56 deletions
diff --git a/app/finders/environments_finder.rb b/app/finders/environments_finder.rb
new file mode 100644
index 00000000000..a59f8c1efa3
--- /dev/null
+++ b/app/finders/environments_finder.rb
@@ -0,0 +1,55 @@
+class EnvironmentsFinder
+ attr_reader :project, :current_user, :params
+
+ def initialize(project, current_user, params = {})
+ @project, @current_user, @params = project, current_user, params
+ end
+
+ def execute
+ deployments = project.deployments
+ deployments =
+ if ref
+ deployments_query = params[:with_tags] ? 'ref = :ref OR tag IS TRUE' : 'ref = :ref'
+ deployments.where(deployments_query, ref: ref.to_s)
+ elsif commit
+ deployments.where(sha: commit.sha)
+ else
+ deployments.none
+ end
+
+ environment_ids = deployments
+ .group(:environment_id)
+ .select(:environment_id)
+
+ environments = project.environments.available
+ .where(id: environment_ids).order_by_last_deployed_at.to_a
+
+ environments.select! do |environment|
+ Ability.allowed?(current_user, :read_environment, environment)
+ end
+
+ if ref && commit
+ environments.select! do |environment|
+ environment.includes_commit?(commit)
+ end
+ end
+
+ if ref && params[:recently_updated]
+ environments.select! do |environment|
+ environment.recently_updated_on_branch?(ref)
+ end
+ end
+
+ environments
+ end
+
+ private
+
+ def ref
+ params[:ref].try(:to_s)
+ end
+
+ def commit
+ params[:commit]
+ end
+end
diff --git a/app/finders/group_finder.rb b/app/finders/group_finder.rb
new file mode 100644
index 00000000000..24c84d2d1aa
--- /dev/null
+++ b/app/finders/group_finder.rb
@@ -0,0 +1,17 @@
+class GroupFinder
+ include Gitlab::Allowable
+
+ def initialize(current_user)
+ @current_user = current_user
+ end
+
+ def execute(*params)
+ group = Group.find_by(*params)
+
+ if can?(@current_user, :read_group, group)
+ group
+ else
+ nil
+ end
+ end
+end
diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb
new file mode 100644
index 00000000000..fce3775f40e
--- /dev/null
+++ b/app/finders/group_members_finder.rb
@@ -0,0 +1,20 @@
+class GroupMembersFinder
+ def initialize(group)
+ @group = group
+ end
+
+ def execute
+ group_members = @group.members
+
+ return group_members unless @group.parent
+
+ parents_members = GroupMember.non_request.
+ where(source_id: @group.ancestors.select(:id)).
+ where.not(user_id: @group.users.select(:id))
+
+ wheres = ["members.id IN (#{group_members.select(:id).to_sql})"]
+ wheres << "members.id IN (#{parents_members.select(:id).to_sql})"
+
+ GroupMember.where(wheres.join(' OR '))
+ end
+end
diff --git a/app/finders/group_projects_finder.rb b/app/finders/group_projects_finder.rb
index aa8f4c1d0e4..3b9a421b118 100644
--- a/app/finders/group_projects_finder.rb
+++ b/app/finders/group_projects_finder.rb
@@ -18,7 +18,7 @@ class GroupProjectsFinder < UnionFinder
projects = []
if current_user
- if @group.users.include?(current_user) || current_user.admin?
+ if @group.users.include?(current_user)
projects << @group.projects unless only_shared
projects << @group.shared_projects unless only_owned
else
diff --git a/app/finders/groups_finder.rb b/app/finders/groups_finder.rb
index 4e43f42e9e1..d932a17883f 100644
--- a/app/finders/groups_finder.rb
+++ b/app/finders/groups_finder.rb
@@ -2,7 +2,7 @@ class GroupsFinder < UnionFinder
def execute(current_user = nil)
segments = all_groups(current_user)
- find_union(segments, Group).order_id_desc
+ find_union(segments, Group).with_route.order_id_desc
end
private
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 1576fc80a6b..f7ebb1807d7 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -16,9 +16,10 @@
# label_name: string
# sort: string
# non_archived: boolean
+# iids: integer[]
#
class IssuableFinder
- NONE = '0'
+ NONE = '0'.freeze
attr_accessor :current_user, :params
@@ -32,14 +33,17 @@ class IssuableFinder
items = by_scope(items)
items = by_state(items)
items = by_group(items)
- items = by_project(items)
items = by_search(items)
- items = by_milestone(items)
items = by_assignee(items)
items = by_author(items)
- items = by_label(items)
items = by_due_date(items)
items = by_non_archived(items)
+ items = by_iids(items)
+ items = by_milestone(items)
+ items = by_label(items)
+
+ # Filtering by project HAS TO be the last because we use the project IDs yielded by the issuable query thus far
+ items = by_project(items)
sort(items)
end
@@ -105,8 +109,7 @@ class IssuableFinder
@project = project
end
- def projects
- return @projects if defined?(@projects)
+ def projects(items = nil)
return @projects = project if project?
projects =
@@ -115,7 +118,7 @@ class IssuableFinder
elsif group
GroupProjectsFinder.new(group).execute(current_user)
else
- ProjectsFinder.new.execute(current_user)
+ projects_finder.execute(current_user, item_project_ids(items))
end
@projects = projects.with_feature_available_for_user(klass, current_user).reorder(nil)
@@ -255,9 +258,9 @@ class IssuableFinder
def by_project(items)
items =
if project?
- items.of_projects(projects).references_project
- elsif projects
- items.merge(projects.reorder(nil)).join_project
+ items.of_projects(projects(items)).references_project
+ elsif projects(items)
+ items.merge(projects(items).reorder(nil)).join_project
else
items.none
end
@@ -266,16 +269,11 @@ class IssuableFinder
end
def by_search(items)
- if search
- items =
- if search =~ iid_pattern
- items.where(iid: $~[:iid])
- else
- items.full_search(search)
- end
- end
+ search ? items.full_search(search) : items
+ end
- items
+ def by_iids(items)
+ params[:iids].present? ? items.where(iid: params[:iids]) : items
end
def sort(items)
@@ -312,18 +310,25 @@ class IssuableFinder
params[:milestone_title] == Milestone::Upcoming.name
end
+ def filter_by_started_milestone?
+ params[:milestone_title] == Milestone::Started.name
+ end
+
def by_milestone(items)
if milestones?
if filter_by_no_milestone?
items = items.left_joins_milestones.where(milestone_id: [-1, nil])
elsif filter_by_upcoming_milestone?
- upcoming_ids = Milestone.upcoming_ids_by_projects(projects)
+ upcoming_ids = Milestone.upcoming_ids_by_projects(projects(items))
items = items.left_joins_milestones.where(milestone_id: upcoming_ids)
+ elsif filter_by_started_milestone?
+ items = items.left_joins_milestones.where('milestones.start_date <= NOW()')
else
items = items.with_milestone(params[:milestone_title])
+ items_projects = projects(items)
- if projects
- items = items.where(milestones: { project_id: projects })
+ if items_projects
+ items = items.where(milestones: { project_id: items_projects })
end
end
end
@@ -337,9 +342,10 @@ class IssuableFinder
items = items.without_label
else
items = items.with_label(label_names, params[:sort])
+ items_projects = projects(items)
- if projects
- label_ids = LabelsFinder.new(current_user, project_ids: projects).execute(skip_authorization: true).select(:id)
+ if items_projects
+ label_ids = LabelsFinder.new(current_user, project_ids: items_projects).execute(skip_authorization: true).select(:id)
items = items.where(labels: { id: label_ids })
end
end
@@ -399,4 +405,8 @@ class IssuableFinder
def current_user_related?
params[:scope] == 'created-by-me' || params[:scope] == 'authored' || params[:scope] == 'assigned-to-me'
end
+
+ def projects_finder
+ @projects_finder ||= ProjectsFinder.new
+ end
end
diff --git a/app/finders/issues_finder.rb b/app/finders/issues_finder.rb
index 707eddd4d29..08713272947 100644
--- a/app/finders/issues_finder.rb
+++ b/app/finders/issues_finder.rb
@@ -26,10 +26,6 @@ class IssuesFinder < IssuableFinder
IssuesFinder.not_restricted_by_confidentiality(current_user)
end
- def iid_pattern
- @iid_pattern ||= %r{\A#{Regexp.escape(Issue.reference_prefix)}(?<iid>\d+)\z}
- end
-
def self.not_restricted_by_confidentiality(user)
return Issue.where('issues.confidential IS NULL OR issues.confidential IS FALSE') if user.blank?
@@ -45,4 +41,8 @@ class IssuesFinder < IssuableFinder
user_id: user.id,
project_ids: user.authorized_projects(Gitlab::Access::REPORTER).select(:id))
end
+
+ def item_project_ids(items)
+ items&.reorder(nil)&.select(:project_id)
+ end
end
diff --git a/app/finders/labels_finder.rb b/app/finders/labels_finder.rb
index fa0e2a5e3d8..e52083f86e4 100644
--- a/app/finders/labels_finder.rb
+++ b/app/finders/labels_finder.rb
@@ -20,8 +20,17 @@ class LabelsFinder < UnionFinder
if project?
if project
- label_ids << project.group.labels if project.group.present?
- label_ids << project.labels
+ if project.group.present?
+ labels_table = Label.arel_table
+
+ label_ids << Label.where(
+ labels_table[:type].eq('GroupLabel').and(labels_table[:group_id].eq(project.group.id)).or(
+ labels_table[:type].eq('ProjectLabel').and(labels_table[:project_id].eq(project.id))
+ )
+ )
+ else
+ label_ids << project.labels
+ end
end
else
label_ids << Label.where(group_id: projects.group_ids)
diff --git a/app/finders/members_finder.rb b/app/finders/members_finder.rb
index 702944404f5..af24045886e 100644
--- a/app/finders/members_finder.rb
+++ b/app/finders/members_finder.rb
@@ -1,13 +1,35 @@
-class MembersFinder < Projects::ApplicationController
- def initialize(project_members, project_group)
- @project_members = project_members
- @project_group = project_group
+class MembersFinder
+ attr_reader :project, :current_user, :group
+
+ def initialize(project, current_user)
+ @project = project
+ @current_user = current_user
+ @group = project.group
+ end
+
+ def execute
+ project_members = project.project_members
+ project_members = project_members.non_invite unless can?(current_user, :admin_project, project)
+ wheres = ["members.id IN (#{project_members.select(:id).to_sql})"]
+
+ if group
+ # We need `.where.not(user_id: nil)` here otherwise when a group has an
+ # invitee, it would make the following query return 0 rows since a NULL
+ # user_id would be present in the subquery
+ # See http://stackoverflow.com/questions/129077/not-in-clause-and-null-values
+ non_null_user_ids = project_members.where.not(user_id: nil).select(:user_id)
+
+ group_members = GroupMembersFinder.new(group).execute
+ group_members = group_members.where.not(user_id: non_null_user_ids)
+ group_members = group_members.non_invite unless can?(current_user, :admin_group, group)
+
+ wheres << "members.id IN (#{group_members.select(:id).to_sql})"
+ end
+
+ Member.where(wheres.join(' OR '))
end
- def execute(current_user)
- non_null_user_ids = @project_members.where.not(user_id: nil).select(:user_id)
- group_members = @project_group.group_members.where.not(user_id: non_null_user_ids)
- group_members = group_members.non_invite unless can?(current_user, :admin_group, @project_group)
- group_members
+ def can?(*args)
+ Ability.allowed?(*args)
end
end
diff --git a/app/finders/merge_requests_finder.rb b/app/finders/merge_requests_finder.rb
index 8b82255445e..1eec45d9cb5 100644
--- a/app/finders/merge_requests_finder.rb
+++ b/app/finders/merge_requests_finder.rb
@@ -23,11 +23,7 @@ class MergeRequestsFinder < IssuableFinder
private
- def iid_pattern
- @iid_pattern ||= %r{\A[
- #{Regexp.escape(MergeRequest.reference_prefix)}
- #{Regexp.escape(Issue.reference_prefix)}
- ](?<iid>\d+)\z
- }x
+ def item_project_ids(items)
+ items&.reorder(nil)&.select(:target_project_id)
end
end
diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb
index 4bd8c83081a..6630c6384f2 100644
--- a/app/finders/notes_finder.rb
+++ b/app/finders/notes_finder.rb
@@ -28,11 +28,12 @@ class NotesFinder
private
def init_collection
- if @params[:target_id]
- @notes = on_target(@params[:target_type], @params[:target_id])
- else
- @notes = notes_of_any_type
- end
+ @notes =
+ if @params[:target_id]
+ on_target(@params[:target_type], @params[:target_id])
+ else
+ notes_of_any_type
+ end
end
def notes_of_any_type
diff --git a/app/finders/personal_access_tokens_finder.rb b/app/finders/personal_access_tokens_finder.rb
new file mode 100644
index 00000000000..760166b453f
--- /dev/null
+++ b/app/finders/personal_access_tokens_finder.rb
@@ -0,0 +1,45 @@
+class PersonalAccessTokensFinder
+ attr_accessor :params
+
+ delegate :build, :find, :find_by, to: :execute
+
+ def initialize(params = {})
+ @params = params
+ end
+
+ def execute
+ tokens = PersonalAccessToken.all
+ tokens = by_user(tokens)
+ tokens = by_impersonation(tokens)
+ by_state(tokens)
+ end
+
+ private
+
+ def by_user(tokens)
+ return tokens unless @params[:user]
+ tokens.where(user: @params[:user])
+ end
+
+ def by_impersonation(tokens)
+ case @params[:impersonation]
+ when true
+ tokens.with_impersonation
+ when false
+ tokens.without_impersonation
+ else
+ tokens
+ end
+ end
+
+ def by_state(tokens)
+ case @params[:state]
+ when 'active'
+ tokens.active
+ when 'inactive'
+ tokens.inactive
+ else
+ tokens
+ end
+ end
+end
diff --git a/app/finders/pipelines_finder.rb b/app/finders/pipelines_finder.rb
index 32aea75486d..a9172f6767f 100644
--- a/app/finders/pipelines_finder.rb
+++ b/app/finders/pipelines_finder.rb
@@ -10,7 +10,11 @@ class PipelinesFinder
scoped_pipelines =
case scope
when 'running'
- pipelines.running_or_pending
+ pipelines.running
+ when 'pending'
+ pipelines.pending
+ when 'finished'
+ pipelines.finished
when 'branches'
from_ids(ids_for_ref(branches))
when 'tags'
diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb
index c7911736812..18ec45f300d 100644
--- a/app/finders/projects_finder.rb
+++ b/app/finders/projects_finder.rb
@@ -3,7 +3,7 @@ class ProjectsFinder < UnionFinder
segments = all_projects(current_user)
segments.map! { |s| s.where(id: project_ids_relation) } if project_ids_relation
- find_union(segments, Project)
+ find_union(segments, Project).with_route
end
private
diff --git a/app/finders/todos_finder.rb b/app/finders/todos_finder.rb
index a93a63bdb9b..b7f091f334d 100644
--- a/app/finders/todos_finder.rb
+++ b/app/finders/todos_finder.rb
@@ -13,7 +13,7 @@
#
class TodosFinder
- NONE = '0'
+ NONE = '0'.freeze
attr_accessor :current_user, :params
@@ -99,7 +99,7 @@ class TodosFinder
end
def type?
- type.present? && ['Issue', 'MergeRequest'].include?(type)
+ type.present? && %w(Issue MergeRequest).include?(type)
end
def type