diff options
Diffstat (limited to 'app/graphql/resolvers')
18 files changed, 152 insertions, 28 deletions
diff --git a/app/graphql/resolvers/base_resolver.rb b/app/graphql/resolvers/base_resolver.rb index 48563633d11..20ed089d159 100644 --- a/app/graphql/resolvers/base_resolver.rb +++ b/app/graphql/resolvers/base_resolver.rb @@ -124,6 +124,16 @@ module Resolvers [args[:iid], args[:iids]].any? ? 0 : 0.01 end + def self.before_connection_authorization(&block) + @before_connection_authorization_block = block + end + + # rubocop: disable Style/TrivialAccessors + def self.before_connection_authorization_block + @before_connection_authorization_block + end + # rubocop: enable Style/TrivialAccessors + def offset_pagination(relation) ::Gitlab::Graphql::Pagination::OffsetPaginatedRelation.new(relation) end diff --git a/app/graphql/resolvers/board_list_issues_resolver.rb b/app/graphql/resolvers/board_list_issues_resolver.rb index 25fb35ec74b..7c85dd8fb9b 100644 --- a/app/graphql/resolvers/board_list_issues_resolver.rb +++ b/app/graphql/resolvers/board_list_issues_resolver.rb @@ -13,15 +13,29 @@ module Resolvers alias_method :list, :object def resolve(**args) - filter_params = item_filters(args[:filters]).merge(board_id: list.board.id, id: list.id) + filters = item_filters(args[:filters]) + mutually_exclusive_milestone_args!(filters) + + filter_params = filters.merge(board_id: list.board.id, id: list.id) service = ::Boards::Issues::ListService.new(list.board.resource_parent, context[:current_user], filter_params) + pagination_connections = Gitlab::Graphql::Pagination::Keyset::Connection.new(service.execute) + + ::Boards::Issues::ListService.initialize_relative_positions(list.board, current_user, pagination_connections.items) - service.execute + pagination_connections end # https://gitlab.com/gitlab-org/gitlab/-/issues/235681 def self.complexity_multiplier(args) 0.005 end + + private + + def mutually_exclusive_milestone_args!(filters) + if filters[:milestone_title] && filters[:milestone_wildcard_id] + raise ::Gitlab::Graphql::Errors::ArgumentError, 'Incompatible arguments: milestoneTitle, milestoneWildcardId.' + end + end end end diff --git a/app/graphql/resolvers/ci/group_runners_resolver.rb b/app/graphql/resolvers/ci/group_runners_resolver.rb new file mode 100644 index 00000000000..e9c399d3855 --- /dev/null +++ b/app/graphql/resolvers/ci/group_runners_resolver.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module Resolvers + module Ci + class GroupRunnersResolver < RunnersResolver + type Types::Ci::RunnerType.connection_type, null: true + + argument :membership, ::Types::Ci::RunnerMembershipFilterEnum, + required: false, + default_value: :descendants, + description: 'Control which runners to include in the results.' + + protected + + def runners_finder_params(params) + super(params).merge(membership: params[:membership]) + end + + def parent_param + raise 'Expected group missing' unless parent.is_a?(Group) + + { group: parent } + end + end + end +end diff --git a/app/graphql/resolvers/ci/runners_resolver.rb b/app/graphql/resolvers/ci/runners_resolver.rb index 1957c4ec058..07105701daa 100644 --- a/app/graphql/resolvers/ci/runners_resolver.rb +++ b/app/graphql/resolvers/ci/runners_resolver.rb @@ -34,7 +34,7 @@ module Resolvers .execute) end - private + protected def runners_finder_params(params) { @@ -47,6 +47,19 @@ module Resolvers tag_name: node_selection&.selects?(:tag_list) } }.compact + .merge(parent_param) + end + + def parent_param + return {} unless parent + + raise "Unexpected parent type: #{parent.class}" + end + + private + + def parent + object.respond_to?(:sync) ? object.sync : object end end end diff --git a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb index 8d77c0f3a8d..9de36b5b7d1 100644 --- a/app/graphql/resolvers/concerns/issue_resolver_arguments.rb +++ b/app/graphql/resolvers/concerns/issue_resolver_arguments.rb @@ -30,7 +30,7 @@ module IssueResolverArguments description: 'Usernames of users assigned to the issue.' argument :assignee_id, GraphQL::Types::String, required: false, - description: 'ID of a user assigned to the issues, "none" and "any" values are supported.' + description: 'ID of a user assigned to the issues. Wildcard values "NONE" and "ANY" are supported.' argument :created_before, Types::TimeType, required: false, description: 'Issues created before this date.' @@ -59,6 +59,9 @@ module IssueResolverArguments argument :milestone_wildcard_id, ::Types::MilestoneWildcardIdEnum, required: false, description: 'Filter issues by milestone ID wildcard.' + argument :my_reaction_emoji, GraphQL::Types::String, + required: false, + description: 'Filter by reaction emoji applied by the current user. Wildcard values "NONE" and "ANY" are supported.' argument :not, Types::Issues::NegatedIssueFilterInputType, description: 'Negated arguments.', prepare: ->(negated_args, ctx) { negated_args.to_h }, diff --git a/app/graphql/resolvers/concerns/resolves_pipelines.rb b/app/graphql/resolvers/concerns/resolves_pipelines.rb index 77f2105db7c..7fb0852b11e 100644 --- a/app/graphql/resolvers/concerns/resolves_pipelines.rb +++ b/app/graphql/resolvers/concerns/resolves_pipelines.rb @@ -17,6 +17,11 @@ module ResolvesPipelines GraphQL::Types::String, required: false, description: "Filter pipelines by the sha of the commit they are run for." + + argument :source, + GraphQL::Types::String, + required: false, + description: "Filter pipelines by their source. Will be ignored if `dast_view_scans` feature flag is disabled." end class_methods do @@ -30,6 +35,8 @@ module ResolvesPipelines end def resolve_pipelines(project, params = {}) + params.delete(:source) unless Feature.enabled?(:dast_view_scans, project, default_enabled: :yaml) + Ci::PipelinesFinder.new(project, context[:current_user], params).execute end end diff --git a/app/graphql/resolvers/labels_resolver.rb b/app/graphql/resolvers/labels_resolver.rb index 505d1dff8d2..f0e099e8fb2 100644 --- a/app/graphql/resolvers/labels_resolver.rb +++ b/app/graphql/resolvers/labels_resolver.rb @@ -10,7 +10,7 @@ module Resolvers argument :search_term, GraphQL::Types::String, required: false, - description: 'A search term to find labels with.' + description: 'Search term to find labels with.' argument :include_ancestor_groups, GraphQL::Types::Boolean, required: false, diff --git a/app/graphql/resolvers/merge_requests_resolver.rb b/app/graphql/resolvers/merge_requests_resolver.rb index 8f2c7847a2e..c0dd61078c6 100644 --- a/app/graphql/resolvers/merge_requests_resolver.rb +++ b/app/graphql/resolvers/merge_requests_resolver.rb @@ -49,7 +49,7 @@ module Resolvers argument :state, ::Types::MergeRequestStateEnum, required: false, - description: 'A merge request state. If provided, all resolved merge requests will have this state.' + description: 'Merge request state. If provided, all resolved merge requests will have this state.' argument :labels, [GraphQL::Types::String], required: false, diff --git a/app/graphql/resolvers/milestones_resolver.rb b/app/graphql/resolvers/milestones_resolver.rb index 84f7d66ec19..dc6d781f584 100644 --- a/app/graphql/resolvers/milestones_resolver.rb +++ b/app/graphql/resolvers/milestones_resolver.rb @@ -15,15 +15,15 @@ module Resolvers argument :title, GraphQL::Types::String, required: false, - description: 'The title of the milestone.' + description: 'Title of the milestone.' argument :search_title, GraphQL::Types::String, required: false, - description: 'A search string for the title.' + description: 'Search string for the title.' argument :containing_date, Types::TimeType, required: false, - description: 'A date that the milestone contains.' + description: 'Date the milestone contains.' argument :sort, Types::MilestoneSortEnum, description: 'Sort milestones by this criteria.', diff --git a/app/graphql/resolvers/package_details_resolver.rb b/app/graphql/resolvers/package_details_resolver.rb index 89d79747732..42cb23e701d 100644 --- a/app/graphql/resolvers/package_details_resolver.rb +++ b/app/graphql/resolvers/package_details_resolver.rb @@ -6,7 +6,7 @@ module Resolvers argument :id, ::Types::GlobalIDType[::Packages::Package], required: true, - description: 'The global ID of the package.' + description: 'Global ID of the package.' def ready?(**args) context[self.class] ||= { executions: 0 } diff --git a/app/graphql/resolvers/paginated_tree_resolver.rb b/app/graphql/resolvers/paginated_tree_resolver.rb index d1b4e75169c..6c0545d26de 100644 --- a/app/graphql/resolvers/paginated_tree_resolver.rb +++ b/app/graphql/resolvers/paginated_tree_resolver.rb @@ -10,11 +10,11 @@ module Resolvers argument :path, GraphQL::Types::String, required: false, default_value: '', # root of the repository - description: 'The path to get the tree for. Default value is the root of the repository.' + description: 'Path to get the tree for. Default value is the root of the repository.' argument :ref, GraphQL::Types::String, required: false, default_value: :head, - description: 'The commit ref to get the tree for. Default value is HEAD.' + description: 'Commit ref to get the tree for. Default value is HEAD.' argument :recursive, GraphQL::Types::Boolean, required: false, default_value: false, diff --git a/app/graphql/resolvers/release_resolver.rb b/app/graphql/resolvers/release_resolver.rb index 0374a1103de..82b5647615e 100644 --- a/app/graphql/resolvers/release_resolver.rb +++ b/app/graphql/resolvers/release_resolver.rb @@ -6,7 +6,7 @@ module Resolvers argument :tag_name, GraphQL::Types::String, required: true, - description: 'The name of the tag associated to the release.' + description: 'Name of the tag associated to the release.' alias_method :project, :object diff --git a/app/graphql/resolvers/repository_branch_names_resolver.rb b/app/graphql/resolvers/repository_branch_names_resolver.rb index e9aacda2652..96550bce32f 100644 --- a/app/graphql/resolvers/repository_branch_names_resolver.rb +++ b/app/graphql/resolvers/repository_branch_names_resolver.rb @@ -8,15 +8,15 @@ module Resolvers argument :search_pattern, GraphQL::Types::String, required: true, - description: 'The pattern to search for branch names by.' + description: 'Pattern to search for branch names by.' argument :offset, GraphQL::Types::Int, required: true, - description: 'The number of branch names to skip.' + description: 'Number of branch names to skip.' argument :limit, GraphQL::Types::Int, required: true, - description: 'The number of branch names to return.' + description: 'Number of branch names to return.' def resolve(search_pattern:, offset:, limit:) Repositories::BranchNamesFinder.new(object, offset: offset, limit: limit, search: search_pattern).execute diff --git a/app/graphql/resolvers/snippets_resolver.rb b/app/graphql/resolvers/snippets_resolver.rb index 7d18c9c6fea..149bd8fa1ce 100644 --- a/app/graphql/resolvers/snippets_resolver.rb +++ b/app/graphql/resolvers/snippets_resolver.rb @@ -12,15 +12,15 @@ module Resolvers argument :author_id, ::Types::GlobalIDType[::User], required: false, - description: 'The ID of an author.' + description: 'ID of an author.' argument :project_id, ::Types::GlobalIDType[::Project], required: false, - description: 'The ID of a project.' + description: 'ID of a project.' argument :type, Types::Snippets::TypeEnum, required: false, - description: 'The type of snippet.' + description: 'Type of snippet.' argument :explore, GraphQL::Types::Boolean, diff --git a/app/graphql/resolvers/todo_resolver.rb b/app/graphql/resolvers/todo_resolver.rb index 263b190c74e..f0be1b6e9a5 100644 --- a/app/graphql/resolvers/todo_resolver.rb +++ b/app/graphql/resolvers/todo_resolver.rb @@ -8,27 +8,34 @@ module Resolvers argument :action, [Types::TodoActionEnum], required: false, - description: 'The action to be filtered.' + description: 'Action to be filtered.' argument :author_id, [GraphQL::Types::ID], required: false, - description: 'The ID of an author.' + description: 'ID of an author.' argument :project_id, [GraphQL::Types::ID], required: false, - description: 'The ID of a project.' + description: 'ID of a project.' argument :group_id, [GraphQL::Types::ID], required: false, - description: 'The ID of a group.' + description: 'ID of a group.' argument :state, [Types::TodoStateEnum], required: false, - description: 'The state of the todo.' + description: 'State of the todo.' argument :type, [Types::TodoTargetEnum], required: false, - description: 'The type of the todo.' + description: 'Type of the todo.' + + before_connection_authorization do |nodes, current_user| + Preloaders::UserMaxAccessLevelInProjectsPreloader.new( + nodes.map(&:project).compact, + current_user + ).execute + end def resolve(**args) return Todo.none unless current_user.present? && target.present? diff --git a/app/graphql/resolvers/tree_resolver.rb b/app/graphql/resolvers/tree_resolver.rb index 70b4d81845c..8d6ece0956e 100644 --- a/app/graphql/resolvers/tree_resolver.rb +++ b/app/graphql/resolvers/tree_resolver.rb @@ -9,11 +9,11 @@ module Resolvers argument :path, GraphQL::Types::String, required: false, default_value: '', - description: 'The path to get the tree for. Default value is the root of the repository.' + description: 'Path to get the tree for. Default value is the root of the repository.' argument :ref, GraphQL::Types::String, required: false, default_value: :head, - description: 'The commit ref to get the tree for. Default value is HEAD.' + description: 'Commit ref to get the tree for. Default value is HEAD.' argument :recursive, GraphQL::Types::Boolean, required: false, default_value: false, diff --git a/app/graphql/resolvers/users/groups_resolver.rb b/app/graphql/resolvers/users/groups_resolver.rb new file mode 100644 index 00000000000..0899b08e19c --- /dev/null +++ b/app/graphql/resolvers/users/groups_resolver.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +module Resolvers + module Users + class GroupsResolver < BaseResolver + include Gitlab::Graphql::Authorize::AuthorizeResource + include LooksAhead + + type Types::GroupType.connection_type, null: true + + authorize :read_user_groups + authorizes_object! + + argument :search, GraphQL::Types::String, + required: false, + description: 'Search by group name or path.' + argument :permission_scope, + ::Types::PermissionTypes::GroupEnum, + required: false, + description: 'Filter by permissions the user has on groups.' + + before_connection_authorization do |nodes, current_user| + Preloaders::UserMaxAccessLevelInGroupsPreloader.new(nodes, current_user).execute + end + + def resolve_with_lookahead(**args) + return unless Feature.enabled?(:paginatable_namespace_drop_down_for_project_creation, current_user, default_enabled: :yaml) + + apply_lookahead(Groups::UserGroupsFinder.new(current_user, object, args).execute) + end + + private + + def preloads + { + path: [:route], + full_path: [:route] + } + end + end + end +end + +Resolvers::Users::GroupsResolver.prepend_mod_with('Resolvers::Users::GroupsResolver') diff --git a/app/graphql/resolvers/users/snippets_resolver.rb b/app/graphql/resolvers/users/snippets_resolver.rb index ee1727aadbe..75bba8debab 100644 --- a/app/graphql/resolvers/users/snippets_resolver.rb +++ b/app/graphql/resolvers/users/snippets_resolver.rb @@ -11,7 +11,7 @@ module Resolvers argument :type, Types::Snippets::TypeEnum, required: false, - description: 'The type of snippet.' + description: 'Type of snippet.' private |