Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions app/graph/analyzers/max_alias_per_field_analyzer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module Analyzers
class MaxAliasPerFieldAnalyzer < GraphQL::Analysis::AST::Analyzer
MAX_ALIASES_PER_FIELD = CheckConfig.get(:max_aliases_per_field, 10, :integer)

def initialize(query)
super
@alias_count_by_field = Hash.new(0)
end

def on_enter_field(node, parent, visitor)
if node.alias
field_name = node.name
@alias_count_by_field[field_name] += 1
end
end

def result
exceeded = @alias_count_by_field.find do |_field, count|
count > MAX_ALIASES_PER_FIELD
end
return unless exceeded
field, count = exceeded
GraphQL::AnalysisError.new("Field '#{field}' can be queried with an alias at most #{MAX_ALIASES_PER_FIELD} times (got #{count}).")
end
end
end
2 changes: 2 additions & 0 deletions app/graph/relay_on_rails_schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class RelayOnRailsSchema < GraphQL::Schema
use GraphQL::Analysis::AST
use GraphQL::Execution::Errors

query_analyzer Analyzers::MaxAliasPerFieldAnalyzer

lazy_resolve(Concurrent::Future, :value)

disable_introspection_entry_points unless Rails.env.development?
Expand Down
40 changes: 40 additions & 0 deletions test/controllers/graphql_controller_3_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -391,4 +391,44 @@ def setup
assert_equal [pm1.id, pm2.id].sort, JSON.parse(@response.body)['data']['search']['medias']['edges'].collect{ |x| x['node']['dbid'] }.sort
end
end

test "should query with maximum nubmer of field alias" do
u = create_user
t = create_team
create_team_user team: t, user: u, role: 'admin'
pm = create_project_media team: t
authenticate_with_user(u)
stub_configs({ 'max_aliases_per_field' => 2 }) do
# Verify alias against field not whole query
query = %{
query {
project_media(ids: "#{pm.id}") {
a1: dbid
a2: dbid
b1: id
b2: id
}
}
}
post :create, params: { query: query, team: t.slug }
assert_response :success
data = JSON.parse(@response.body)['data']['project_media']
assert_equal 4, data.count
# Should trigger an error because the field alias exceeded the allowed value
query = %{
query {
project_media(ids: "#{pm.id}") {
a1: dbid
a2: dbid
b1: id
b2: id
aa: dbid
}
}
}
post :create, params: { query: query, team: t.slug }
assert_response :success
assert_equal "Field 'dbid' can be queried with an alias at most 2 times (got 3).", JSON.parse(@response.body)['errors'][0]['message']
end
end
end
Loading