Skip to content

Instantly share code, notes, and snippets.

@yourivdlans
Created May 7, 2019 08:41
Show Gist options
  • Save yourivdlans/7d1093e5500820804a7ca8d263c98ecf to your computer and use it in GitHub Desktop.
Save yourivdlans/7d1093e5500820804a7ca8d263c98ecf to your computer and use it in GitHub Desktop.
# This policy ensures all queries and fields are disallowed by default
# Ensuring a whitelisting strategy
#
# Each Pundit policy should implement a field? method
# Which accepts a field to test if it is allowed to be used
class GraphqlPolicy
FALSE_PROC = ->(_obj, _args, _ctx) { false }
TRUE_PROC = ->(_obj, _args, _ctx) { true }
RULES = {
Types::QueryType => {
'bookings': ->(booking, _args, ctx) { BookingPolicy.new(ctx[:current_user], booking.object).show? }
},
Types::BookingType => {
'study': ->(booking, _args, ctx) { BookingPolicy.new(ctx[:current_user], booking.object).field?(:study) },
'room': ->(booking, _args, ctx) { BookingPolicy.new(ctx[:current_user], booking.object).field?(:room) },
'startsAt': ->(booking, _args, ctx) { BookingPolicy.new(ctx[:current_user], booking.object).field?(:starts_at) },
'endsAt': ->(booking, _args, ctx) { BookingPolicy.new(ctx[:current_user], booking.object).field?(:ends_at) },
'booking_type': ->(booking, _args, ctx) { BookingPolicy.new(ctx[:current_user], booking.object).field?(:booking_type) }
},
Types::RoomType => {
'name': ->(room, _args, ctx) { RoomPolicy.new(ctx[:current_user], room.object).field?(:name) },
'roomNumber': ->(room, _args, ctx) { RoomPolicy.new(ctx[:current_user], room.object).field?(:room_number) },
'roomType': ->(room, _args, ctx) { RoomPolicy.new(ctx[:current_user], room.object).field?(:room_type) }
},
Types::StudyType => {
'title': ->(study, _args, ctx) { StudyPolicy.new(ctx[:current_user], study.object).field?(:title) },
'user': ->(study, _args, ctx) { StudyPolicy.new(ctx[:current_user], study.object).field?(:user) }
},
Types::UserType => {
'name': ->(user, _args, ctx) { UserPolicy.new(ctx[:current_user], user.object).field?(:name) },
'email': ->(user, _args, ctx) { UserPolicy.new(ctx[:current_user], user.object).field?(:email) }
}
}.freeze
def self.guard(type, field)
return TRUE_PROC if type.introspection?
return FALSE_PROC if field == '*'
RULES.dig(type.metadata[:type_class], field) || FALSE_PROC
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment