pushcart 0.0.1.proto1
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/LICENSE +20 -0
- data/README.md +7 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/pushcart/application.js +13 -0
- data/app/assets/stylesheets/pushcart/application.css +15 -0
- data/app/controllers/concerns/pushcart/getable.rb +127 -0
- data/app/controllers/concerns/pushcart/postable.rb +113 -0
- data/app/controllers/pushcart/application_controller.rb +4 -0
- data/app/controllers/pushcart/pub_sub/base_controller.rb +4 -0
- data/app/controllers/pushcart/pub_sub/subscriptions_controller.rb +8 -0
- data/app/helpers/pushcart/application_helper.rb +4 -0
- data/app/jobs/pushcart/subscription_renewal_job.rb +9 -0
- data/app/views/layouts/pushcart/application.html.erb +14 -0
- data/config/routes.rb +6 -0
- data/lib/pushcart.rb +16 -0
- data/lib/pushcart/composable.rb +10 -0
- data/lib/pushcart/connectable.rb +34 -0
- data/lib/pushcart/deliverable.rb +5 -0
- data/lib/pushcart/engine.rb +5 -0
- data/lib/pushcart/errors.rb +4 -0
- data/lib/pushcart/requestable.rb +68 -0
- data/lib/pushcart/stateable.rb +166 -0
- data/lib/pushcart/subscribable.rb +25 -0
- data/lib/pushcart/version.rb +3 -0
- data/lib/tasks/pushcart_tasks.rake +4 -0
- data/test/connectable_test.rb +24 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +13 -0
- data/test/dummy/app/assets/stylesheets/application.css +15 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/subscription.rb +9 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +26 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +41 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/config/secrets.yml +22 -0
- data/test/dummy/db/migrate/20151016222203_create_subscriptions.rb +59 -0
- data/test/dummy/db/schema.rb +51 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +0 -0
- data/test/dummy/log/test.log +5270 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/fixtures/subscriptions.yml +6 -0
- data/test/integration/content_delivery_test.rb +58 -0
- data/test/integration/hub_request_test.rb +127 -0
- data/test/pushcart_test.rb +7 -0
- data/test/requestable_test.rb +7 -0
- data/test/routes_test.rb +9 -0
- data/test/state_test.rb +13 -0
- data/test/test_helper.rb +27 -0
- metadata +349 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2621b1fb0b34606a1385ef7d7e4e3f6d4d78033e
|
4
|
+
data.tar.gz: 2ee9ce5b166dd3a51443798d01dfa263ba7b655c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fc21913f640a1ee3ec05252a765774398b5f7a6ad07bf1cb2fab09beeb4d6264396cf6a864d82f835f972965396b197fb8b5ff22dfdb17a3b9bb68833c583876
|
7
|
+
data.tar.gz: 260ee10070e9d7da4fd1391ae4bb349ec96b9d33baa2782d596175b51934e8be27575045f29ab915ce21cc3bec17e1aabfab718ed50fa99e3b1d48de3e80c03b
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2015 Chris Kalafarski
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# Pushcart
|
2
|
+
|
3
|
+
[](https://rubygems.org/gems/pushcart)
|
4
|
+
[](https://gemnasium.com/scour/pushcart)
|
5
|
+
[](https://travis-ci.org/scour/pushcart)
|
6
|
+
[](https://codeclimate.com/github/scour/pushcart)
|
7
|
+
[](https://coveralls.io/github/scour/pushcart?branch=master)
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
begin
|
2
|
+
require "bundler/setup"
|
3
|
+
rescue LoadError
|
4
|
+
puts "You must `gem install bundler` and `bundle install` to run rake tasks"
|
5
|
+
end
|
6
|
+
|
7
|
+
require "rdoc/task"
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = "rdoc"
|
11
|
+
rdoc.title = "Pushcart"
|
12
|
+
rdoc.options << "--line-numbers"
|
13
|
+
rdoc.rdoc_files.include("README.rdoc")
|
14
|
+
rdoc.rdoc_files.include("lib/**/*.rb")
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
18
|
+
load "rails/tasks/engine.rake"
|
19
|
+
|
20
|
+
load "rails/tasks/statistics.rake"
|
21
|
+
|
22
|
+
Bundler::GemHelper.install_tasks
|
23
|
+
|
24
|
+
require "rake/testtask"
|
25
|
+
|
26
|
+
Rake::TestTask.new(:test) do |t|
|
27
|
+
t.libs << "lib"
|
28
|
+
t.libs << "test"
|
29
|
+
t.pattern = "test/**/*_test.rb"
|
30
|
+
t.verbose = false
|
31
|
+
end
|
32
|
+
|
33
|
+
task :console do
|
34
|
+
require "pry"
|
35
|
+
require "pushcart"
|
36
|
+
ARGV.clear
|
37
|
+
Pry.start
|
38
|
+
end
|
39
|
+
|
40
|
+
task default: :test
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any styles
|
10
|
+
* defined in the other CSS/SCSS files in this directory. It is generally better to create a new
|
11
|
+
* file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,127 @@
|
|
1
|
+
module Pushcart
|
2
|
+
# Hubs send GET requests to a subscription's callback URL in several
|
3
|
+
# cases:
|
4
|
+
|
5
|
+
# * To indicate that a publisher determined the a subscription
|
6
|
+
# request should not accepted and the subscription is being denied
|
7
|
+
# * To notify the subscriber that a previously accepted subscription is now
|
8
|
+
# being denied
|
9
|
+
# * To verify that the subscriber sent a previously received request to
|
10
|
+
# subscribe or unsubscribe to a given topic
|
11
|
+
#
|
12
|
+
# Hubs do not expect a response in the case of denials. Intent verification
|
13
|
+
# responses MUST be 2xx with a body equal to the `hub.challenge` parameter
|
14
|
+
# if the subscriber is verifying the intent, otherwise a 404 response MUST
|
15
|
+
# be sent.
|
16
|
+
module Getable
|
17
|
+
extend ActiveSupport::Concern
|
18
|
+
|
19
|
+
included do
|
20
|
+
before_action :expecting_callback, only: :get
|
21
|
+
before_action :validate_callback_params, only: :get
|
22
|
+
end
|
23
|
+
|
24
|
+
def get
|
25
|
+
subscription_denied? ? subscription_denied_get : intent_verification_get
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def subscription_denied_get
|
31
|
+
# TODO add support for Location Header?
|
32
|
+
|
33
|
+
# @subscription.deny!(reason: params['hub.reason'])
|
34
|
+
render status: 200, nothing: true
|
35
|
+
end
|
36
|
+
|
37
|
+
def intent_verification_get
|
38
|
+
if subscribe_intent_verification?
|
39
|
+
subscribe_intent_verification_get
|
40
|
+
elsif unsubscribe_intent_verification?
|
41
|
+
unsubscribe_intent_verification_get
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def subscribe_intent_verification_get
|
46
|
+
# TODO
|
47
|
+
end
|
48
|
+
|
49
|
+
def unsubscribe_intent_verification_get
|
50
|
+
# TODO
|
51
|
+
end
|
52
|
+
|
53
|
+
def expecting_callback
|
54
|
+
# TODO
|
55
|
+
# unless expecting_any_callback
|
56
|
+
# render status: 404, nothing: true
|
57
|
+
# end
|
58
|
+
end
|
59
|
+
|
60
|
+
def expecting_any_callback
|
61
|
+
expecting_subscribe_callback ||
|
62
|
+
expecting_unsubscribe_callback ||
|
63
|
+
expecting_denied_callback
|
64
|
+
end
|
65
|
+
|
66
|
+
def expecting_subscribe_callback
|
67
|
+
# TODO
|
68
|
+
end
|
69
|
+
|
70
|
+
def expecting_unsubscribe_callback
|
71
|
+
# TODO
|
72
|
+
end
|
73
|
+
|
74
|
+
def expecting_denied_callback
|
75
|
+
# TODO
|
76
|
+
end
|
77
|
+
|
78
|
+
# `The hub.mode` and `hub.topic` parameters are required for all GET
|
79
|
+
# requests made to a subscription's callback URL. The `hub.topic` value
|
80
|
+
# must match the topic of the subscription that originally registered the
|
81
|
+
# subscription, and the only valid `hub.mode` values are "subscribe",
|
82
|
+
# "unsubscribe", and "denied".
|
83
|
+
def validate_callback_params
|
84
|
+
unless validate_callback_params_topic && validate_callback_params_mode
|
85
|
+
render status: 404, nothing: true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def validate_callback_params_topic
|
90
|
+
params["hob.topic"] && params["hob.topic"] == @subscription.topic
|
91
|
+
end
|
92
|
+
|
93
|
+
def validate_callback_params_mode
|
94
|
+
validate_denied_callback_params_mode ||
|
95
|
+
validate_subscribe_callback_params_mode ||
|
96
|
+
validate_unsubscribe_callback_params_mode
|
97
|
+
end
|
98
|
+
|
99
|
+
def validate_denied_callback_params_mode
|
100
|
+
params["hub.mode"] == "denied"
|
101
|
+
end
|
102
|
+
alias_method :subscription_denied?, :validate_denied_callback_params_mode
|
103
|
+
|
104
|
+
def validate_subscribe_callback_params_mode
|
105
|
+
params["hub.mode"] == "subscribe" &&
|
106
|
+
!params["hub.challenge"].blank? &&
|
107
|
+
!params["hub.lease_seconds"].blank?
|
108
|
+
end
|
109
|
+
|
110
|
+
def validate_unsubscribe_callback_params_mode
|
111
|
+
params["hub.mode"] == "unsubscribe" &&
|
112
|
+
!params["hub.challenge"].blank?
|
113
|
+
end
|
114
|
+
|
115
|
+
def intent_verification?
|
116
|
+
subscribe_intent_verification? || unsubscribe_intent_verification?
|
117
|
+
end
|
118
|
+
|
119
|
+
def subscribe_intent_verification?
|
120
|
+
params["hub.mode"] == "subscribe"
|
121
|
+
end
|
122
|
+
|
123
|
+
def unsubscribe_intent_verification?
|
124
|
+
params["hub.mode"] == "unsubscribe"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
require "link_header"
|
2
|
+
|
3
|
+
module Pushcart
|
4
|
+
# The only case where a POST request is sent to a subscription's callback
|
5
|
+
# URL is when the hub is attempting to deliver new content. The hub MAY
|
6
|
+
# distribute content as a diff between two consecutive versions of the
|
7
|
+
# content being delivered. The request MUST have a `Content-Type`
|
8
|
+
# corresponding to the type of the topic, and MUST include a Link Header
|
9
|
+
# with `rel=hub` pointing to the hub and `rel=self` set to the topic that's
|
10
|
+
# being updated.
|
11
|
+
#
|
12
|
+
# Any response other than 2xx, including redirects, could be considered by
|
13
|
+
# the hub to be a failure, and deliveries could be retried. The body of
|
14
|
+
# this response will be ignored by the hub. A 2xx response should be sent as
|
15
|
+
# soon as the payload arrives, even if it has not been processed yet, or
|
16
|
+
# processing fails.
|
17
|
+
module Postable
|
18
|
+
extend ActiveSupport::Concern
|
19
|
+
|
20
|
+
included do
|
21
|
+
before_action :expecting_content_distribution, only: :post
|
22
|
+
before_action :verify_content_type, only: :post
|
23
|
+
before_action :verify_link_headers, only: :post
|
24
|
+
before_action :authenticate_content_distribution, only: :post
|
25
|
+
end
|
26
|
+
|
27
|
+
def post
|
28
|
+
# TODO
|
29
|
+
# @subscription.process_content_distribution_payload()
|
30
|
+
render status: 202, nothing: true
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
# Ensure that the given subscription is in a state where it is expecting to
|
36
|
+
# receive content from a hub
|
37
|
+
def expecting_content_distribution
|
38
|
+
# unless request.content_type == @subscription.active?
|
39
|
+
# render status: 400, nothing: true
|
40
|
+
# end
|
41
|
+
end
|
42
|
+
|
43
|
+
# https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#contentdistribution
|
44
|
+
# This request MUST have a Content-Type corresponding to the type of the
|
45
|
+
# topic.
|
46
|
+
def verify_content_type
|
47
|
+
# unless request.content_type == @subscription.topic_content_type
|
48
|
+
# render status: 400, nothing: true
|
49
|
+
# end
|
50
|
+
end
|
51
|
+
|
52
|
+
# https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#contentdistribution
|
53
|
+
# The request MUST include a Link Header [RFC5988] with rel=hub pointing to
|
54
|
+
# the Hub as well as a Link Header [RFC5988] with rel=self set to the topic
|
55
|
+
# that's being updated. The Hub SHOULD combine both headers into a single
|
56
|
+
# Link Header [RFC5988].
|
57
|
+
def verify_link_headers
|
58
|
+
# unless verify_link_header(:hub, @subscription.hub) &&
|
59
|
+
# verify_link_header(:self, @subscription.topic)
|
60
|
+
# render status: 400, nothing: true
|
61
|
+
# end
|
62
|
+
end
|
63
|
+
|
64
|
+
def verify_link_header(rel, value)
|
65
|
+
links = LinkHeader.parse(request.headers["Link"]).to_a
|
66
|
+
!links.detect { |l| l[1][0][1] == rel.to_s && l[0] == value }.empty?
|
67
|
+
end
|
68
|
+
|
69
|
+
# https://pubsubhubbub.github.io/PubSubHubbub/pubsubhubbub-core-0.4.html#authednotify
|
70
|
+
# If the subscriber supplied a value for hub.secret in their subscription
|
71
|
+
# request, the hub MUST generate an HMAC signature of the payload and
|
72
|
+
# include that signature in the request headers of the content distribution
|
73
|
+
# request. The X-Hub-Signature header's value MUST be in the form
|
74
|
+
# sha1=signature where signature is a 40-byte, hexadecimal representation of
|
75
|
+
# a SHA1 signature [RFC3174]. The signature MUST be computed using the HMAC
|
76
|
+
# algorithm [RFC2104] with the request body as the data and the hub.secret
|
77
|
+
# as the key.
|
78
|
+
#
|
79
|
+
# When subscribers receive a content distribution request with the
|
80
|
+
# X-Hub-Signature header specified, they SHOULD recompute the SHA1 signature
|
81
|
+
# with the shared secret using the same method as the hub. If the signature
|
82
|
+
# does not match, subscribers MUST still return a 2xx success response to
|
83
|
+
# acknowledge receipt, but locally ignore the message as invalid. Using this
|
84
|
+
# technique along with HTTPS [RFC2818] for subscription requests enables
|
85
|
+
# simple subscribers to receive authenticated notifications from hubs
|
86
|
+
# without the need for subscribers to run an HTTPS [RFC2818] server.
|
87
|
+
def authenticate_content_distribution
|
88
|
+
# The PuSH 0.4 spec does not explicitly say what to do when a hub is
|
89
|
+
# required to send a signature and it does not.
|
90
|
+
unless request.headers["X-Hub-Signature"] =~ /sha1=./
|
91
|
+
render status: 403, nothing: true
|
92
|
+
return
|
93
|
+
end
|
94
|
+
|
95
|
+
hub_signature = request.headers["X-Hub-Signature"].split("=")[1]
|
96
|
+
body = request.body.read
|
97
|
+
|
98
|
+
# TODO Do this check on the model
|
99
|
+
digest = OpenSSL::Digest::SHA1.new
|
100
|
+
key = @subscription.hmac_secret_key # TODO
|
101
|
+
data = body
|
102
|
+
hmac = OpenSSL::HMAC.hexdigest(digest, key, data)
|
103
|
+
|
104
|
+
unless hmac == hub_signature
|
105
|
+
# If the signature does not match, subscribers MUST still return a 2xx
|
106
|
+
# success response to acknowledge receipt...
|
107
|
+
# (but exit, because we don't want to process the data)
|
108
|
+
# render status: 202, nothing: true
|
109
|
+
return
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Pushcart</title>
|
5
|
+
<%= stylesheet_link_tag "pushcart/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "pushcart/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
ADDED
data/lib/pushcart.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "aasm"
|
2
|
+
require "excon"
|
3
|
+
require "faraday"
|
4
|
+
require "link_header"
|
5
|
+
require "validate_url"
|
6
|
+
require "pushcart/engine"
|
7
|
+
require "pushcart/errors"
|
8
|
+
require "pushcart/connectable"
|
9
|
+
require "pushcart/deliverable"
|
10
|
+
require "pushcart/requestable"
|
11
|
+
require "pushcart/stateable"
|
12
|
+
require "pushcart/composable"
|
13
|
+
require "pushcart/subscribable"
|
14
|
+
|
15
|
+
module Pushcart
|
16
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Pushcart
|
2
|
+
module Connectable
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def callback_uri
|
6
|
+
raise ConfigurationError, "Incomplete callback URI configuration" if !ENV["PUSH_CALLBACK_SCHEME"] || !ENV["PUSH_CALLBACK_HOST"] || !ENV["PUSH_CALLBACK_PORT"]
|
7
|
+
raise ArgumentError, "ID required for callback URI" if !id
|
8
|
+
|
9
|
+
scheme = ENV["PUSH_CALLBACK_SCHEME"]
|
10
|
+
host = ENV["PUSH_CALLBACK_HOST"]
|
11
|
+
port = ENV["PUSH_CALLBACK_PORT"].to_i
|
12
|
+
path = "/subscriptions/#{id}/callback"
|
13
|
+
|
14
|
+
components = { host: host, port: port, path: path }
|
15
|
+
(scheme == "https" ? URI::HTTPS : URI::HTTP).build(components)
|
16
|
+
end
|
17
|
+
|
18
|
+
def connection(mode:)
|
19
|
+
# TODO Better error
|
20
|
+
raise "Missing" if !callback_uri || !mode || !topic || !hmac_secret_key
|
21
|
+
|
22
|
+
Faraday.new do |conn|
|
23
|
+
conn.adapter Faraday.default_adapter
|
24
|
+
conn.request :url_encoded
|
25
|
+
conn.params = {
|
26
|
+
"hub.callback": callback_uri.to_s,
|
27
|
+
"hub.mode": mode,
|
28
|
+
"hub.topic": topic,
|
29
|
+
"hub.secret": hmac_secret_key
|
30
|
+
}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|