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:
Diffstat (limited to 'app/graphql/resolvers')
-rw-r--r--app/graphql/resolvers/alert_management/http_integrations_resolver.rb30
-rw-r--r--app/graphql/resolvers/alert_management/integrations_resolver.rb43
-rw-r--r--app/graphql/resolvers/base_resolver.rb24
-rw-r--r--app/graphql/resolvers/blobs_resolver.rb37
-rw-r--r--app/graphql/resolvers/board_lists_resolver.rb18
-rw-r--r--app/graphql/resolvers/board_resolver.rb2
-rw-r--r--app/graphql/resolvers/ci/config_resolver.rb6
-rw-r--r--app/graphql/resolvers/ci/jobs_resolver.rb13
-rw-r--r--app/graphql/resolvers/ci/pipeline_stages_resolver.rb2
-rw-r--r--app/graphql/resolvers/ci/runner_platforms_resolver.rb3
-rw-r--r--app/graphql/resolvers/ci/runner_setup_resolver.rb43
-rw-r--r--app/graphql/resolvers/ci/test_report_summary_resolver.rb17
-rw-r--r--app/graphql/resolvers/ci/test_suite_resolver.rb40
-rw-r--r--app/graphql/resolvers/concerns/board_issue_filterable.rb13
-rw-r--r--app/graphql/resolvers/concerns/issue_resolver_arguments.rb33
-rw-r--r--app/graphql/resolvers/concerns/looks_ahead.rb15
-rw-r--r--app/graphql/resolvers/concerns/manual_authorization.rb11
-rw-r--r--app/graphql/resolvers/concerns/resolves_merge_requests.rb3
-rw-r--r--app/graphql/resolvers/concerns/resolves_snippets.rb2
-rw-r--r--app/graphql/resolvers/echo_resolver.rb6
-rw-r--r--app/graphql/resolvers/environments_resolver.rb2
-rw-r--r--app/graphql/resolvers/group_members_resolver.rb6
-rw-r--r--app/graphql/resolvers/group_merge_requests_resolver.rb2
-rw-r--r--app/graphql/resolvers/group_milestones_resolver.rb28
-rw-r--r--app/graphql/resolvers/issues_resolver.rb3
-rw-r--r--app/graphql/resolvers/members_resolver.rb6
-rw-r--r--app/graphql/resolvers/merge_request_resolver.rb8
-rw-r--r--app/graphql/resolvers/merge_requests_resolver.rb39
-rw-r--r--app/graphql/resolvers/metrics/dashboard_resolver.rb9
-rw-r--r--app/graphql/resolvers/milestones_resolver.rb4
-rw-r--r--app/graphql/resolvers/package_details_resolver.rb10
-rw-r--r--app/graphql/resolvers/project_jobs_resolver.rb41
-rw-r--r--app/graphql/resolvers/project_pipeline_resolver.rb2
-rw-r--r--app/graphql/resolvers/projects/services_resolver.rb12
-rw-r--r--app/graphql/resolvers/repository_branch_names_resolver.rb17
-rw-r--r--app/graphql/resolvers/snippets/blobs_resolver.rb3
-rw-r--r--app/graphql/resolvers/timelog_resolver.rb112
-rw-r--r--app/graphql/resolvers/user_merge_requests_resolver_base.rb25
-rw-r--r--app/graphql/resolvers/user_starred_projects_resolver.rb6
-rw-r--r--app/graphql/resolvers/users/snippets_resolver.rb7
40 files changed, 560 insertions, 143 deletions
diff --git a/app/graphql/resolvers/alert_management/http_integrations_resolver.rb b/app/graphql/resolvers/alert_management/http_integrations_resolver.rb
index 94a72bca7c7..abc54614a59 100644
--- a/app/graphql/resolvers/alert_management/http_integrations_resolver.rb
+++ b/app/graphql/resolvers/alert_management/http_integrations_resolver.rb
@@ -3,19 +3,39 @@
module Resolvers
module AlertManagement
class HttpIntegrationsResolver < BaseResolver
- alias_method :project, :synchronized_object
+ include ::Gitlab::Graphql::Laziness
+
+ alias_method :project, :object
+
+ argument :id, Types::GlobalIDType[::AlertManagement::HttpIntegration],
+ required: false,
+ description: 'ID of the integration.'
type Types::AlertManagement::HttpIntegrationType.connection_type, null: true
- def resolve(**args)
- http_integrations
+ def resolve(id: nil)
+ return [] unless Ability.allowed?(current_user, :admin_operations, project)
+
+ if id
+ integrations_by(gid: id)
+ else
+ http_integrations
+ end
end
private
- def http_integrations
- return [] unless Ability.allowed?(current_user, :admin_operations, project)
+ def integrations_by(gid:)
+ id = Types::GlobalIDType[::AlertManagement::HttpIntegration].coerce_isolated_input(gid)
+ object = GitlabSchema.find_by_gid(id)
+
+ defer { object }.then do |integration|
+ ret = integration if project == integration&.project
+ Array.wrap(ret)
+ end
+ end
+ def http_integrations
::AlertManagement::HttpIntegrationsFinder.new(project, {}).execute
end
end
diff --git a/app/graphql/resolvers/alert_management/integrations_resolver.rb b/app/graphql/resolvers/alert_management/integrations_resolver.rb
index 4d1fe367277..cb7e73c2d1a 100644
--- a/app/graphql/resolvers/alert_management/integrations_resolver.rb
+++ b/app/graphql/resolvers/alert_management/integrations_resolver.rb
@@ -3,27 +3,60 @@
module Resolvers
module AlertManagement
class IntegrationsResolver < BaseResolver
- alias_method :project, :synchronized_object
+ include ::Gitlab::Graphql::Laziness
+
+ alias_method :project, :object
+
+ argument :id, ::Types::GlobalIDType,
+ required: false,
+ description: 'ID of the integration.'
type Types::AlertManagement::IntegrationType.connection_type, null: true
- def resolve(**args)
- http_integrations + prometheus_integrations
+ def resolve(id: nil)
+ if id
+ integrations_by(gid: id)
+ else
+ http_integrations + prometheus_integrations
+ end
end
private
+ def integrations_by(gid:)
+ object = GitlabSchema.object_from_id(gid, expected_type: expected_integration_types)
+ defer { object }.then do |integration|
+ ret = integration if project == integration&.project
+ Array.wrap(ret)
+ end
+ end
+
def prometheus_integrations
- return [] unless Ability.allowed?(current_user, :admin_project, project)
+ return [] unless prometheus_integrations_allowed?
Array(project.prometheus_service)
end
def http_integrations
- return [] unless Ability.allowed?(current_user, :admin_operations, project)
+ return [] unless http_integrations_allowed?
::AlertManagement::HttpIntegrationsFinder.new(project, {}).execute
end
+
+ def prometheus_integrations_allowed?
+ Ability.allowed?(current_user, :admin_project, project)
+ end
+
+ def http_integrations_allowed?
+ Ability.allowed?(current_user, :admin_operations, project)
+ end
+
+ def expected_integration_types
+ [].tap do |types|
+ types << ::AlertManagement::HttpIntegration if http_integrations_allowed?
+ types << ::PrometheusService if prometheus_integrations_allowed?
+ end
+ end
end
end
end
diff --git a/app/graphql/resolvers/base_resolver.rb b/app/graphql/resolvers/base_resolver.rb
index 67bba079512..48563633d11 100644
--- a/app/graphql/resolvers/base_resolver.rb
+++ b/app/graphql/resolvers/base_resolver.rb
@@ -39,9 +39,7 @@ module Resolvers
as_single << block
# Have we been called after defining the single version of this resolver?
- if @single.present?
- @single.instance_exec(&block)
- end
+ @single.instance_exec(&block) if @single.present?
end
def self.as_single
@@ -90,7 +88,7 @@ module Resolvers
def self.last
parent = self
- @last ||= Class.new(self.single) do
+ @last ||= Class.new(single) do
type parent.singular_type, null: true
def select_result(results)
@@ -138,16 +136,6 @@ module Resolvers
end
end
- # TODO: remove! This should never be necessary
- # Remove as part of https://gitlab.com/gitlab-org/gitlab/-/issues/13984,
- # since once we use that authorization approach, the object is guaranteed to
- # be synchronized before any field.
- def synchronized_object
- strong_memoize(:synchronized_object) do
- ::Gitlab::Graphql::Lazy.force(object)
- end
- end
-
def single?
false
end
@@ -160,5 +148,13 @@ module Resolvers
def select_result(results)
results
end
+
+ def self.authorization
+ @authorization ||= ::Gitlab::Graphql::Authorize::ObjectAuthorization.new(try(:required_permissions))
+ end
+
+ def self.authorized?(object, context)
+ authorization.ok?(object, context[:current_user])
+ end
end
end
diff --git a/app/graphql/resolvers/blobs_resolver.rb b/app/graphql/resolvers/blobs_resolver.rb
new file mode 100644
index 00000000000..d006769bd4b
--- /dev/null
+++ b/app/graphql/resolvers/blobs_resolver.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class BlobsResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ type Types::Tree::BlobType.connection_type, null: true
+ authorize :download_code
+ calls_gitaly!
+
+ alias_method :repository, :object
+
+ argument :paths, [GraphQL::STRING_TYPE],
+ required: true,
+ description: 'Array of desired blob paths.'
+ argument :ref, GraphQL::STRING_TYPE,
+ required: false,
+ default_value: nil,
+ description: 'The commit ref to get the blobs from. Default value is HEAD.'
+
+ # We fetch blobs from Gitaly efficiently but it still scales O(N) with the
+ # number of paths being fetched, so apply a scaling limit to that.
+ def self.resolver_complexity(args, child_complexity:)
+ super + (args[:paths] || []).size
+ end
+
+ def resolve(paths:, ref:)
+ authorize!(repository.container)
+
+ return [] if repository.empty?
+
+ ref ||= repository.root_ref
+
+ repository.blobs_at(paths.map { |path| [ref, path] })
+ end
+ end
+end
diff --git a/app/graphql/resolvers/board_lists_resolver.rb b/app/graphql/resolvers/board_lists_resolver.rb
index e66f7b97b40..0b699006626 100644
--- a/app/graphql/resolvers/board_lists_resolver.rb
+++ b/app/graphql/resolvers/board_lists_resolver.rb
@@ -3,13 +3,12 @@
module Resolvers
class BoardListsResolver < BaseResolver
include BoardIssueFilterable
- prepend ManualAuthorization
include Gitlab::Graphql::Authorize::AuthorizeResource
+ include LooksAhead
type Types::BoardListType, null: true
- extras [:lookahead]
-
authorize :read_issue_board_list
+ authorizes_object!
argument :id, Types::GlobalIDType[List],
required: false,
@@ -21,15 +20,11 @@ module Resolvers
alias_method :board, :object
- def resolve(lookahead: nil, id: nil, issue_filters: {})
- authorize!(board)
-
+ def resolve_with_lookahead(id: nil, issue_filters: {})
lists = board_lists(id)
context.scoped_set!(:issue_filters, issue_filters(issue_filters))
- if load_preferences?(lookahead)
- List.preload_preferences_for_user(lists, current_user)
- end
+ List.preload_preferences_for_user(lists, current_user) if load_preferences?
offset_pagination(lists)
end
@@ -46,9 +41,8 @@ module Resolvers
service.execute(board, create_default_lists: false)
end
- def load_preferences?(lookahead)
- lookahead&.selection(:edges)&.selection(:node)&.selects?(:collapsed) ||
- lookahead&.selection(:nodes)&.selects?(:collapsed)
+ def load_preferences?
+ node_selection&.selects?(:collapsed)
end
def extract_list_id(gid)
diff --git a/app/graphql/resolvers/board_resolver.rb b/app/graphql/resolvers/board_resolver.rb
index 637d690e4cd..85362ab1422 100644
--- a/app/graphql/resolvers/board_resolver.rb
+++ b/app/graphql/resolvers/board_resolver.rb
@@ -2,7 +2,7 @@
module Resolvers
class BoardResolver < BaseResolver.single
- alias_method :parent, :synchronized_object
+ alias_method :parent, :object
type Types::BoardType, null: true
diff --git a/app/graphql/resolvers/ci/config_resolver.rb b/app/graphql/resolvers/ci/config_resolver.rb
index f8670649e48..252c9d3acf0 100644
--- a/app/graphql/resolvers/ci/config_resolver.rb
+++ b/app/graphql/resolvers/ci/config_resolver.rb
@@ -7,6 +7,10 @@ module Resolvers
include ResolvesProject
type Types::Ci::Config::ConfigType, null: true
+ description <<~MD
+ Linted and processed contents of a CI config.
+ Should not be requested more than once per request.
+ MD
authorize :read_pipeline
@@ -55,7 +59,7 @@ module Resolvers
name: job[:name],
stage: job[:stage],
group_name: CommitStatus.new(name: job[:name]).group_name,
- needs: job.dig(:needs) || [],
+ needs: job[:needs] || [],
allow_failure: job[:allow_failure],
before_script: job[:before_script],
script: job[:script],
diff --git a/app/graphql/resolvers/ci/jobs_resolver.rb b/app/graphql/resolvers/ci/jobs_resolver.rb
index dd565094017..5ae9e721cc8 100644
--- a/app/graphql/resolvers/ci/jobs_resolver.rb
+++ b/app/graphql/resolvers/ci/jobs_resolver.rb
@@ -11,7 +11,18 @@ module Resolvers
required: false,
description: 'Filter jobs by the type of security report they produce.'
- def resolve(security_report_types: [])
+ argument :statuses, [::Types::Ci::JobStatusEnum],
+ required: false,
+ description: 'Filter jobs by status.'
+
+ def resolve(statuses: nil, security_report_types: [])
+ jobs = init_collection(security_report_types)
+ jobs = jobs.with_status(statuses) if statuses.present?
+
+ jobs
+ end
+
+ def init_collection(security_report_types)
if security_report_types.present?
::Security::SecurityJobsFinder.new(
pipeline: pipeline,
diff --git a/app/graphql/resolvers/ci/pipeline_stages_resolver.rb b/app/graphql/resolvers/ci/pipeline_stages_resolver.rb
index 98170e0cd2e..a458e873935 100644
--- a/app/graphql/resolvers/ci/pipeline_stages_resolver.rb
+++ b/app/graphql/resolvers/ci/pipeline_stages_resolver.rb
@@ -16,7 +16,7 @@ module Resolvers
def preloads
{
- statuses: [:needs]
+ jobs: { latest_statuses: [:needs] }
}
end
end
diff --git a/app/graphql/resolvers/ci/runner_platforms_resolver.rb b/app/graphql/resolvers/ci/runner_platforms_resolver.rb
index 9677c5139b4..f120e94b67b 100644
--- a/app/graphql/resolvers/ci/runner_platforms_resolver.rb
+++ b/app/graphql/resolvers/ci/runner_platforms_resolver.rb
@@ -3,7 +3,8 @@
module Resolvers
module Ci
class RunnerPlatformsResolver < BaseResolver
- type Types::Ci::RunnerPlatformType, null: false
+ type Types::Ci::RunnerPlatformType.connection_type, null: true
+ description 'Supported runner platforms.'
def resolve(**args)
runner_instructions.map do |platform, data|
diff --git a/app/graphql/resolvers/ci/runner_setup_resolver.rb b/app/graphql/resolvers/ci/runner_setup_resolver.rb
index ac2a56b89a7..9166999b400 100644
--- a/app/graphql/resolvers/ci/runner_setup_resolver.rb
+++ b/app/graphql/resolvers/ci/runner_setup_resolver.rb
@@ -3,30 +3,37 @@
module Resolvers
module Ci
class RunnerSetupResolver < BaseResolver
+ ACCESS_DENIED = 'User is not authorized to register a runner for the specified resource!'
+
type Types::Ci::RunnerSetupType, null: true
+ description 'Runner setup instructions.'
- argument :platform, GraphQL::STRING_TYPE,
- required: true,
- description: 'Platform to generate the instructions for.'
+ argument :platform,
+ type: GraphQL::STRING_TYPE,
+ required: true,
+ description: 'Platform to generate the instructions for.'
- argument :architecture, GraphQL::STRING_TYPE,
- required: true,
- description: 'Architecture to generate the instructions for.'
+ argument :architecture,
+ type: GraphQL::STRING_TYPE,
+ required: true,
+ description: 'Architecture to generate the instructions for.'
- argument :project_id, ::Types::GlobalIDType[::Project],
- required: false,
- description: 'Project to register the runner for.'
+ argument :project_id,
+ type: ::Types::GlobalIDType[::Project],
+ required: false,
+ deprecated: { reason: 'No longer used', milestone: '13.11' },
+ description: 'Project to register the runner for.'
- argument :group_id, ::Types::GlobalIDType[::Group],
- required: false,
- description: 'Group to register the runner for.'
+ argument :group_id,
+ type: ::Types::GlobalIDType[::Group],
+ required: false,
+ deprecated: { reason: 'No longer used', milestone: '13.11' },
+ description: 'Group to register the runner for.'
def resolve(platform:, architecture:, **args)
instructions = Gitlab::Ci::RunnerInstructions.new(
- current_user: current_user,
os: platform,
- arch: architecture,
- **target_param(args)
+ arch: architecture
)
{
@@ -34,11 +41,15 @@ module Resolvers
register_instructions: instructions.register_command
}
ensure
- raise Gitlab::Graphql::Errors::ResourceNotAvailable, 'User is not authorized to register a runner for the specified resource!' if instructions.errors.include?('Gitlab::Access::AccessDeniedError')
+ raise Gitlab::Graphql::Errors::ResourceNotAvailable, ACCESS_DENIED if access_denied?(instructions)
end
private
+ def access_denied?(instructions)
+ instructions.errors.include?('Gitlab::Access::AccessDeniedError')
+ end
+
def other_install_instructions(platform)
Gitlab::Ci::RunnerInstructions::OTHER_ENVIRONMENTS[platform.to_sym][:installation_instructions_url]
end
diff --git a/app/graphql/resolvers/ci/test_report_summary_resolver.rb b/app/graphql/resolvers/ci/test_report_summary_resolver.rb
new file mode 100644
index 00000000000..22db70f032a
--- /dev/null
+++ b/app/graphql/resolvers/ci/test_report_summary_resolver.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Ci
+ class TestReportSummaryResolver < BaseResolver
+ type ::Types::Ci::TestReportSummaryType, null: true
+
+ alias_method :pipeline, :object
+
+ def resolve(**args)
+ TestReportSummarySerializer
+ .new(project: pipeline.project, current_user: @current_user)
+ .represent(pipeline.test_report_summary)
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/ci/test_suite_resolver.rb b/app/graphql/resolvers/ci/test_suite_resolver.rb
new file mode 100644
index 00000000000..90cc30b1281
--- /dev/null
+++ b/app/graphql/resolvers/ci/test_suite_resolver.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+module Resolvers
+ module Ci
+ class TestSuiteResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+
+ type ::Types::Ci::TestSuiteType, null: true
+ authorize :read_build
+ authorizes_object!
+
+ alias_method :pipeline, :object
+
+ argument :build_ids, [GraphQL::ID_TYPE],
+ required: true,
+ description: 'IDs of the builds used to run the test suite.'
+
+ def resolve(build_ids:)
+ builds = pipeline.latest_builds.id_in(build_ids).presence
+ return unless builds
+
+ TestSuiteSerializer
+ .new(project: pipeline.project, current_user: @current_user)
+ .represent(load_test_suite_data(builds), details: true)
+ end
+
+ private
+
+ def load_test_suite_data(builds)
+ suite = builds.sum do |build|
+ build.collect_test_reports!(Gitlab::Ci::Reports::TestReports.new)
+ end
+
+ Gitlab::Ci::Reports::TestFailureHistory.new(suite.failed.values, pipeline.project).load!
+
+ suite
+ end
+ end
+ end
+end
diff --git a/app/graphql/resolvers/concerns/board_issue_filterable.rb b/app/graphql/resolvers/concerns/board_issue_filterable.rb
index 1541738f46c..3484a1cc4ba 100644
--- a/app/graphql/resolvers/concerns/board_issue_filterable.rb
+++ b/app/graphql/resolvers/concerns/board_issue_filterable.rb
@@ -7,10 +7,10 @@ module BoardIssueFilterable
def issue_filters(args)
filters = args.to_h
+
set_filter_values(filters)
if filters[:not]
- filters[:not] = filters[:not].to_h
set_filter_values(filters[:not])
end
@@ -18,6 +18,17 @@ module BoardIssueFilterable
end
def set_filter_values(filters)
+ filter_by_assignee(filters)
+ end
+
+ def filter_by_assignee(filters)
+ if filters[:assignee_username] && filters[:assignee_wildcard_id]
+ raise ::Gitlab::Graphql::Errors::ArgumentError, 'Incompatible arguments: assigneeUsername, assigneeWildcardId.'
+ end
+
+ if filters[:assignee_wildcard_id]
+ filters[:assignee_id] = filters.delete(:assignee_wildcard_id)
+ end
end
end
diff --git a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
index 84b0dafe213..0ff3997f3bc 100644
--- a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
+++ b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb
@@ -12,10 +12,10 @@ module IssueResolverArguments
argument :iids, [GraphQL::STRING_TYPE],
required: false,
description: 'List of IIDs of issues. For example, [1, 2].'
- argument :label_name, GraphQL::STRING_TYPE.to_list_type,
+ argument :label_name, [GraphQL::STRING_TYPE, null: true],
required: false,
description: 'Labels applied to this issue.'
- argument :milestone_title, GraphQL::STRING_TYPE.to_list_type,
+ argument :milestone_title, [GraphQL::STRING_TYPE, null: true],
required: false,
description: 'Milestone applied to this issue.'
argument :author_username, GraphQL::STRING_TYPE,
@@ -23,7 +23,8 @@ module IssueResolverArguments
description: 'Username of the author of the issue.'
argument :assignee_username, GraphQL::STRING_TYPE,
required: false,
- description: 'Username of a user assigned to the issue.'
+ description: 'Username of a user assigned to the issue.',
+ deprecated: { reason: 'Use `assigneeUsernames`', milestone: '13.11' }
argument :assignee_usernames, [GraphQL::STRING_TYPE],
required: false,
description: 'Usernames of users assigned to the issue.'
@@ -55,6 +56,10 @@ module IssueResolverArguments
as: :issue_types,
description: 'Filter issues by the given issue types.',
required: false
+ argument :not, Types::Issues::NegatedIssueFilterInputType,
+ description: 'List of negated params.',
+ prepare: ->(negated_args, ctx) { negated_args.to_h },
+ required: false
end
def resolve_with_lookahead(**args)
@@ -69,11 +74,22 @@ module IssueResolverArguments
args[:iids] ||= [args.delete(:iid)].compact if args[:iid]
args[:attempt_project_search_optimizations] = true if args[:search].present?
+ prepare_assignee_username_params(args)
+
finder = IssuesFinder.new(current_user, args)
continue_issue_resolve(parent, finder, **args)
end
+ def ready?(**args)
+ if args.slice(*mutually_exclusive_assignee_username_args).compact.size > 1
+ arg_str = mutually_exclusive_assignee_username_args.map { |x| x.to_s.camelize(:lower) }.join(', ')
+ raise Gitlab::Graphql::Errors::ArgumentError, "only one of [#{arg_str}] arguments is allowed at the same time."
+ end
+
+ super
+ end
+
class_methods do
def resolver_complexity(args, child_complexity:)
complexity = super
@@ -82,4 +98,15 @@ module IssueResolverArguments
complexity
end
end
+
+ private
+
+ def prepare_assignee_username_params(args)
+ args[:assignee_username] = args.delete(:assignee_usernames) if args[:assignee_usernames].present?
+ args[:not][:assignee_username] = args[:not].delete(:assignee_usernames) if args.dig(:not, :assignee_usernames).present?
+ end
+
+ def mutually_exclusive_assignee_username_args
+ [:assignee_usernames, :assignee_username]
+ end
end
diff --git a/app/graphql/resolvers/concerns/looks_ahead.rb b/app/graphql/resolvers/concerns/looks_ahead.rb
index 77a85edfba6..644b2a11460 100644
--- a/app/graphql/resolvers/concerns/looks_ahead.rb
+++ b/app/graphql/resolvers/concerns/looks_ahead.rb
@@ -15,12 +15,7 @@ module LooksAhead
end
def apply_lookahead(query)
- selection = node_selection
-
- includes = preloads.each.flat_map do |name, requirements|
- selection&.selects?(name) ? requirements : []
- end
- all_preloads = (unconditional_includes + includes).uniq
+ all_preloads = (unconditional_includes + filtered_preloads).uniq
return query if all_preloads.empty?
@@ -37,6 +32,14 @@ module LooksAhead
{}
end
+ def filtered_preloads
+ selection = node_selection
+
+ preloads.each.flat_map do |name, requirements|
+ selection&.selects?(name) ? requirements : []
+ end
+ end
+
def node_selection
return unless lookahead
diff --git a/app/graphql/resolvers/concerns/manual_authorization.rb b/app/graphql/resolvers/concerns/manual_authorization.rb
deleted file mode 100644
index 182110b9594..00000000000
--- a/app/graphql/resolvers/concerns/manual_authorization.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-# frozen_string_literal: true
-
-# TODO: remove this entirely when framework authorization is released
-# See: https://gitlab.com/gitlab-org/gitlab/-/issues/290216
-module ManualAuthorization
- def resolve(**args)
- super
- rescue ::Gitlab::Graphql::Errors::ResourceNotAvailable
- nil
- end
-end
diff --git a/app/graphql/resolvers/concerns/resolves_merge_requests.rb b/app/graphql/resolvers/concerns/resolves_merge_requests.rb
index 31444b0c592..75f1ee478a8 100644
--- a/app/graphql/resolvers/concerns/resolves_merge_requests.rb
+++ b/app/graphql/resolvers/concerns/resolves_merge_requests.rb
@@ -50,7 +50,8 @@ module ResolvesMergeRequests
approved_by: [:approved_by_users],
milestone: [:milestone],
security_auto_fix: [:author],
- head_pipeline: [:merge_request_diff, { head_pipeline: [:merge_request] }]
+ head_pipeline: [:merge_request_diff, { head_pipeline: [:merge_request] }],
+ timelogs: [:timelogs]
}
end
end
diff --git a/app/graphql/resolvers/concerns/resolves_snippets.rb b/app/graphql/resolvers/concerns/resolves_snippets.rb
index 445f3567b1d..8de85c074ec 100644
--- a/app/graphql/resolvers/concerns/resolves_snippets.rb
+++ b/app/graphql/resolvers/concerns/resolves_snippets.rb
@@ -4,7 +4,7 @@ module ResolvesSnippets
extend ActiveSupport::Concern
included do
- type Types::SnippetType.connection_type, null: false
+ type Types::SnippetType.connection_type, null: true
argument :ids, [::Types::GlobalIDType[::Snippet]],
required: false,
diff --git a/app/graphql/resolvers/echo_resolver.rb b/app/graphql/resolvers/echo_resolver.rb
index 0c7dad622cf..a09b0a1fd87 100644
--- a/app/graphql/resolvers/echo_resolver.rb
+++ b/app/graphql/resolvers/echo_resolver.rb
@@ -5,8 +5,10 @@ module Resolvers
type ::GraphQL::STRING_TYPE, null: false
description 'Testing endpoint to validate the API with'
- argument :text, GraphQL::STRING_TYPE, required: true,
- description: 'Text to echo back.'
+ argument :text,
+ type: GraphQL::STRING_TYPE,
+ required: true,
+ description: 'Text to echo back.'
def resolve(text:)
username = current_user&.username
diff --git a/app/graphql/resolvers/environments_resolver.rb b/app/graphql/resolvers/environments_resolver.rb
index ed3395d05aa..df04e70e250 100644
--- a/app/graphql/resolvers/environments_resolver.rb
+++ b/app/graphql/resolvers/environments_resolver.rb
@@ -21,7 +21,7 @@ module Resolvers
def resolve(**args)
return unless project.present?
- EnvironmentsFinder.new(project, context[:current_user], args).find
+ EnvironmentsFinder.new(project, context[:current_user], args).execute
rescue EnvironmentsFinder::InvalidStatesError => exception
raise Gitlab::Graphql::Errors::ArgumentError, exception.message
end
diff --git a/app/graphql/resolvers/group_members_resolver.rb b/app/graphql/resolvers/group_members_resolver.rb
index 36e1977b756..d3662b08cdf 100644
--- a/app/graphql/resolvers/group_members_resolver.rb
+++ b/app/graphql/resolvers/group_members_resolver.rb
@@ -13,12 +13,6 @@ module Resolvers
private
- def preloads
- {
- user: [:user, :source]
- }
- end
-
def finder_class
GroupMembersFinder
end
diff --git a/app/graphql/resolvers/group_merge_requests_resolver.rb b/app/graphql/resolvers/group_merge_requests_resolver.rb
index 2bad974daf7..34a4c67bc56 100644
--- a/app/graphql/resolvers/group_merge_requests_resolver.rb
+++ b/app/graphql/resolvers/group_merge_requests_resolver.rb
@@ -4,7 +4,7 @@ module Resolvers
class GroupMergeRequestsResolver < MergeRequestsResolver
include GroupIssuableResolver
- alias_method :group, :synchronized_object
+ alias_method :group, :object
type Types::MergeRequestType.connection_type, null: true
diff --git a/app/graphql/resolvers/group_milestones_resolver.rb b/app/graphql/resolvers/group_milestones_resolver.rb
index 179283fd7b7..31280b36278 100644
--- a/app/graphql/resolvers/group_milestones_resolver.rb
+++ b/app/graphql/resolvers/group_milestones_resolver.rb
@@ -1,22 +1,40 @@
# frozen_string_literal: true
-# rubocop:disable Graphql/ResolverType (inherited from MilestonesResolver)
module Resolvers
class GroupMilestonesResolver < MilestonesResolver
argument :include_descendants, GraphQL::BOOLEAN_TYPE,
required: false,
- description: 'Also return milestones in all subgroups and subprojects.'
+ description: 'Include milestones from all subgroups and subprojects.'
+ argument :include_ancestors, GraphQL::BOOLEAN_TYPE,
+ required: false,
+ description: 'Include milestones from all parent groups.'
type Types::MilestoneType.connection_type, null: true
private
def parent_id_parameters(args)
- return { group_ids: parent.id } unless args[:include_descendants].present?
+ include_ancestors = args[:include_ancestors].present?
+ include_descendants = args[:include_descendants].present?
+ return { group_ids: parent.id } unless include_ancestors || include_descendants
+
+ group_ids = if include_ancestors && include_descendants
+ parent.self_and_hierarchy
+ elsif include_ancestors
+ parent.self_and_ancestors
+ else
+ parent.self_and_descendants
+ end
+
+ project_ids = if include_descendants
+ group_projects.with_issues_or_mrs_available_for_user(current_user)
+ else
+ nil
+ end
{
- group_ids: parent.self_and_descendants.public_or_visible_to_user(current_user).select(:id),
- project_ids: group_projects.with_issues_or_mrs_available_for_user(current_user)
+ group_ids: group_ids.public_or_visible_to_user(current_user).select(:id),
+ project_ids: project_ids
}
end
diff --git a/app/graphql/resolvers/issues_resolver.rb b/app/graphql/resolvers/issues_resolver.rb
index ac3bdda0f12..7a67f115abf 100644
--- a/app/graphql/resolvers/issues_resolver.rb
+++ b/app/graphql/resolvers/issues_resolver.rb
@@ -44,7 +44,8 @@ module Resolvers
{
alert_management_alert: [:alert_management_alert],
labels: [:labels],
- assignees: [:assignees]
+ assignees: [:assignees],
+ timelogs: [:timelogs]
}
end
diff --git a/app/graphql/resolvers/members_resolver.rb b/app/graphql/resolvers/members_resolver.rb
index 76c3ae936ee..2b731d54cdd 100644
--- a/app/graphql/resolvers/members_resolver.rb
+++ b/app/graphql/resolvers/members_resolver.rb
@@ -21,6 +21,12 @@ module Resolvers
private
+ def preloads
+ {
+ user: [:user, :source]
+ }
+ end
+
def finder_class
# override in subclass
end
diff --git a/app/graphql/resolvers/merge_request_resolver.rb b/app/graphql/resolvers/merge_request_resolver.rb
index 8fd33c6626e..c431d079beb 100644
--- a/app/graphql/resolvers/merge_request_resolver.rb
+++ b/app/graphql/resolvers/merge_request_resolver.rb
@@ -4,14 +4,14 @@ module Resolvers
class MergeRequestResolver < BaseResolver.single
include ResolvesMergeRequests
- alias_method :project, :synchronized_object
+ alias_method :project, :object
type ::Types::MergeRequestType, null: true
argument :iid, GraphQL::STRING_TYPE,
- required: true,
- as: :iids,
- description: 'IID of the merge request, for example `1`.'
+ required: true,
+ as: :iids,
+ description: 'IID of the merge request, for example `1`.'
def no_results_possible?(args)
project.nil?
diff --git a/app/graphql/resolvers/merge_requests_resolver.rb b/app/graphql/resolvers/merge_requests_resolver.rb
index ecbdaaa3f55..a9eea4ae4b8 100644
--- a/app/graphql/resolvers/merge_requests_resolver.rb
+++ b/app/graphql/resolvers/merge_requests_resolver.rb
@@ -3,42 +3,49 @@
module Resolvers
class MergeRequestsResolver < BaseResolver
include ResolvesMergeRequests
+ extend ::Gitlab::Graphql::NegatableArguments
type ::Types::MergeRequestType.connection_type, null: true
- alias_method :project, :synchronized_object
+ alias_method :project, :object
def self.accept_assignee
argument :assignee_username, GraphQL::STRING_TYPE,
- required: false,
- description: 'Username of the assignee.'
+ required: false,
+ description: 'Username of the assignee.'
end
def self.accept_author
argument :author_username, GraphQL::STRING_TYPE,
- required: false,
- description: 'Username of the author.'
+ required: false,
+ description: 'Username of the author.'
end
def self.accept_reviewer
argument :reviewer_username, GraphQL::STRING_TYPE,
- required: false,
- description: 'Username of the reviewer.'
+ required: false,
+ description: 'Username of the reviewer.'
end
argument :iids, [GraphQL::STRING_TYPE],
- required: false,
- description: 'Array of IIDs of merge requests, for example `[1, 2]`.'
+ required: false,
+ description: 'Array of IIDs of merge requests, for example `[1, 2]`.'
argument :source_branches, [GraphQL::STRING_TYPE],
required: false,
as: :source_branch,
- description: 'Array of source branch names. All resolved merge requests will have one of these branches as their source.'
+ description: <<~DESC
+ Array of source branch names.
+ All resolved merge requests will have one of these branches as their source.
+ DESC
argument :target_branches, [GraphQL::STRING_TYPE],
required: false,
as: :target_branch,
- description: 'Array of target branch names. All resolved merge requests will have one of these branches as their target.'
+ description: <<~DESC
+ Array of target branch names.
+ All resolved merge requests will have one of these branches as their target.
+ DESC
argument :state, ::Types::MergeRequestStateEnum,
required: false,
@@ -62,6 +69,16 @@ module Resolvers
required: false,
default_value: :created_desc
+ negated do
+ argument :labels, [GraphQL::STRING_TYPE],
+ required: false,
+ as: :label_name,
+ description: 'Array of label names. All resolved merge requests will not have these labels.'
+ argument :milestone_title, GraphQL::STRING_TYPE,
+ required: false,
+ description: 'Title of the milestone.'
+ end
+
def self.single
::Resolvers::MergeRequestResolver
end
diff --git a/app/graphql/resolvers/metrics/dashboard_resolver.rb b/app/graphql/resolvers/metrics/dashboard_resolver.rb
index a82a4a95254..0669fececd5 100644
--- a/app/graphql/resolvers/metrics/dashboard_resolver.rb
+++ b/app/graphql/resolvers/metrics/dashboard_resolver.rb
@@ -8,15 +8,16 @@ module Resolvers
argument :path, GraphQL::STRING_TYPE,
required: true,
- description: "Path to a file which defines metrics dashboard " \
- "eg: 'config/prometheus/common_metrics.yml'."
+ description: <<~MD
+ Path to a file which defines a metrics dashboard eg: `"config/prometheus/common_metrics.yml"`.
+ MD
alias_method :environment, :object
- def resolve(**args)
+ def resolve(path:)
return unless environment
- ::PerformanceMonitoring::PrometheusDashboard.find_for(**args, **service_params)
+ ::PerformanceMonitoring::PrometheusDashboard.find_for(path: path, **service_params)
end
private
diff --git a/app/graphql/resolvers/milestones_resolver.rb b/app/graphql/resolvers/milestones_resolver.rb
index 9a715e4d08b..c94e3d9e1d8 100644
--- a/app/graphql/resolvers/milestones_resolver.rb
+++ b/app/graphql/resolvers/milestones_resolver.rb
@@ -7,7 +7,7 @@ module Resolvers
argument :ids, [GraphQL::ID_TYPE],
required: false,
- description: 'Array of global milestone IDs, e.g., "gid://gitlab/Milestone/1".'
+ description: 'Array of global milestone IDs, e.g., `"gid://gitlab/Milestone/1"`.'
argument :state, Types::MilestoneStateEnum,
required: false,
@@ -56,7 +56,7 @@ module Resolvers
end
def parent
- synchronized_object
+ object
end
def parent_id_parameters(args)
diff --git a/app/graphql/resolvers/package_details_resolver.rb b/app/graphql/resolvers/package_details_resolver.rb
index e688e34599a..89d79747732 100644
--- a/app/graphql/resolvers/package_details_resolver.rb
+++ b/app/graphql/resolvers/package_details_resolver.rb
@@ -2,12 +2,20 @@
module Resolvers
class PackageDetailsResolver < BaseResolver
- type ::Types::Packages::PackageType, null: true
+ type ::Types::Packages::PackageDetailsType, null: true
argument :id, ::Types::GlobalIDType[::Packages::Package],
required: true,
description: 'The global ID of the package.'
+ def ready?(**args)
+ context[self.class] ||= { executions: 0 }
+ context[self.class][:executions] += 1
+ raise GraphQL::ExecutionError, "Package details can be requested only for one package at a time" if context[self.class][:executions] > 1
+
+ super
+ end
+
def resolve(id:)
# TODO: remove this line when the compatibility layer is removed
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
diff --git a/app/graphql/resolvers/project_jobs_resolver.rb b/app/graphql/resolvers/project_jobs_resolver.rb
new file mode 100644
index 00000000000..75068014242
--- /dev/null
+++ b/app/graphql/resolvers/project_jobs_resolver.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class ProjectJobsResolver < BaseResolver
+ include Gitlab::Graphql::Authorize::AuthorizeResource
+ include LooksAhead
+
+ type ::Types::Ci::JobType.connection_type, null: true
+ authorize :read_build
+ authorizes_object!
+
+ argument :statuses, [::Types::Ci::JobStatusEnum],
+ required: false,
+ description: 'Filter jobs by status.'
+
+ alias_method :project, :object
+
+ def ready?(**args)
+ context[self.class] ||= { executions: 0 }
+ context[self.class][:executions] += 1
+ raise GraphQL::ExecutionError, "Jobs can only be requested for one project at a time" if context[self.class][:executions] > 1
+
+ super
+ end
+
+ def resolve_with_lookahead(statuses: nil)
+ jobs = ::Ci::JobsFinder.new(current_user: current_user, project: project, params: { scope: statuses }).execute
+
+ apply_lookahead(jobs)
+ end
+
+ private
+
+ def preloads
+ {
+ artifacts: [:job_artifacts],
+ pipeline: [:user]
+ }
+ end
+ end
+end
diff --git a/app/graphql/resolvers/project_pipeline_resolver.rb b/app/graphql/resolvers/project_pipeline_resolver.rb
index 8fca6b829c0..aa8808b15ac 100644
--- a/app/graphql/resolvers/project_pipeline_resolver.rb
+++ b/app/graphql/resolvers/project_pipeline_resolver.rb
@@ -31,7 +31,7 @@ module Resolvers
end
else
BatchLoader::GraphQL.for(sha).batch(key: project) do |shas, loader, args|
- finder = ::Ci::PipelinesFinder.new(project, current_user, shas: shas)
+ finder = ::Ci::PipelinesFinder.new(project, current_user, sha: shas)
finder.execute.each { |pipeline| loader.call(pipeline.sha.to_s, pipeline) }
end
diff --git a/app/graphql/resolvers/projects/services_resolver.rb b/app/graphql/resolvers/projects/services_resolver.rb
index f618bf2df77..ec31a7dbe6d 100644
--- a/app/graphql/resolvers/projects/services_resolver.rb
+++ b/app/graphql/resolvers/projects/services_resolver.rb
@@ -3,11 +3,11 @@
module Resolvers
module Projects
class ServicesResolver < BaseResolver
- prepend ManualAuthorization
include Gitlab::Graphql::Authorize::AuthorizeResource
type Types::Projects::ServiceType.connection_type, null: true
authorize :admin_project
+ authorizes_object!
argument :active,
GraphQL::BOOLEAN_TYPE,
@@ -20,15 +20,7 @@ module Resolvers
alias_method :project, :object
- def resolve(**args)
- authorize!(project)
-
- services(args[:active], args[:type])
- end
-
- private
-
- def services(active, type)
+ def resolve(active: nil, type: nil)
servs = project.services
servs = servs.by_active_flag(active) unless active.nil?
servs = servs.by_type(type) unless type.blank?
diff --git a/app/graphql/resolvers/repository_branch_names_resolver.rb b/app/graphql/resolvers/repository_branch_names_resolver.rb
new file mode 100644
index 00000000000..45cfe229b2f
--- /dev/null
+++ b/app/graphql/resolvers/repository_branch_names_resolver.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class RepositoryBranchNamesResolver < BaseResolver
+ type ::GraphQL::STRING_TYPE, null: false
+
+ calls_gitaly!
+
+ argument :search_pattern, GraphQL::STRING_TYPE,
+ required: true,
+ description: 'The pattern to search for branch names by.'
+
+ def resolve(search_pattern:)
+ Repositories::BranchNamesFinder.new(object, search: search_pattern).execute
+ end
+ end
+end
diff --git a/app/graphql/resolvers/snippets/blobs_resolver.rb b/app/graphql/resolvers/snippets/blobs_resolver.rb
index 569b82149d3..4328d38d485 100644
--- a/app/graphql/resolvers/snippets/blobs_resolver.rb
+++ b/app/graphql/resolvers/snippets/blobs_resolver.rb
@@ -3,12 +3,12 @@
module Resolvers
module Snippets
class BlobsResolver < BaseResolver
- prepend ManualAuthorization
include Gitlab::Graphql::Authorize::AuthorizeResource
type Types::Snippets::BlobType.connection_type, null: true
authorize :read_snippet
calls_gitaly!
+ authorizes_object!
alias_method :snippet, :object
@@ -17,7 +17,6 @@ module Resolvers
description: 'Paths of the blobs.'
def resolve(paths: [])
- authorize!(snippet)
return [snippet.blob] if snippet.empty_repo?
if paths.empty?
diff --git a/app/graphql/resolvers/timelog_resolver.rb b/app/graphql/resolvers/timelog_resolver.rb
new file mode 100644
index 00000000000..aebd04259ee
--- /dev/null
+++ b/app/graphql/resolvers/timelog_resolver.rb
@@ -0,0 +1,112 @@
+# frozen_string_literal: true
+
+module Resolvers
+ class TimelogResolver < BaseResolver
+ include LooksAhead
+
+ type ::Types::TimelogType.connection_type, null: false
+
+ argument :start_date, Types::TimeType,
+ required: false,
+ description: 'List time logs within a date range where the logged date is equal to or after startDate.'
+
+ argument :end_date, Types::TimeType,
+ required: false,
+ description: 'List time logs within a date range where the logged date is equal to or before endDate.'
+
+ argument :start_time, Types::TimeType,
+ required: false,
+ description: 'List time-logs within a time range where the logged time is equal to or after startTime.'
+
+ argument :end_time, Types::TimeType,
+ required: false,
+ description: 'List time-logs within a time range where the logged time is equal to or before endTime.'
+
+ def resolve_with_lookahead(**args)
+ return Timelog.none unless timelogs_available_for_user?
+
+ validate_params_presence!(args)
+ transformed_args = transform_args(args)
+ validate_time_difference!(transformed_args)
+
+ find_timelogs(transformed_args)
+ end
+
+ private
+
+ def preloads
+ {
+ note: [:note]
+ }
+ end
+
+ def find_timelogs(args)
+ apply_lookahead(group.timelogs(args[:start_time], args[:end_time]))
+ end
+
+ def timelogs_available_for_user?
+ group&.user_can_access_group_timelogs?(context[:current_user])
+ end
+
+ def validate_params_presence!(args)
+ message = case time_params_count(args)
+ when 0
+ 'Start and End arguments must be present'
+ when 1
+ 'Both Start and End arguments must be present'
+ when 2
+ validate_duplicated_args(args)
+ when 3 || 4
+ 'Only Time or Date arguments must be present'
+ end
+
+ raise_argument_error(message) if message
+ end
+
+ def validate_time_difference!(args)
+ message = if args[:end_time] < args[:start_time]
+ 'Start argument must be before End argument'
+ elsif args[:end_time] - args[:start_time] > 60.days
+ 'The time range period cannot contain more than 60 days'
+ end
+
+ raise_argument_error(message) if message
+ end
+
+ def transform_args(args)
+ return args if args.keys == [:start_time, :end_time]
+
+ time_args = args.except(:start_date, :end_date)
+
+ if time_args.empty?
+ time_args[:start_time] = args[:start_date].beginning_of_day
+ time_args[:end_time] = args[:end_date].end_of_day
+ elsif time_args.key?(:start_time)
+ time_args[:end_time] = args[:end_date].end_of_day
+ elsif time_args.key?(:end_time)
+ time_args[:start_time] = args[:start_date].beginning_of_day
+ end
+
+ time_args
+ end
+
+ def time_params_count(args)
+ [:start_time, :end_time, :start_date, :end_date].count { |param| args.key?(param) }
+ end
+
+ def validate_duplicated_args(args)
+ if args.key?(:start_time) && args.key?(:start_date) ||
+ args.key?(:end_time) && args.key?(:end_date)
+ 'Both Start and End arguments must be present'
+ end
+ end
+
+ def raise_argument_error(message)
+ raise Gitlab::Graphql::Errors::ArgumentError, message
+ end
+
+ def group
+ @group ||= object.respond_to?(:sync) ? object.sync : object
+ end
+ end
+end
diff --git a/app/graphql/resolvers/user_merge_requests_resolver_base.rb b/app/graphql/resolvers/user_merge_requests_resolver_base.rb
index 47967fe69f9..221a43f691d 100644
--- a/app/graphql/resolvers/user_merge_requests_resolver_base.rb
+++ b/app/graphql/resolvers/user_merge_requests_resolver_base.rb
@@ -4,16 +4,24 @@ module Resolvers
class UserMergeRequestsResolverBase < MergeRequestsResolver
include ResolvesProject
- argument :project_path, GraphQL::STRING_TYPE,
- required: false,
- description: 'The full-path of the project the authored merge requests should be in. Incompatible with projectId.'
+ argument :project_path,
+ type: GraphQL::STRING_TYPE,
+ required: false,
+ description: <<~DESC
+ The full-path of the project the authored merge requests should be in.
+ Incompatible with projectId.
+ DESC
- argument :project_id, ::Types::GlobalIDType[::Project],
- required: false,
- description: 'The global ID of the project the authored merge requests should be in. Incompatible with projectPath.'
+ argument :project_id,
+ type: ::Types::GlobalIDType[::Project],
+ required: false,
+ description: <<~DESC
+ The global ID of the project the authored merge requests should be in.
+ Incompatible with projectPath.
+ DESC
attr_reader :project
- alias_method :user, :synchronized_object
+ alias_method :user, :object
def ready?(project_id: nil, project_path: nil, **args)
return early_return unless can_read_profile?
@@ -22,8 +30,7 @@ module Resolvers
load_project(project_path, project_id)
return early_return unless can_read_project?
elsif args[:iids].present?
- raise ::Gitlab::Graphql::Errors::ArgumentError,
- 'iids requires projectPath or projectId'
+ raise ::Gitlab::Graphql::Errors::ArgumentError, 'iids requires projectPath or projectId'
end
super(**args)
diff --git a/app/graphql/resolvers/user_starred_projects_resolver.rb b/app/graphql/resolvers/user_starred_projects_resolver.rb
index db420b3d116..a8abe759f27 100644
--- a/app/graphql/resolvers/user_starred_projects_resolver.rb
+++ b/app/graphql/resolvers/user_starred_projects_resolver.rb
@@ -2,11 +2,11 @@
module Resolvers
class UserStarredProjectsResolver < BaseResolver
- type Types::ProjectType, null: true
+ type Types::ProjectType.connection_type, null: true
argument :search, GraphQL::STRING_TYPE,
- required: false,
- description: 'Search query.'
+ required: false,
+ description: 'Search query.'
alias_method :user, :object
diff --git a/app/graphql/resolvers/users/snippets_resolver.rb b/app/graphql/resolvers/users/snippets_resolver.rb
index e8048b9deb9..ee1727aadbe 100644
--- a/app/graphql/resolvers/users/snippets_resolver.rb
+++ b/app/graphql/resolvers/users/snippets_resolver.rb
@@ -5,6 +5,7 @@ module Resolvers
module Users
class SnippetsResolver < BaseResolver
include ResolvesSnippets
+ include Gitlab::Allowable
alias_method :user, :object
@@ -14,6 +15,12 @@ module Resolvers
private
+ def resolve_snippets(_args)
+ return Snippet.none unless Ability.allowed?(current_user, :read_user_profile, user)
+
+ super
+ end
+
def snippet_finder_params(args)
super.merge(author: user)
end