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 +4 -4
- data/README.md +4 -23
- data/app/controllers/hasura_handler/actions_controller.rb +12 -6
- data/app/controllers/hasura_handler/application_controller.rb +8 -2
- data/app/controllers/hasura_handler/auth_hook_controller.rb +35 -0
- data/app/controllers/hasura_handler/events_controller.rb +7 -7
- data/app/jobs/hasura_handler/event_handler_job.rb +1 -1
- data/app/jobs/hasura_handler/event_job.rb +1 -1
- data/config/routes.rb +7 -2
- data/lib/hasura_handler.rb +14 -3
- data/lib/hasura_handler/action.rb +3 -3
- data/lib/hasura_handler/authenticator.rb +21 -0
- data/lib/hasura_handler/event.rb +12 -10
- data/lib/hasura_handler/event_handler.rb +2 -2
- data/lib/hasura_handler/event_processor.rb +7 -2
- metadata +13 -21
- data/lib/hasura_handler/version.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d39e768059737605f096e2fb1ebc03b97a30ff3c05a55a580bc4f99b96e0e60e
|
4
|
+
data.tar.gz: 9322488f0d8cd4934509279e28b824926cb1f7a14a982700c323f5c11dab5d81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 021c7736f7148d728ea3b09562051e5b3679a6b9370a127304f988274a81cf2959b012dc2b2561fb257f43c10a2e396d753ce01101d19d1c1cc300337df9da69
|
7
|
+
data.tar.gz: ddda66c93f15b46b003f063b878fc00c59adba67bc0d6ec500d1b514ad1dfd0ecedf6f761db967a146678fb442060e8dbcb4cbea0306688ef0490ac31293118f
|
data/README.md
CHANGED
@@ -1,28 +1,9 @@
|
|
1
|
-
# HasuraHandler
|
2
|
-
|
1
|
+
# HasuraHandler  [](https://github.com/KazW/HasuraHandler/actions?query=workflow%3Atests) [](https://codeclimate.com/github/KazW/HasuraHandler/maintainability) [](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
|
-
|
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
|
-
|
6
|
-
|
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[
|
12
|
-
action = klass.new(
|
13
|
-
|
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
|
-
|
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
|
-
|
6
|
-
|
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
|
-
|
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
|
)
|
data/config/routes.rb
CHANGED
@@ -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#
|
8
|
+
post '/events', to: 'events#index'
|
4
9
|
end
|
5
10
|
|
6
11
|
if HasuraHandler.actions_enabled
|
7
|
-
post '/actions', to: 'actions#
|
12
|
+
post '/actions', to: 'actions#index'
|
8
13
|
end
|
9
14
|
end
|
data/lib/hasura_handler.rb
CHANGED
@@ -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 = '
|
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
|
-
|
31
|
-
|
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
|
data/lib/hasura_handler/event.rb
CHANGED
@@ -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[
|
14
|
-
@table = event[
|
15
|
-
@trigger = event[
|
16
|
-
@event = event[
|
17
|
-
@
|
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[
|
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 |
|
39
|
-
@event.send(
|
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.
|
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-
|
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
|
-
|
34
|
-
|
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.
|
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.
|
83
|
+
rubygems_version: 3.1.2
|
92
84
|
signing_key:
|
93
85
|
specification_version: 4
|
94
86
|
summary: Integrates Hasura with Rails
|