hasura_handler 0.1.3 → 0.1.8

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: f772550a50cbdcfdcebd62cc96813060cd16a10c0bb6196a7405c6fa418c915a
4
- data.tar.gz: 85b8df94f285c9fa393dc1d05126af92dfec690f5ff16092a317d6a494355905
3
+ metadata.gz: 25f72768507a2bb41a57d8496b0a169a81d9f6a23f1b319b0b75070d9fad060d
4
+ data.tar.gz: a45f22682a707e9387daf8243715f48f6e84ac6d813329e87581b128d6822baa
5
5
  SHA512:
6
- metadata.gz: b263514fe1d23d90c422a933c14ee3ac0e69c7a681702fdbfc85f7ec65bf66f5f738dbf4ebc2c2a54e032ab84cbba143b7f9a73e39d12ffa532b0e816157024f
7
- data.tar.gz: 636455f631df28448915c2a3fa8c2fe79348c453845dc1b30a30bbf879ff15a3e5126da6a31216e1cdb620dc000b936a00bb14f69a620661685fed995ee3192e
6
+ metadata.gz: 5047bb08871d97abf679305bf0ec75c0de747b2a9ba9b30287b8f946bb7fe28337dbc38011c5d8224dd292b50cf4b7b6df67331b832ba6bd49120dd22207ef0c
7
+ data.tar.gz: bb3a3b2637e97375ab5a8477e3cf5a13e7e2d06800e8758411620c24e9eb938ffe793a9b90e744cdfa05d03b934bee8b96be2b614a9a125d40e3d097fdc5963f
data/README.md CHANGED
@@ -1,28 +1,9 @@
1
- # HasuraHandler![tests](https://github.com/KazW/HasuraHandler/workflows/tests/badge.svg)
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,29 +2,27 @@ require_dependency 'hasura_handler/application_controller'
2
2
 
3
3
  module HasuraHandler
4
4
  class ActionsController < ApplicationController
5
+ before_action :check_header
6
+
5
7
  def index
6
- unless HasuraHandler::Action.hasura_actions.keys.include?(action_params['action']['name'])
8
+ unless HasuraHandler::Action.hasura_actions.keys.include?(raw_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'].to_h, action_params['input'].to_h)
13
- action.run
13
+ klass = HasuraHandler::Action.hasura_actions[raw_params['action']['name']]
14
+ action = klass.new(
15
+ clean_headers,
16
+ raw_params['session_variables'].to_h,
17
+ raw_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
18
24
  render json: action.output
19
25
  end
20
26
  end
21
-
22
- def action_params
23
- full_params.permit(
24
- action: [:name],
25
- input: {},
26
- session_variables: {}
27
- )
28
- end
29
27
  end
30
28
  end
@@ -1,6 +1,8 @@
1
1
  module HasuraHandler
2
2
  class ApplicationController < ActionController::API
3
- before_action :check_header
3
+ def protect_against_forgery?
4
+ false
5
+ end
4
6
 
5
7
  private
6
8
 
@@ -10,8 +12,12 @@ module HasuraHandler
10
12
  end
11
13
  end
12
14
 
13
- def full_params
14
- ActionController::Parameters.new(JSON.parse(request.body.read))
15
+ def raw_params
16
+ @raw_params ||= JSON.parse(request.raw_post)
17
+ end
18
+
19
+ def clean_headers
20
+ request.headers.reject{ |k,v| k.include?('.') }.to_h
15
21
  end
16
22
  end
17
23
  end
@@ -0,0 +1,31 @@
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 = raw_params['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 authenticate
22
+ @authenticator = HasuraHandler.authenticator.new(@headers)
23
+
24
+ if @authenticator.success?
25
+ render json: @authenticator.response, status: 200
26
+ else
27
+ render json: { error: true, message: @authenticator.error_message }, status: 401
28
+ end
29
+ end
30
+ end
31
+ end
@@ -2,8 +2,10 @@ require_dependency 'hasura_handler/application_controller'
2
2
 
3
3
  module HasuraHandler
4
4
  class EventsController < ApplicationController
5
+ before_action :check_header
6
+
5
7
  def index
6
- processor = HasuraHandler::EventHandler.new(event_params.to_h)
8
+ processor = HasuraHandler::EventProcessor.new(raw_params)
7
9
 
8
10
  unless processor.event.valid?
9
11
  error_response(processor.event.errors)
@@ -30,29 +32,5 @@ module HasuraHandler
30
32
  response.set_header('Retry-After', HasuraHandler.retry_after)
31
33
  render json: { success: false, errors: errors }, status: 400
32
34
  end
33
-
34
- def event_params
35
- full_params.permit(
36
- :id,
37
- :created_at,
38
- table: [
39
- :schema,
40
- :name
41
- ],
42
- trigger: [
43
- :name
44
- ],
45
- event: [
46
- :op,
47
- {
48
- session_variables: {},
49
- data: {
50
- new: {},
51
- old: {}
52
- }
53
- }
54
- ]
55
- )
56
- end
57
35
  end
58
36
  end
@@ -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,4 +1,9 @@
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
8
  post '/events', to: 'events#index'
4
9
  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,
@@ -16,6 +20,8 @@ module HasuraHandler
16
20
  :retry_after
17
21
 
18
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
@@ -17,11 +17,13 @@ module HasuraHandler
17
17
  end
18
18
 
19
19
  attr_reader :session_variables,
20
+ :headers,
20
21
  :input,
21
22
  :output,
22
23
  :error_message
23
24
 
24
- def initialize(session_variables, input)
25
+ def initialize(headers, session_variables, input)
26
+ @headers = headers
25
27
  @session_variables = session_variables
26
28
  @input = input
27
29
  @output = {}
@@ -0,0 +1,22 @@
1
+ module HasuraHandler
2
+ class Authenticator
3
+ attr_reader :headers
4
+ attr_accessor :response,
5
+ :error_message
6
+
7
+ def initialize(headers)
8
+ @headers = headers
9
+ @response = {}
10
+ end
11
+
12
+ def success?
13
+ begin
14
+ authenticate
15
+ ensure
16
+ return false if @response.blank?
17
+ end
18
+
19
+ @response.present? || @error_message.blank?
20
+ end
21
+ end
22
+ end
@@ -4,6 +4,7 @@ module HasuraHandler
4
4
  :table,
5
5
  :trigger,
6
6
  :event,
7
+ :op,
7
8
  :created_at,
8
9
  :raw_event,
9
10
  :errors,
@@ -11,9 +12,10 @@ module HasuraHandler
11
12
 
12
13
  def initialize(event)
13
14
  @id = event['id']
14
- @table = event['table']
15
- @trigger = event['trigger']
15
+ @table = event['table']['name']
16
+ @trigger = event['trigger']['name']
16
17
  @event = event['event']
18
+ @op = event['event']['op']
17
19
  @created_at = event['created_at']
18
20
  @raw_event = event
19
21
  @errors = {}
@@ -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
@@ -16,6 +16,8 @@ module HasuraHandler
16
16
  end
17
17
  end
18
18
 
19
+ attr_reader :event
20
+
19
21
  def initialize(event)
20
22
  @event = event
21
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,36 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hasura_handler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.8
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-26 00:00:00.000000000 Z
11
+ date: 2020-08-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 6.0.3
20
17
  - - ">="
21
18
  - !ruby/object:Gem::Version
22
- version: 6.0.3.2
19
+ version: '5.0'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - "~>"
28
- - !ruby/object:Gem::Version
29
- version: 6.0.3
30
24
  - - ">="
31
25
  - !ruby/object:Gem::Version
32
- version: 6.0.3.2
33
- description: Provides an easy way to build custom backends for Hasura.
26
+ version: '5.0'
27
+ description: HasuraHandler is a Rails framework that makes building microservices
28
+ for Hasura easy.
34
29
  email:
35
30
  - me@kaz.codes
36
31
  executables: []
@@ -42,6 +37,7 @@ files:
42
37
  - Rakefile
43
38
  - app/controllers/hasura_handler/actions_controller.rb
44
39
  - app/controllers/hasura_handler/application_controller.rb
40
+ - app/controllers/hasura_handler/auth_hook_controller.rb
45
41
  - app/controllers/hasura_handler/events_controller.rb
46
42
  - app/jobs/hasura_handler/application_job.rb
47
43
  - app/jobs/hasura_handler/event_handler_job.rb
@@ -49,16 +45,20 @@ files:
49
45
  - config/routes.rb
50
46
  - lib/hasura_handler.rb
51
47
  - lib/hasura_handler/action.rb
48
+ - lib/hasura_handler/authenticator.rb
52
49
  - lib/hasura_handler/engine.rb
53
50
  - lib/hasura_handler/event.rb
54
51
  - lib/hasura_handler/event_handler.rb
55
52
  - lib/hasura_handler/event_processor.rb
56
- - lib/hasura_handler/version.rb
57
53
  - lib/tasks/hasura_handler_tasks.rake
58
- homepage: https://github.com/KazW/HasuraHandler
54
+ homepage: https://kazw.github.io/HasuraHandler
59
55
  licenses:
60
56
  - MIT
61
- metadata: {}
57
+ metadata:
58
+ bug_tracker_uri: https://github.com/KazW/HasuraHandler/issues
59
+ documentation_uri: https://kazw.github.io/HasuraHandler
60
+ homepage_uri: https://kazw.github.io/HasuraHandler
61
+ source_code_uri: https://github.com/KazW/HasuraHandler
62
62
  post_install_message:
63
63
  rdoc_options: []
64
64
  require_paths:
@@ -74,7 +74,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  requirements: []
77
- rubygems_version: 3.1.4
77
+ rubygems_version: 3.1.2
78
78
  signing_key:
79
79
  specification_version: 4
80
80
  summary: Integrates Hasura with Rails
@@ -1,3 +0,0 @@
1
- module HasuraHandler
2
- VERSION = '0.1.3'
3
- end