the_captain_rails 2.1.0
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 +7 -0
- data/README.md +85 -0
- data/app/controllers/the_captain/events/webhook_controller.rb +31 -0
- data/config/routes.rb +5 -0
- data/lib/the_captain/events.rb +61 -0
- data/lib/the_captain/rails/engine.rb +15 -0
- data/lib/the_captain_rails.rb +7 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 067e4917ab8718f6a09759d82038125d823b7f26c2b89a961930045f9d400426
|
4
|
+
data.tar.gz: 79d157124ef0a1b7709dd73d5503cbfc2e4b7cb140be100c146ed169589703cc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dd80b45095569decb676aea7afa7e9bdd5e8ef0052774ff95d64d759201d20780b3e41ea127ffb8383d0d87f671f98ebf8cb08a1795272b6de9da4dbed3ec5a1
|
7
|
+
data.tar.gz: e5ae2c72bca3c5a93560bbf1a9e9005bbdacafb9a60ed4fcc290de4a32605024c0a796074362642116584e739d4698b540c59fb6e53867f18b08dc3c67d5a364
|
data/README.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# TheCaptain Rails
|
2
|
+
The gist is that this is housing Rail's specific logic for handling Captain responses and submissions in a Rails project.
|
3
|
+
|
4
|
+
Main core feature is the ability to subscribe / explicitly listen for Webhooks that a developer would like to Handel in a specific manner.
|
5
|
+
|
6
|
+
I.E. If a Webhook comes back for an IP or Content analysis. A developer may want to allow specific class handlers to manage / analyze these pieces of information differently and directed to other parts of the application.
|
7
|
+
|
8
|
+
(AKA: Single Responsibility Rule)
|
9
|
+
|
10
|
+
## Usage
|
11
|
+
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
```ruby
|
17
|
+
gem "the_captain", git: "https://github.com/VianetManagement/the-captain-ruby.git", branch: "3.0.0"
|
18
|
+
gem 'the_captain_rails', git: "https://github.com/VianetManagement/the-captain-rails"
|
19
|
+
```
|
20
|
+
|
21
|
+
|
22
|
+
## Configuration
|
23
|
+
|
24
|
+
### Webhook events
|
25
|
+
|
26
|
+
#### Configuring The Rails Router Path
|
27
|
+
|
28
|
+
Ensure we mount the controller path to handel requests.
|
29
|
+
|
30
|
+
`/config/routes.rb`
|
31
|
+
```ruby
|
32
|
+
Rails.application.routes.draw do
|
33
|
+
mount TheCaptain::Events::Engine => "/captain/events"
|
34
|
+
# ....
|
35
|
+
end
|
36
|
+
```
|
37
|
+
|
38
|
+
Your webhook endpoint will look something like `http://[HOST]/captain/events`
|
39
|
+
|
40
|
+
#### Configuring Webhook Listeners
|
41
|
+
|
42
|
+
`/config/initializer/the_captain.rb`
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
TheCaptain::Event.configure do |config|
|
46
|
+
config.subscribe("Account Abuse") { |event| ... }
|
47
|
+
|
48
|
+
# Alternatively you can also define a class that contains a `call/1` method
|
49
|
+
config.subscribe("Account Abuse", AccountManagment::Abuse.new)
|
50
|
+
|
51
|
+
# If you wish for all events to pass through a single entry point or you want to log something about any webhook
|
52
|
+
# passthrough
|
53
|
+
config.all { |event| ... }
|
54
|
+
|
55
|
+
# [again] Alternatively you can also define a class that contains a `call/1` method
|
56
|
+
config.all WebhookManager.new
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
Be default the `.subscribe/2` method will listen and attempt to parse which **Kit Name** triggered the given webhook.
|
61
|
+
|
62
|
+
You can modify the listening key by configuring the `.event_key_filter/1`
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
|
66
|
+
TheCaptain::Event.configure do |config|
|
67
|
+
config.event_key_filter = proc { |event| event.[some_key_value_in_response] }
|
68
|
+
config.subscribe([modified_filer_key_result]) { |event| }
|
69
|
+
end
|
70
|
+
|
71
|
+
```
|
72
|
+
|
73
|
+
You can also reject or accept events by modifying the `.event_filter/1`
|
74
|
+
|
75
|
+
**Note:** If the filter does not return an event. The `all` listener will not be triggered.
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
TheCaptain::Event.configure do |config|
|
79
|
+
# If the event's decision id is 1000, then ignore it (i.e.: don't return the event)
|
80
|
+
config.event_filter = proc { |event| event unless event.descition.id == 1000 }
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
## License
|
85
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TheCaptain
|
4
|
+
module Events
|
5
|
+
class WebhookController < ActionController::Base
|
6
|
+
if ::Rails.application.config.action_controller.default_protect_from_forgery
|
7
|
+
skip_before_action :verify_authenticity_token
|
8
|
+
end
|
9
|
+
|
10
|
+
# post
|
11
|
+
def event
|
12
|
+
::TheCaptain::Events.instrument(process_event)
|
13
|
+
head :ok
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def process_event
|
19
|
+
request_body = request.body.read
|
20
|
+
request_url = request.original_url
|
21
|
+
http_version = request.headers["version"] || "HTTP/1.1"
|
22
|
+
response = construct_response_from(request_body, request_url, http_version)
|
23
|
+
::TheCaptain::Response::CaptainVessel.new(response)
|
24
|
+
end
|
25
|
+
|
26
|
+
def construct_response_from(payload, uri_destination, http_version)
|
27
|
+
HTTP::Response.new(body: payload, uri: uri_destination, status: 200, version: http_version)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module TheCaptain
|
4
|
+
module Events
|
5
|
+
class << self
|
6
|
+
attr_accessor :adapter, :backend, :namespace, :event_filter, :event_key_filter
|
7
|
+
|
8
|
+
def configure
|
9
|
+
raise ArgumentError, "Must provide a block to configure events" unless block_given?
|
10
|
+
yield self
|
11
|
+
end
|
12
|
+
|
13
|
+
def subscribe(kit_name, callable = Proc.new)
|
14
|
+
backend.subscribe(namespace.to_regexp(kit_name), adapter.call(callable))
|
15
|
+
end
|
16
|
+
|
17
|
+
def all(callable = Proc.new)
|
18
|
+
subscribe(nil, callable)
|
19
|
+
end
|
20
|
+
|
21
|
+
def instrument(event)
|
22
|
+
event = event_filter.call(event)
|
23
|
+
return unless event
|
24
|
+
event_key = event_key_filter.call(event)
|
25
|
+
backend.instrument(namespace.call(event_key), event)
|
26
|
+
end
|
27
|
+
|
28
|
+
def listening?(kit_name)
|
29
|
+
namespaced_name = namespace.call(kit_name)
|
30
|
+
backend.notifier.listening?(namespaced_name)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
Namespace = Struct.new(:value, :delimiter) do
|
35
|
+
def call(name = nil)
|
36
|
+
"#{value}#{delimiter}#{name&.to_s&.tr(' ', delimiter)&.downcase}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_regexp(name = nil)
|
40
|
+
/^#{Regexp.escape(call(name))}/
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
NotificationAdapter = Struct.new(:subscriber) do
|
45
|
+
def self.call(callable)
|
46
|
+
new(callable)
|
47
|
+
end
|
48
|
+
|
49
|
+
def call(*args)
|
50
|
+
payload = args.last
|
51
|
+
subscriber.call(payload)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
self.adapter = NotificationAdapter
|
56
|
+
self.backend = ActiveSupport::Notifications
|
57
|
+
self.namespace = Namespace.new("captain_event", ".")
|
58
|
+
self.event_filter = lambda { |event| event }
|
59
|
+
self.event_key_filter = lambda { |event| event.dig(:action) }
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rails/engine"
|
4
|
+
|
5
|
+
module TheCaptain
|
6
|
+
module Events
|
7
|
+
class Engine < ::Rails::Engine
|
8
|
+
isolate_namespace TheCaptain::Events
|
9
|
+
|
10
|
+
initializer "the_captain_rails.initialize" do
|
11
|
+
require "the_captain_rails"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: the_captain_rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- George J Protacio-Karaszi
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-09-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: the_captain
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '5.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '11.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '11.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec-rails
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.5'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.5'
|
69
|
+
description: The Captain will tell, talk, and taddle on those pesky fraudulent scalliwags.
|
70
|
+
email:
|
71
|
+
- george@elevatorup.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- README.md
|
77
|
+
- app/controllers/the_captain/events/webhook_controller.rb
|
78
|
+
- config/routes.rb
|
79
|
+
- lib/the_captain/events.rb
|
80
|
+
- lib/the_captain/rails/engine.rb
|
81
|
+
- lib/the_captain_rails.rb
|
82
|
+
homepage: https://github.com/VianetManagement/the-captain-rails
|
83
|
+
licenses:
|
84
|
+
- MIT
|
85
|
+
metadata: {}
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
- app
|
91
|
+
- config
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 2.7.7
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Ruby on Rails bindings for the The Captain API
|
108
|
+
test_files: []
|