hasura_handler 0.1.0 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 95be3b9811df02080b282112b53e0b0a6aacd4520cd98de9de851af3349028a8
4
- data.tar.gz: 41a54a270f42447b21ae308b79e23bd1ad24851cbc00d1c5101d8ca478342ef5
3
+ metadata.gz: d39e768059737605f096e2fb1ebc03b97a30ff3c05a55a580bc4f99b96e0e60e
4
+ data.tar.gz: 9322488f0d8cd4934509279e28b824926cb1f7a14a982700c323f5c11dab5d81
5
5
  SHA512:
6
- metadata.gz: f03c0e96d4c8f4e06de84c7ed087fb79a3c86d0fe8be6a29fd8d465d581c1a0735e81bf7cb3015eb1c7ac4bc2e25416ceef712716aa805a9163c6940d83aaa59
7
- data.tar.gz: b3c696453cd65e2c16b9d0e2888d0681456d7bba76d1e78d93b5cbcf510096c5618ecd58e5d81c5c7bdbfdffe8d68a651963e8737e293b93476fd9d6d7c8c720
6
+ metadata.gz: 021c7736f7148d728ea3b09562051e5b3679a6b9370a127304f988274a81cf2959b012dc2b2561fb257f43c10a2e396d753ce01101d19d1c1cc300337df9da69
7
+ data.tar.gz: ddda66c93f15b46b003f063b878fc00c59adba67bc0d6ec500d1b514ad1dfd0ecedf6f761db967a146678fb442060e8dbcb4cbea0306688ef0490ac31293118f
data/README.md CHANGED
@@ -1,28 +1,9 @@
1
- # HasuraHandler
2
- Short description and motivation.
1
+ # HasuraHandler ![Gem Version](https://badge.fury.io/rb/hasura_handler.svg) [![tests](https://github.com/KazW/HasuraHandler/workflows/tests/badge.svg)](https://github.com/KazW/HasuraHandler/actions?query=workflow%3Atests) [![Maintainability](https://api.codeclimate.com/v1/badges/38864d7565ab11729b6b/maintainability)](https://codeclimate.com/github/KazW/HasuraHandler/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/38864d7565ab11729b6b/test_coverage)](https://codeclimate.com/github/KazW/HasuraHandler/test_coverage)
2
+ HasuraHandler is a Rails framework that makes building microservices for Hasura easy.
3
+ HasuraHandler also simplifies adding Hasura to an existing Rails app.
3
4
 
4
5
  ## Usage
5
- How to use my plugin.
6
-
7
- ## Installation
8
- Add this line to your application's Gemfile:
9
-
10
- ```ruby
11
- gem 'hasura_handler'
12
- ```
13
-
14
- And then execute:
15
- ```bash
16
- $ bundle
17
- ```
18
-
19
- Or install it yourself as:
20
- ```bash
21
- $ gem install hasura_handler
22
- ```
23
-
24
- ## Contributing
25
- Contribution directions go here.
6
+ Please see the [documentation site](https://kazw.github.io/HasuraHandler).
26
7
 
27
8
  ## License
28
9
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -2,16 +2,22 @@ require_dependency 'hasura_handler/application_controller'
2
2
 
3
3
  module HasuraHandler
4
4
  class ActionsController < ApplicationController
5
- def process
6
- unless HasuraHandler::Action.hasura_actions.keys.include?(action_params[:action][:name])
5
+ before_action :check_header
6
+
7
+ def index
8
+ unless HasuraHandler::Action.hasura_actions.keys.include?(action_params['action']['name'])
7
9
  render json: { error: true, message: 'action name not registered' }, status: 404
8
10
  return
9
11
  end
10
12
 
11
- klass = HasuraHandler::Action.hasura_actions[action_params[:action][:name]]
12
- action = klass.new(action_params[:session_variables], action_params[:input])
13
- action.run
13
+ klass = HasuraHandler::Action.hasura_actions[action_params['action']['name']]
14
+ action = klass.new(
15
+ clean_headers,
16
+ action_params['session_variables'].to_h,
17
+ action_params['input'].to_h
18
+ )
14
19
 
20
+ action.run
15
21
  if action.error_message.present?
16
22
  render json: { error: true, message: action.error_message }, status: 400
17
23
  else
@@ -20,7 +26,7 @@ module HasuraHandler
20
26
  end
21
27
 
22
28
  def action_params
23
- params.permit(
29
+ full_params.permit(
24
30
  action: [:name],
25
31
  input: {},
26
32
  session_variables: {}
@@ -1,7 +1,5 @@
1
1
  module HasuraHandler
2
2
  class ApplicationController < ActionController::API
3
- before_action :check_header
4
-
5
3
  private
6
4
 
7
5
  def check_header
@@ -9,5 +7,13 @@ module HasuraHandler
9
7
  render json: { error: true, message: 'unable to authenticate request' }, status: 401
10
8
  end
11
9
  end
10
+
11
+ def full_params
12
+ ActionController::Parameters.new(JSON.parse(request.raw_post))
13
+ end
14
+
15
+ def clean_headers
16
+ request.headers.reject{ |k,v| k.include?('.') }.to_h
17
+ end
12
18
  end
13
19
  end
@@ -0,0 +1,35 @@
1
+ require_dependency "hasura_handler/application_controller"
2
+
3
+ module HasuraHandler
4
+ class AuthHookController < ApplicationController
5
+ def get_mode
6
+ @headers = clean_headers.to_h.select{ |k,v| k =~ /\AHTTP_/ }.to_h
7
+ authenticate
8
+ end
9
+
10
+ def post_mode
11
+ @headers = post_params['auth_hook']['headers'].
12
+ to_h.
13
+ map{ |k,v| ['HTTP_' + k.to_s.gsub('-', '_').upcase, v] }.
14
+ to_h
15
+
16
+ authenticate
17
+ end
18
+
19
+ private
20
+
21
+ def post_params
22
+ params.permit(auth_hook: {}, headers: {})
23
+ end
24
+
25
+ def authenticate
26
+ @authenticator = HasuraHandler.authenticator.new(@headers)
27
+
28
+ if @authenticator.success?
29
+ render json: @authenticator.response, status: 200
30
+ else
31
+ render json: { error: true, message: @authenticator.error_message }, status: 401
32
+ end
33
+ end
34
+ end
35
+ end
@@ -2,8 +2,10 @@ require_dependency 'hasura_handler/application_controller'
2
2
 
3
3
  module HasuraHandler
4
4
  class EventsController < ApplicationController
5
- def process
6
- processor = HasuraHandler::EventHandler.new(event_params)
5
+ before_action :check_header
6
+
7
+ def index
8
+ processor = HasuraHandler::EventProcessor.new(event_params.to_h)
7
9
 
8
10
  unless processor.event.valid?
9
11
  error_response(processor.event.errors)
@@ -32,9 +34,10 @@ module HasuraHandler
32
34
  end
33
35
 
34
36
  def event_params
35
- params.permit(
37
+ full_params.permit(
36
38
  :id,
37
39
  :created_at,
40
+ delivery_info: {},
38
41
  table: [
39
42
  :schema,
40
43
  :name
@@ -46,10 +49,7 @@ module HasuraHandler
46
49
  :op,
47
50
  {
48
51
  session_variables: {},
49
- data: {
50
- new: {},
51
- old: {}
52
- }
52
+ data: {}
53
53
  }
54
54
  ]
55
55
  )
@@ -4,7 +4,7 @@ module HasuraHandler
4
4
 
5
5
  def perform(handler_class, event)
6
6
  klass = handler_class.constantize
7
- handler = klass.new(event)
7
+ handler = klass.new(HasuraHandler::Event.new(event))
8
8
  handler.run
9
9
  end
10
10
  end
@@ -3,7 +3,7 @@ module HasuraHandler
3
3
  queue_as HasuraHandler.event_job_queue
4
4
 
5
5
  def perform(event)
6
- HasuraHandler::EventHandler.new(event).process
6
+ HasuraHandler::EventProcessor.new(event).process
7
7
  end
8
8
  end
9
9
  end
@@ -1,9 +1,14 @@
1
1
  HasuraHandler::Engine.routes.draw do
2
+ if HasuraHandler.authentication_enabled
3
+ get '/auth', to: 'auth_hook#get_mode'
4
+ post '/auth', to: 'auth_hook#post_mode'
5
+ end
6
+
2
7
  if HasuraHandler.events_enabled
3
- post '/events', to: 'events#process'
8
+ post '/events', to: 'events#index'
4
9
  end
5
10
 
6
11
  if HasuraHandler.actions_enabled
7
- post '/actions', to: 'actions#process'
12
+ post '/actions', to: 'actions#index'
8
13
  end
9
14
  end
@@ -1,5 +1,7 @@
1
1
  require 'hasura_handler/engine'
2
+ require 'hasura_handler/authenticator'
2
3
  require 'hasura_handler/event_handler'
4
+ require 'hasura_handler/event_processor'
3
5
  require 'hasura_handler/event'
4
6
  require 'hasura_handler/action'
5
7
 
@@ -7,6 +9,8 @@ module HasuraHandler
7
9
  class << self
8
10
  mattr_accessor :auth_header,
9
11
  :auth_key,
12
+ :authentication_enabled,
13
+ :authenticator,
10
14
  :events_enabled,
11
15
  :actions_enabled,
12
16
  :event_job_queue,
@@ -15,7 +19,9 @@ module HasuraHandler
15
19
  :fanout_events,
16
20
  :retry_after
17
21
 
18
- self.auth_header = 'X-Hasura-Service-Key'
22
+ self.auth_header = 'HTTP_X_HASURA_SERVICE_KEY'
23
+ self.authentication_enabled = false
24
+ self.authenticator = nil
19
25
  self.events_enabled = true
20
26
  self.async_events = true
21
27
  self.fanout_events = true
@@ -27,8 +33,13 @@ module HasuraHandler
27
33
 
28
34
  def self.setup(&block)
29
35
  yield self
30
- [:auth_key].each do |key|
31
- raise "HasuraHandler requires the #{key} to be configured." if self.send(key).blank?
36
+
37
+ if (self.events_enabled || self.actions_enabled) && self.auth_key.blank?
38
+ raise "HasuraHandler requires the auth_key to be configured if actions or events are enabled."
39
+ end
40
+
41
+ if self.authentication_enabled && self.authenticator.blank?
42
+ raise "HasuraHandler requires the authenticator to be configured if authentication hook is enabled."
32
43
  end
33
44
  end
34
45
  end
@@ -5,9 +5,7 @@ module HasuraHandler
5
5
  attr_reader :hasura_action_name
6
6
 
7
7
  def action_name(action_name)
8
- raise 'run method not defined' unless new(nil, nil).respond_to?(:run)
9
8
  raise 'action_name must be a symbol or string' unless action_name.is_a?(Symbol) || action_name.is_a?(String)
10
- raise 'action_name already used' if @@hasura_actions.keys.include?(action_name.to_s)
11
9
 
12
10
  @@hasura_actions[action_name.to_s] = self
13
11
  @hasura_action_name = action_name.to_s
@@ -19,11 +17,13 @@ module HasuraHandler
19
17
  end
20
18
 
21
19
  attr_reader :session_variables,
20
+ :headers,
22
21
  :input,
23
22
  :output,
24
23
  :error_message
25
24
 
26
- def initialize(session_variables, input)
25
+ def initialize(headers, session_variables, input)
26
+ @headers = headers
27
27
  @session_variables = session_variables
28
28
  @input = input
29
29
  @output = {}
@@ -0,0 +1,21 @@
1
+ module HasuraHandler
2
+ class Authenticator
3
+ attr_accessor :response,
4
+ :error_message
5
+
6
+ def initialize(headers)
7
+ @headers = headers
8
+ @response = {}
9
+ end
10
+
11
+ def success?
12
+ begin
13
+ authenticate
14
+ ensure
15
+ return false if @response.blank?
16
+ end
17
+
18
+ @response.present? || @error_message.blank?
19
+ end
20
+ end
21
+ end
@@ -4,17 +4,19 @@ module HasuraHandler
4
4
  :table,
5
5
  :trigger,
6
6
  :event,
7
+ :op,
7
8
  :created_at,
8
9
  :raw_event,
9
10
  :errors,
10
11
  :valid
11
12
 
12
13
  def initialize(event)
13
- @id = event[:id]
14
- @table = event[:table]
15
- @trigger = event[:trigger]
16
- @event = event[:event]
17
- @created_at = event[:created_at]
14
+ @id = event['id']
15
+ @table = event['table']['name']
16
+ @trigger = event['trigger']['name']
17
+ @event = event['event']
18
+ @op = event['event']['op']
19
+ @created_at = event['created_at']
18
20
  @raw_event = event
19
21
  @errors = {}
20
22
 
@@ -42,21 +44,21 @@ module HasuraHandler
42
44
  end
43
45
 
44
46
  def validate_table
45
- unless @table.is_a?(Hash)
47
+ unless @raw_event['table'].is_a?(Hash)
46
48
  @errors['table'] = 'not a hash'
47
49
  return
48
50
  end
49
51
 
50
- string_fields?(@table, 'table', [:schema, :name])
52
+ string_fields?(@raw_event['table'], 'table', [:schema, :name])
51
53
  end
52
54
 
53
55
  def validate_trigger
54
- unless @trigger.is_a?(Hash)
56
+ unless @raw_event['trigger'].is_a?(Hash)
55
57
  @errors['trigger'] = 'not a hash'
56
58
  return
57
59
  end
58
60
 
59
- string_fields?(@trigger, 'trigger', [:name])
61
+ string_fields?(@raw_event['trigger'], 'trigger', [:name])
60
62
  end
61
63
 
62
64
  def validate_event
@@ -65,7 +67,7 @@ module HasuraHandler
65
67
  return
66
68
  end
67
69
 
68
- @errors['event.session_variables'] = 'not a hash' unless @event[:session_variables].is_a?(Hash)
70
+ @errors['event.session_variables'] = 'not a hash' unless @event['session_variables'].is_a?(Hash)
69
71
  string_fields?(@event, 'event', [:op])
70
72
 
71
73
  [:new, :old].each do |field|
@@ -12,12 +12,12 @@ module HasuraHandler
12
12
  raise 'invalid matcher value' unless matchers[matcher].is_a?(String)
13
13
  end
14
14
 
15
- raise 'run method not defined' unless new(nil).respond_to?(:run)
16
-
17
15
  @hasura_matchers = matchers
18
16
  end
19
17
  end
20
18
 
19
+ attr_reader :event
20
+
21
21
  def initialize(event)
22
22
  @event = event
23
23
  end
@@ -19,6 +19,10 @@ module HasuraHandler
19
19
  handler.run
20
20
  end
21
21
  end
22
+
23
+ if event_handlers.size == 0
24
+ Rails.logger.debug('[HasuraHandler] Received event with no matching handlers.')
25
+ end
22
26
  end
23
27
 
24
28
  private
@@ -28,6 +32,7 @@ module HasuraHandler
28
32
  descendants.
29
33
  map{ |klass| [klass, klass.hasura_matchers] }.
30
34
  to_h.
35
+ select{ |klass, matchers| matchers.present? }.
31
36
  map{ |klass,matchers| [klass, check_matchers(matchers)] }.
32
37
  to_h.
33
38
  select{ |klass,match| match }.
@@ -35,8 +40,8 @@ module HasuraHandler
35
40
  end
36
41
 
37
42
  def check_matchers(matchers)
38
- matchers.all? do |matcher|
39
- @event.send(matcher.first) == matcher.last
43
+ matchers.all? do |field,value|
44
+ @event.send(field) == value
40
45
  end
41
46
  end
42
47
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hasura_handler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kaz Walker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-07-25 00:00:00.000000000 Z
11
+ date: 2020-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -30,21 +30,8 @@ dependencies:
30
30
  - - ">="
31
31
  - !ruby/object:Gem::Version
32
32
  version: 6.0.3.2
33
- - !ruby/object:Gem::Dependency
34
- name: graphql-client
35
- requirement: !ruby/object:Gem::Requirement
36
- requirements:
37
- - - "~>"
38
- - !ruby/object:Gem::Version
39
- version: 0.16.0
40
- type: :runtime
41
- prerelease: false
42
- version_requirements: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - "~>"
45
- - !ruby/object:Gem::Version
46
- version: 0.16.0
47
- description: Provides an easy way to build custom backends for Hasura.
33
+ description: HasuraHandler is a Rails framework that makes building microservices
34
+ for Hasura easy.
48
35
  email:
49
36
  - me@kaz.codes
50
37
  executables: []
@@ -56,6 +43,7 @@ files:
56
43
  - Rakefile
57
44
  - app/controllers/hasura_handler/actions_controller.rb
58
45
  - app/controllers/hasura_handler/application_controller.rb
46
+ - app/controllers/hasura_handler/auth_hook_controller.rb
59
47
  - app/controllers/hasura_handler/events_controller.rb
60
48
  - app/jobs/hasura_handler/application_job.rb
61
49
  - app/jobs/hasura_handler/event_handler_job.rb
@@ -63,16 +51,20 @@ files:
63
51
  - config/routes.rb
64
52
  - lib/hasura_handler.rb
65
53
  - lib/hasura_handler/action.rb
54
+ - lib/hasura_handler/authenticator.rb
66
55
  - lib/hasura_handler/engine.rb
67
56
  - lib/hasura_handler/event.rb
68
57
  - lib/hasura_handler/event_handler.rb
69
58
  - lib/hasura_handler/event_processor.rb
70
- - lib/hasura_handler/version.rb
71
59
  - lib/tasks/hasura_handler_tasks.rake
72
- homepage: https://github.com/KazW/HasuraHandler
60
+ homepage: https://kazw.github.io/HasuraHandler
73
61
  licenses:
74
62
  - MIT
75
- metadata: {}
63
+ metadata:
64
+ bug_tracker_uri: https://github.com/KazW/HasuraHandler/issues
65
+ documentation_uri: https://kazw.github.io/HasuraHandler
66
+ homepage_uri: https://kazw.github.io/HasuraHandler
67
+ source_code_uri: https://github.com/KazW/HasuraHandler
76
68
  post_install_message:
77
69
  rdoc_options: []
78
70
  require_paths:
@@ -88,7 +80,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
88
80
  - !ruby/object:Gem::Version
89
81
  version: '0'
90
82
  requirements: []
91
- rubygems_version: 3.1.4
83
+ rubygems_version: 3.1.2
92
84
  signing_key:
93
85
  specification_version: 4
94
86
  summary: Integrates Hasura with Rails
@@ -1,3 +0,0 @@
1
- module HasuraHandler
2
- VERSION = '0.1.0'
3
- end