Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 13, 2025

The Query.users field returned all users without authorization. Per issue comments, this should be restricted to admins while preserving the ability to query individual users by ID through a dedicated user query field.

Changes

  • GlobalPolicy: Added list_users ability to admin-only policy block
  • QueryType.users: Added authorization check that raises GraphQL::UnauthorizedError for non-admin users
  • QueryType.user: Added new dedicated query field for fetching a single user by ID
  • Tests: Added coverage for both the restricted users query and the new user(id:) query

Authorization Matrix

User Type Query.users Query.user(id:)
Anonymous
Regular User
Admin

Example

# app/graphql/types/query_type.rb
field :user, Types::UserType, null: true, description: 'Find a user' do
  argument :id, Types::GlobalIdType[::User], required: true, description: 'GlobalID of the target user'
end

def user(id:)
  SagittariusSchema.object_from_id(id)
end

def users
  unless Ability.allowed?(current_authentication, :list_users, :global)
    raise GraphQL::UnauthorizedError, 'You do not have permission to list all users'
  end
  User.all
end
# Admins can list all users
query { users { nodes { id username } } }

# All authenticated users can query by ID using the dedicated user field
query { user(id: "gid://sagittarius/User/123") { id username } }

Error Handling

Uses GraphQL::UnauthorizedError instead of GraphQL::ExecutionError to provide consistent authorization error structure across the GraphQL API, matching the error handling pattern used in mutations and other authorization failures.

Original prompt

This section details on the original issue you should resolve

<issue_title>Should the Query.users field be restricted to admin users?</issue_title>
<issue_description></issue_description>

Comments on the Issue (you are @copilot in this section)

@nicosammito Generally we should. But it should be possible to query a user over his id

💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI self-assigned this Nov 13, 2025
Co-authored-by: Knerio <96529060+Knerio@users.noreply.github.com>
Copilot AI changed the title [WIP] Restrict Query.users field to admin users Restrict Query.users field to admin users only Nov 13, 2025
Copilot AI requested a review from Knerio November 13, 2025 22:24
Copilot finished work on behalf of Knerio November 13, 2025 22:24
@Knerio
Copy link
Member

Knerio commented Nov 13, 2025

@copilot Is there even a user query via id?

Co-authored-by: Knerio <96529060+Knerio@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 13, 2025

@copilot Is there even a user query via id?

Yes, users can be queried by ID using the node query which is part of the GraphQL Relay specification:

query {
  node(id: "gid://sagittarius/User/123") {
    ... on User {
      id
      username
    }
  }
}

This works because UserType has id_field User (line 49 in app/graphql/types/user_type.rb), which makes it compatible with the node interface. I've also added tests in spec/requests/graphql/query/user_node_query_spec.rb to verify this functionality works for authenticated users.

Additionally, I've updated the error handling to use GraphQL::UnauthorizedError instead of GraphQL::ExecutionError for consistent error structure (commit 522c8cd).

@github-actions
Copy link

github-actions bot commented Nov 13, 2025

GitLab Pipeline Action

General information

Link to pipeline: https://gitlab.com/code0-tech/development/sagittarius/-/pipelines/2160720545

Status: Passed
Duration: 4 minutes

Job summaries

rspec: [ee]

Coverage report available at https://code0-tech.gitlab.io/-/development/sagittarius/-/jobs/12100941356/artifacts/tmp/coverage/index.html
Test summary available at https://gitlab.com/code0-tech/development/sagittarius/-/pipelines/2160720545/test_report
Finished in 18.88 seconds (files took 12.86 seconds to load)
1193 examples, 0 failures
Line Coverage: 91.7% (3991 / 4352)
[TEST PROF INFO] Time spent in factories: 00:10.255 (39.81% of total time)

rspec: [ce]

Coverage report available at https://code0-tech.gitlab.io/-/development/sagittarius/-/jobs/12100941355/artifacts/tmp/coverage/index.html
Test summary available at https://gitlab.com/code0-tech/development/sagittarius/-/pipelines/2160720545/test_report
Finished in 18.74 seconds (files took 9.93 seconds to load)
1146 examples, 0 failures
Line Coverage: 91.09% (3823 / 4197)
[TEST PROF INFO] Time spent in factories: 00:09.965 (41.07% of total time)

rubocop

667 files inspected, no offenses detected

Copilot finished work on behalf of Knerio November 13, 2025 22:32
@Knerio
Copy link
Member

Knerio commented Nov 13, 2025

@copilot Add a seperate query to query users and use that, node is for something else, because its not working

Co-authored-by: Knerio <96529060+Knerio@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Nov 13, 2025

@copilot Add a seperate query to query users and use that, node is for something else, because its not working

Added a dedicated user query field for querying users by ID (commit 2628730):

query {
  user(id: "gid://sagittarius/User/123") {
    id
    username
  }
}

The field follows the same pattern as organization and namespace queries, using Types::GlobalIdType[::User] for type-safe ID handling. Updated the test file from user_node_query_spec.rb to user_query_spec.rb to test the new query field.

Copilot AI changed the title Restrict Query.users field to admin users only Restrict Query.users field to admin users and add Query.user field Nov 13, 2025
Copilot finished work on behalf of Knerio November 13, 2025 22:41
@Knerio
Copy link
Member

Knerio commented Nov 13, 2025

I will need to look into it why it fails

@Knerio Knerio marked this pull request as ready for review November 15, 2025 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Should the Query.users field be restricted to admin users?

2 participants