Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

authorized? for GraphQL::Schema::EnumValue is not working #4825

Open
vitaliiorlov opened this issue Feb 6, 2024 · 2 comments
Open

authorized? for GraphQL::Schema::EnumValue is not working #4825

vitaliiorlov opened this issue Feb 6, 2024 · 2 comments

Comments

@vitaliiorlov
Copy link

Describe the bug

Hi! I found a bug regarding the authorization enum value.
According to source code, this class has the same authorization methods as argument, object, and field classes. But is for EnumValue method authorized? not working.

module GraphQL
  class Schema
    class EnumValue < GraphQL::Schema::Member
      ...

      def visible?(_ctx); true; end
      def authorized?(_ctx); true; end
    end
  end
end

Versions

graphql version: 2.2.7
rails: 7.1.3

Code example

class Types::Enums::BaseEnum < GraphQL::Schema::Enum
  enum_value_class(Types::Enums::BaseEnumValue)
end

class Types::Enums::BaseEnumValue < GraphQL::Schema::EnumValue
  def visible?(_ctx); true; end
  def authorized?(_ctx); false; end
end

Steps to reproduce

Use the code above.

Expected behavior

It works in the same way as for fields, objects, and arguments and denies access to all denied enum values.

Actual behavior
It ignores def authorized?(_ctx); false; end method, and even does not stop in there if put debugger to the method.

@rmosolgo
Copy link
Owner

rmosolgo commented Feb 6, 2024

Hey, thanks for reporting this. Did you find this documented somewhere? I didn't find it in the documentation and I don't see it addressed in the relevant spec (https://github.com/rmosolgo/graphql-ruby/blob/master/spec/graphql/authorization_spec.rb), so I think it was just never dreamed of!

But we could definitely add it. My first thought on a place to add it would be to hook in here:

when "SCALAR", "ENUM"
r = begin
current_type.coerce_result(value, context)

and here:

coerced_value = begin
type.coerce_input(value, context)
rescue StandardError => err
context.schema.handle_or_reraise(context, err)
end

Which go here:

def coerce_result(value, ctx)
warden = ctx.warden
all_values = warden ? warden.enum_values(self) : values.each_value
enum_value = all_values.find { |val| val.value == value }
if enum_value
enum_value.graphql_name
else
raise self::UnresolvedValueError.new(enum: self, value: value, context: ctx)
end
end
def coerce_input(value_name, ctx)
all_values = ctx.warden ? ctx.warden.enum_values(self) : values.each_value
if v = all_values.find { |val| val.graphql_name == value_name }
v.value
elsif v = all_values.find { |val| val.value == value_name }
# this is for matching default values, which are "inputs", but they're
# the Ruby value, not the GraphQL string.
v.value
else
nil
end
end

I think if those two methods (coerce_input and coerce_result) included enum_value.authorized? checks, it would implement this feature.

Feel free to give it a try if you're interested, otherwise I'll keep this open and try to take a crack at it when I find time!

@vitaliiorlov
Copy link
Author

@rmosolgo thank you for looking into this.

Did you find this documented somewhere? I didn't find it in the documentation...

No, there is no documentation regarding this. I just looked around the source code and found that the enum value also has those methods (visible? and authorized?). So, I have such a case in my project where I would like to have such a feature, but tried to work with that and found out that visible? is working correctly, but authorized? does not. This is a short story about how I created this bug because, in the gem's source code, I've seen such a method and anticipated it should work then.

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

No branches or pull requests

2 participants