Skip to content

WIP: Make GraphQL Types authorizable

Luke Duncalfe requested to merge 54417-authorize-types into master

What does this MR do?

  • Allows GraphQL Types to be authorizable
  • Allows GraphQL Scalar fields (ones that return Strings, or Integers) to be authorizable
  • authorize can be passed a Proc

Type authorization

All of these will work:

class ProjectType < BaseObject
  authorize :read_project
end

class ProjectType < BaseObject
  authorize [:read_project, :something_else] 
end

class ProjectType < BaseObject
  authorize ->(obj, args, ctx) { ... }
end

class ProjectType < BaseObject
  authorize [->(obj, args, ctx) { ... }, :read_project]
end

If all of the permission checks do not pass, then:

# Query:
{
  project(fullPath: "root/my-project") {
    id
  }
}

# Response:
{
  "data": {
    "project": null
  }
}

Field authorization

Scalar-types (fields that return Strings, Integers etc.) can now be authorized. The subject for the permission check is different for when the return type is a Scalar vs a Types::*Type:

:some_permission check will be against the Project:

class ProjectType
  field :id, GraphQL::ID_TYPE, authorize: :some_permission
end

:some_permission check will be against the MergeRequest:

class ProjectType
  field :merge_request, Types::MergeRequestType, authorize: :some_permission
end

And, err.. if you want to pass an Array of permissions, it has to be done like this... (!).

class UserType
  field :id, GraphQL::ID_TYPE do 
    authorize [:some_permission, :another_one] 
  end
end

Like Type authorization, Field authorizations also nullify the data if the authorization checks fail:

# Query:
{
  project(fullPath: "root/squash-project") {
    id
  }
}

# Response:
{
  "data": {
    "project": {
      "id": null
    }
  }
}

Type and Field authorization together

Permissions are cumulative, so where permissions are defined in both the Type and the Field:

class UserType
  authorize: :some_permission
end

class IssueType
  field :author, UserType, authorize: :another_permission
end

The user would need both permissions on the User.

Mutation authorization

Mutation authorization is the same as it was before - some methods have been moved from Authorization to AuthorizeResource to allow this. It means that currently the mutation authorization doesn't support Procs, which we could change in the future if we wanted to.

What are the relevant issue numbers?

https://gitlab.com/gitlab-org/gitlab-ce/issues/54417

Does this MR meet the acceptance criteria?

Closes #54417 (closed)

Edited by Luke Duncalfe

Merge request reports