ribbon-intercom 0.3.4 → 0.4.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 +4 -4
- data/lib/ribbon/intercom.rb +1 -0
- data/lib/ribbon/intercom/client/sdk.rb +28 -24
- data/lib/ribbon/intercom/client/sdk/adapters/adapter.rb +17 -6
- data/lib/ribbon/intercom/client/sdk/adapters/adapter/response.rb +2 -27
- data/lib/ribbon/intercom/client/sdk/adapters/http_adapter.rb +6 -4
- data/lib/ribbon/intercom/client/sdk/adapters/local_adapter.rb +5 -4
- data/lib/ribbon/intercom/errors.rb +5 -0
- data/lib/ribbon/intercom/package.rb +22 -22
- data/lib/ribbon/intercom/packageable/mixin.rb +0 -4
- data/lib/ribbon/intercom/packet.rb +52 -0
- data/lib/ribbon/intercom/packet/method_queue.rb +28 -0
- data/lib/ribbon/intercom/service.rb +66 -47
- data/lib/ribbon/intercom/service/channel/stores/redis_store.rb +17 -7
- data/lib/ribbon/intercom/utils.rb +4 -1
- data/lib/ribbon/intercom/utils/method_chain.rb +38 -0
- data/lib/ribbon/intercom/version.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dbc66058ef3f67f202ae929f759b20a1ca45a0f7
|
4
|
+
data.tar.gz: d5eee408147e0cf447120c6f2ee8150cba30cec9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed1f4b07d38b1fca0657cc08ec4fac171ae9fc65a7132f9afe4f46a9043d6104d4fec26ade902ab93bed155102365fdf56518dfbf93b0a2695805173b8d834b3
|
7
|
+
data.tar.gz: 723e68476ea49afd0cf055e2ce6adcfb8636ea6c7d12625abfa9ff2486a1502bc4507af01a7fbfc5f4d8935ee1b0bc82de2a9e223547e99ec9513a6cd9e8fe81
|
data/lib/ribbon/intercom.rb
CHANGED
@@ -9,6 +9,7 @@ module Ribbon
|
|
9
9
|
autoload(:Client, 'ribbon/intercom/client')
|
10
10
|
autoload(:Package, 'ribbon/intercom/package')
|
11
11
|
autoload(:Packageable, 'ribbon/intercom/packageable')
|
12
|
+
autoload(:Packet, 'ribbon/intercom/packet')
|
12
13
|
autoload(:Utils, 'ribbon/intercom/utils')
|
13
14
|
|
14
15
|
module_function
|
@@ -18,6 +18,14 @@ module Ribbon::Intercom
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
def begin
|
22
|
+
Utils::MethodChain.begin { |methods|
|
23
|
+
queue = Packet::MethodQueue.new
|
24
|
+
methods.each { |meth, *args| queue.enqueue(meth, *args) }
|
25
|
+
send_packet(method_queue: queue).retval
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
21
29
|
##
|
22
30
|
# Returns the headers defined for this SDK. Optionally, you may also define
|
23
31
|
# additional headers you'd like to add/override.
|
@@ -34,11 +42,19 @@ module Ribbon::Intercom
|
|
34
42
|
end
|
35
43
|
|
36
44
|
##
|
37
|
-
# Calls the method on the adapter returning the
|
45
|
+
# Calls the method on the adapter returning the response Packet
|
46
|
+
def call(method_name, *args)
|
47
|
+
send_packet(
|
48
|
+
method_queue: Packet::MethodQueue.new.enqueue(method_name, *args)
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Sends the packet with the adapter, returning the response Packet.
|
38
54
|
#
|
39
55
|
# Intended to be called by Package.
|
40
|
-
def
|
41
|
-
_process_response(adapter.
|
56
|
+
def send_packet(packet)
|
57
|
+
_process_response(adapter.send_packet(packet))
|
42
58
|
end
|
43
59
|
|
44
60
|
def dup
|
@@ -64,32 +80,20 @@ module Ribbon::Intercom
|
|
64
80
|
end
|
65
81
|
|
66
82
|
##
|
67
|
-
# Process
|
68
|
-
def _process_response(
|
69
|
-
_handle_response_error(
|
83
|
+
# Process a Packet object returned by Adapter#send_packet.
|
84
|
+
def _process_response(packet)
|
85
|
+
_handle_response_error(packet) if packet.error?
|
70
86
|
|
71
|
-
_init_packages(
|
72
|
-
|
87
|
+
_init_packages(packet.retval)
|
88
|
+
packet
|
73
89
|
end
|
74
90
|
|
75
91
|
##
|
76
92
|
# Raises an error depending on what went wrong.
|
77
|
-
def _handle_response_error(
|
78
|
-
raise '
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
if encoded_error && !encoded_error.empty?
|
83
|
-
begin
|
84
|
-
decoded_error = Base64.strict_decode64(encoded_error)
|
85
|
-
error = Marshal.load(decoded_error)
|
86
|
-
rescue
|
87
|
-
error = Errors::ServerError.new('unknown server error')
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
raise error || Errors::ServerError.new('unexpected server error')
|
92
|
-
end # _handle_response
|
93
|
+
def _handle_response_error(packet)
|
94
|
+
raise 'packet contains no error' unless packet.error?
|
95
|
+
raise packet.error
|
96
|
+
end
|
93
97
|
|
94
98
|
##
|
95
99
|
# Walks the object and initializes all packages (i.e., sets them up to be
|
@@ -9,11 +9,22 @@ module Ribbon::Intercom
|
|
9
9
|
|
10
10
|
##
|
11
11
|
# Call the method on the service.
|
12
|
+
#
|
13
|
+
# @deprecated This method is only called by tests. Don't call it elsewhere.
|
12
14
|
def call(method_name, *args)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
send_packet(
|
16
|
+
method_queue: Packet::MethodQueue.new.enqueue(method_name, *args)
|
17
|
+
)
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Send a packet to the service and returns the Packet returned by the service.
|
22
|
+
def send_packet(packet)
|
23
|
+
packet = Packet.new(packet) if packet.is_a?(Hash)
|
24
|
+
|
25
|
+
send_packet!(packet.encode).tap { |response|
|
26
|
+
raise TypeError, "send_packet! should return an Adapter::Response" unless response.is_a?(Response)
|
27
|
+
}.packet
|
17
28
|
end
|
18
29
|
|
19
30
|
##
|
@@ -43,8 +54,8 @@ module Ribbon::Intercom
|
|
43
54
|
end
|
44
55
|
|
45
56
|
##
|
46
|
-
# Actually
|
47
|
-
def
|
57
|
+
# Actually send the packet to the service. Should return an Adapter::Response object.
|
58
|
+
def send_packet!(packet)
|
48
59
|
raise NotImplementedError
|
49
60
|
end
|
50
61
|
|
@@ -1,37 +1,12 @@
|
|
1
1
|
module Ribbon::Intercom
|
2
2
|
class Client::SDK::Adapters::Adapter
|
3
3
|
class Response < Rack::Response
|
4
|
-
attr_reader :method_name
|
5
|
-
|
6
|
-
def initialize(body, status, headers, method_name)
|
7
|
-
super(body, status, headers)
|
8
|
-
@method_name = method_name.to_sym
|
9
|
-
end
|
10
|
-
|
11
|
-
def missing_permissions
|
12
|
-
@__missing_permissions ||= _intercom_permissions_missing
|
13
|
-
end
|
14
|
-
|
15
4
|
def body
|
16
5
|
super.join
|
17
6
|
end
|
18
7
|
|
19
|
-
|
20
|
-
|
21
|
-
def retval
|
22
|
-
@__retval ||= Marshal.load(Base64.strict_decode64(body)) unless body.empty?
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def _intercom_permissions_missing
|
28
|
-
key = _intercom_permissions_missing_header
|
29
|
-
headers[key] && headers[key].split(',').to_set
|
30
|
-
end
|
31
|
-
|
32
|
-
def _intercom_permissions_missing_header
|
33
|
-
missing_keys = ['X-Intercom-Permissions-Missing', :x_intercom_permissions_missing]
|
34
|
-
missing_keys.detect { |key| headers.key?(key) }
|
8
|
+
def packet
|
9
|
+
@__packet ||= Packet.decode(body) unless body.empty?
|
35
10
|
end
|
36
11
|
end # Response
|
37
12
|
end # Client::SDK::Adapters::Adapter
|
@@ -17,13 +17,15 @@ module Ribbon::Intercom
|
|
17
17
|
@__connection ||= Connection.new(*@_connection_args)
|
18
18
|
end
|
19
19
|
|
20
|
-
|
20
|
+
##
|
21
|
+
# Send the encoded packet up to the service via an HTTP PUT.
|
22
|
+
def send_packet!(encoded_packet)
|
21
23
|
response = connection.put(
|
22
|
-
headers: headers
|
23
|
-
body:
|
24
|
+
headers: headers,
|
25
|
+
body: encoded_packet
|
24
26
|
)
|
25
27
|
|
26
|
-
Adapter::Response.new(response.body, response.code.to_i, response
|
28
|
+
Adapter::Response.new(response.body, response.code.to_i, response)
|
27
29
|
end
|
28
30
|
end # HttpAdapter
|
29
31
|
end # Client::SDK::Adapters
|
@@ -23,17 +23,18 @@ module Ribbon::Intercom
|
|
23
23
|
!!service
|
24
24
|
end
|
25
25
|
|
26
|
-
|
26
|
+
##
|
27
|
+
# Mimics an HTTP PUT
|
28
|
+
def send_packet!(encoded_packet)
|
27
29
|
response = service.call(
|
28
30
|
_http_headers.merge(
|
29
31
|
'HTTP_AUTHORIZATION' => _http_auth,
|
30
|
-
'HTTP_X_INTERCOM_METHOD' => method_name.to_s,
|
31
32
|
'REQUEST_METHOD' => 'PUT',
|
32
|
-
'rack.input' => StringIO.new(
|
33
|
+
'rack.input' => StringIO.new(encoded_packet)
|
33
34
|
)
|
34
35
|
)
|
35
36
|
|
36
|
-
Response.new(response[2], response[0], response[1]
|
37
|
+
Adapter::Response.new(response[2], response[0], response[1])
|
37
38
|
end
|
38
39
|
|
39
40
|
private
|
@@ -7,20 +7,20 @@ module Ribbon::Intercom
|
|
7
7
|
attr_reader :sdk
|
8
8
|
|
9
9
|
def initialize(subject_data=nil, data=nil)
|
10
|
-
|
10
|
+
@_subject_data = subject_data
|
11
11
|
@_data = data
|
12
12
|
end
|
13
13
|
|
14
14
|
def sdk=(sdk)
|
15
|
-
_set_sdk_headers(sdk)
|
16
15
|
@sdk = sdk
|
17
16
|
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
18
|
+
def begin
|
19
|
+
Utils::MethodChain.begin { |methods|
|
20
|
+
queue = Packet::MethodQueue.new
|
21
|
+
methods.each { |meth, *args| queue.enqueue(meth, *args) }
|
22
|
+
_send_method_queue(queue)
|
23
|
+
}
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
@@ -29,35 +29,35 @@ module Ribbon::Intercom
|
|
29
29
|
if @_data && @_data.key?(meth)
|
30
30
|
@_data[meth]
|
31
31
|
elsif sdk
|
32
|
-
|
32
|
+
_send_method_queue(Packet::MethodQueue.new.enqueue(meth, *args))
|
33
33
|
else
|
34
34
|
super
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
def _send_method_queue(method_queue)
|
39
|
+
_process_response(
|
40
|
+
sdk.send_packet(
|
41
|
+
subject: @_subject_data,
|
42
|
+
method_queue: method_queue
|
43
|
+
)
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
38
47
|
def marshal_dump
|
39
48
|
[@_subject_data, @_data]
|
40
49
|
end
|
41
50
|
|
42
51
|
def marshal_load(array)
|
43
|
-
|
52
|
+
@_subject_data = array[0]
|
44
53
|
@_data = array[1]
|
45
54
|
end
|
46
55
|
|
47
|
-
def
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
def _process_response(response)
|
52
|
-
self._subject_data = response.headers['X-Intercom-Subject']
|
53
|
-
@_data = _retrieve_data_from_response(response)
|
54
|
-
|
55
|
-
response.retval
|
56
|
-
end
|
56
|
+
def _process_response(packet)
|
57
|
+
@_subject_data = packet.subject
|
58
|
+
@_data = packet.package_data
|
57
59
|
|
58
|
-
|
59
|
-
encoded_data = response.headers['X-Intercom-Package-Data']
|
60
|
-
encoded_data && Marshal.load(Base64.strict_decode64(encoded_data))
|
60
|
+
packet.retval
|
61
61
|
end
|
62
62
|
end # Package
|
63
63
|
end # Ribbon::Intercom
|
@@ -26,10 +26,6 @@ module Ribbon::Intercom
|
|
26
26
|
self.class._package_with_methods.map { |meth| [meth, public_send(meth)] }.to_h
|
27
27
|
)
|
28
28
|
end
|
29
|
-
|
30
|
-
def encoded_package_data
|
31
|
-
Base64.strict_encode64(Marshal.dump(package_data))
|
32
|
-
end
|
33
29
|
end # Mixin
|
34
30
|
end # Service::Subject
|
35
31
|
end # Ribbon::Intercom
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'base64'
|
3
|
+
|
4
|
+
module Ribbon::Intercom
|
5
|
+
##
|
6
|
+
# Represents a collection of data to be passed between the service and client.
|
7
|
+
class Packet < OpenStruct
|
8
|
+
autoload(:MethodQueue, 'ribbon/intercom/packet/method_queue')
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def decode(encoded_packet)
|
12
|
+
hash = Marshal.load(Base64.strict_decode64(encoded_packet))
|
13
|
+
raise Errors::InvalidEncodingError, hash.inspect unless hash.is_a?(Hash)
|
14
|
+
new(hash)
|
15
|
+
end
|
16
|
+
end # Class Methods
|
17
|
+
|
18
|
+
def initialize(params={})
|
19
|
+
error = params.delete(:error)
|
20
|
+
super(params)
|
21
|
+
self.error = error if error
|
22
|
+
end
|
23
|
+
|
24
|
+
##
|
25
|
+
# Encode (marshal) the error before saving it. This allows the error to be
|
26
|
+
# decoded on the client when requested, rather than decoded at the same time
|
27
|
+
# the packet is decoded, which could cause problems if the error class doesn't
|
28
|
+
# exist on the client.
|
29
|
+
def error=(err)
|
30
|
+
self._encoded_error = Marshal.dump(err)
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# Decode the error, which may not exist on the client.
|
35
|
+
# If the error class doesn't exist on the client, raise a ServerError.
|
36
|
+
def error
|
37
|
+
error? && Marshal.load(_encoded_error)
|
38
|
+
rescue
|
39
|
+
Errors::ServerError.new('unknown server error')
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Whether the packet contains an error
|
44
|
+
def error?
|
45
|
+
!!_encoded_error
|
46
|
+
end
|
47
|
+
|
48
|
+
def encode
|
49
|
+
Base64.strict_encode64(Marshal.dump(to_h))
|
50
|
+
end
|
51
|
+
end # Packet
|
52
|
+
end # Ribbon::Intercom
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Ribbon::Intercom
|
2
|
+
class Packet
|
3
|
+
class MethodQueue
|
4
|
+
##
|
5
|
+
# Enqueue a method with it's arguments.
|
6
|
+
# Supports method chaining.
|
7
|
+
def enqueue(name, *args)
|
8
|
+
self.tap { _queue << [name, *Utils.sanitize(args)] }
|
9
|
+
end
|
10
|
+
|
11
|
+
##
|
12
|
+
# Iterate through the methods and arguments.
|
13
|
+
def each(&block)
|
14
|
+
_queue.each(&block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def empty?
|
18
|
+
_queue.empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def _queue
|
24
|
+
@__queue ||= []
|
25
|
+
end
|
26
|
+
end # MethodQueue
|
27
|
+
end # Packet
|
28
|
+
end # Ribbon::Intercom
|
@@ -44,6 +44,7 @@ module Ribbon::Intercom
|
|
44
44
|
attr_reader :request
|
45
45
|
attr_reader :channel
|
46
46
|
attr_reader :subject
|
47
|
+
attr_reader :request_packet
|
47
48
|
attr_reader :env
|
48
49
|
|
49
50
|
def initialize(opts={})
|
@@ -65,8 +66,8 @@ module Ribbon::Intercom
|
|
65
66
|
store.lookup_channel(token)
|
66
67
|
end
|
67
68
|
|
68
|
-
def sufficient_permissions?(intercom_method)
|
69
|
-
channel.may?(Utils.method_identifier(
|
69
|
+
def sufficient_permissions?(base, intercom_method)
|
70
|
+
Utils.basic_type?(base) || channel.may?(Utils.method_identifier(base, intercom_method))
|
70
71
|
end
|
71
72
|
|
72
73
|
def call(env)
|
@@ -78,8 +79,7 @@ module Ribbon::Intercom
|
|
78
79
|
|
79
80
|
response = catch(:response) {
|
80
81
|
begin
|
81
|
-
|
82
|
-
_call_method(intercom_method, *args)
|
82
|
+
_process_request
|
83
83
|
rescue Exception => error
|
84
84
|
_respond_with_error!(error)
|
85
85
|
end
|
@@ -97,8 +97,10 @@ module Ribbon::Intercom
|
|
97
97
|
def _process_request
|
98
98
|
_init_request
|
99
99
|
_authenticate_request!
|
100
|
+
_load_request_packet
|
100
101
|
_load_subject
|
101
|
-
|
102
|
+
response_packet = _process_methods
|
103
|
+
_respond_with_packet(response_packet)
|
102
104
|
end
|
103
105
|
|
104
106
|
def _init_request
|
@@ -115,8 +117,12 @@ module Ribbon::Intercom
|
|
115
117
|
end
|
116
118
|
end
|
117
119
|
|
120
|
+
def _load_request_packet
|
121
|
+
@request_packet = Packet.decode(request.body.read)
|
122
|
+
end
|
123
|
+
|
118
124
|
def _load_subject
|
119
|
-
if (encoded_subject=
|
125
|
+
if (encoded_subject=request_packet.subject) && !encoded_subject.empty?
|
120
126
|
@subject = _decode_subject(encoded_subject)
|
121
127
|
_error!(Errors::InvalidSubjectSignatureError) unless @subject
|
122
128
|
else
|
@@ -124,35 +130,27 @@ module Ribbon::Intercom
|
|
124
130
|
end
|
125
131
|
end
|
126
132
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
def _load_args
|
134
|
-
_decode_args(request.body.read)
|
135
|
-
rescue Errors::UnsafeValueError
|
136
|
-
_error!(Errors::UnsafeArgumentError, "One or more argument type is invalid.")
|
133
|
+
##
|
134
|
+
# Calls requested methods and returns a response packet for the client.
|
135
|
+
def _process_methods
|
136
|
+
retval = _call_methods
|
137
|
+
_prepare_response_packet(retval)
|
137
138
|
end
|
138
139
|
|
139
140
|
##
|
140
|
-
# Call the
|
141
|
-
def
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
headers['X-Intercom-Package-Data'] = subject.encoded_package_data
|
152
|
-
end
|
153
|
-
end
|
141
|
+
# Call all the methods in the method queue.
|
142
|
+
def _call_methods
|
143
|
+
method_queue = _load_method_queue
|
144
|
+
|
145
|
+
intercom_method = nil
|
146
|
+
base = subject
|
147
|
+
method_queue.each { |meth, *args|
|
148
|
+
intercom_method = meth
|
149
|
+
_sufficient_permissions!(base, meth)
|
150
|
+
base = base.public_send(meth, *args)
|
151
|
+
}
|
154
152
|
|
155
|
-
|
153
|
+
_package(base)
|
156
154
|
rescue NoMethodError => error
|
157
155
|
if error.name == intercom_method
|
158
156
|
_error!(Errors::InvalidMethodError, intercom_method)
|
@@ -161,6 +159,36 @@ module Ribbon::Intercom
|
|
161
159
|
end
|
162
160
|
end
|
163
161
|
|
162
|
+
def _load_method_queue
|
163
|
+
request_packet.method_queue.tap { |mq|
|
164
|
+
raise "No method queue given" unless mq
|
165
|
+
raise "Expected MethodQueue, got: #{mq.inspect}" unless mq.is_a?(Packet::MethodQueue)
|
166
|
+
raise "Empty MethodQueue" if mq.empty?
|
167
|
+
}
|
168
|
+
end
|
169
|
+
|
170
|
+
##
|
171
|
+
# Creates a successful response Packet to be returned to the client.
|
172
|
+
def _prepare_response_packet(retval)
|
173
|
+
Packet.new.tap { |packet|
|
174
|
+
unless self == subject # Order matters here! See: issue#52
|
175
|
+
# Need to send subject back in case it was modified by the methods.
|
176
|
+
packet.subject = _encode_subject(subject)
|
177
|
+
|
178
|
+
if subject.is_a?(Packageable::Mixin)
|
179
|
+
# Need to send the package data back in case it changed, too.
|
180
|
+
packet.package_data = subject.package_data
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
packet.retval = retval
|
185
|
+
}
|
186
|
+
end
|
187
|
+
|
188
|
+
def _respond_with_packet(packet, status=200)
|
189
|
+
_respond!(status, {}, packet.encode)
|
190
|
+
end
|
191
|
+
|
164
192
|
##
|
165
193
|
# Package up any non-basic objects that include Packageable::Mixin.
|
166
194
|
def _package(object)
|
@@ -187,14 +215,13 @@ module Ribbon::Intercom
|
|
187
215
|
##
|
188
216
|
# Marshal dumps the subject and signs the resulting bytes with the channel.
|
189
217
|
def _encode_subject(subject)
|
190
|
-
|
218
|
+
channel.sign(Marshal.dump(subject))
|
191
219
|
end
|
192
220
|
|
193
221
|
##
|
194
222
|
# Decodes the subject sent from the client.
|
195
223
|
def _decode_subject(encoded_subject)
|
196
|
-
|
197
|
-
marshalled_subject = channel.verify(signed_subject)
|
224
|
+
marshalled_subject = channel.verify(encoded_subject)
|
198
225
|
marshalled_subject && Marshal.load(marshalled_subject)
|
199
226
|
end
|
200
227
|
|
@@ -211,15 +238,15 @@ module Ribbon::Intercom
|
|
211
238
|
end
|
212
239
|
end
|
213
240
|
|
214
|
-
def _sufficient_permissions!(intercom_method)
|
215
|
-
unless sufficient_permissions?(intercom_method)
|
216
|
-
required = Utils.method_identifier(
|
241
|
+
def _sufficient_permissions!(base, intercom_method)
|
242
|
+
unless sufficient_permissions?(base, intercom_method)
|
243
|
+
required = Utils.method_identifier(base, intercom_method)
|
217
244
|
_error!(Errors::InsufficientPermissionsError, required)
|
218
245
|
end
|
219
246
|
end
|
220
247
|
|
221
248
|
def _response(status, headers={}, body=EmptyResponse)
|
222
|
-
body = body == EmptyResponse ? [] : [
|
249
|
+
body = body == EmptyResponse ? [] : [body]
|
223
250
|
headers = headers.merge("Content-Type" => "text/plain", "Transfer-Encoding" => "gzip")
|
224
251
|
Rack::Response.new(body, status, headers)
|
225
252
|
end
|
@@ -229,7 +256,7 @@ module Ribbon::Intercom
|
|
229
256
|
end
|
230
257
|
|
231
258
|
def _respond_with_error!(error, status=500)
|
232
|
-
|
259
|
+
_respond_with_packet(Packet.new(error: error), status)
|
233
260
|
end
|
234
261
|
|
235
262
|
def _error!(klass, message=nil)
|
@@ -256,14 +283,6 @@ module Ribbon::Intercom
|
|
256
283
|
end
|
257
284
|
end
|
258
285
|
|
259
|
-
def _encode_body(body)
|
260
|
-
Base64.strict_encode64(Marshal.dump(body))
|
261
|
-
end
|
262
|
-
|
263
|
-
def _encode_error(error)
|
264
|
-
Base64.strict_encode64(Marshal.dump(error))
|
265
|
-
end
|
266
|
-
|
267
286
|
##
|
268
287
|
# Decodes the arguments.
|
269
288
|
#
|
@@ -74,14 +74,24 @@ module Ribbon::Intercom
|
|
74
74
|
private
|
75
75
|
|
76
76
|
def _load_data(token)
|
77
|
-
|
78
|
-
|
77
|
+
channel_data_future = nil
|
78
|
+
permissions_future = nil
|
79
|
+
signing_keys_future = nil
|
80
|
+
|
81
|
+
@_redis.pipelined {
|
82
|
+
channel_data_future = @_redis.hgetall(_key_name(token))
|
83
|
+
permissions_future = @_redis.smembers(_key_name(token, 'permissions'))
|
84
|
+
signing_keys_future = @_redis.hgetall(_key_name(token, 'signing_keys'))
|
85
|
+
}
|
79
86
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
87
|
+
channel_data = channel_data_future.value
|
88
|
+
|
89
|
+
if channel_data && !channel_data.empty?
|
90
|
+
permissions = permissions_future.value
|
91
|
+
|
92
|
+
signing_keys = signing_keys_future.value.map { |key_id, data|
|
93
|
+
[key_id.to_i, Marshal.load(Base64.strict_decode64(data))]
|
94
|
+
}.to_h
|
85
95
|
|
86
96
|
Utils.symbolize_keys(
|
87
97
|
channel_data.merge(
|
@@ -3,10 +3,13 @@ require 'date'
|
|
3
3
|
module Ribbon::Intercom
|
4
4
|
module Utils
|
5
5
|
autoload(:Signer, 'ribbon/intercom/utils/signer')
|
6
|
+
autoload(:MethodChain, 'ribbon/intercom/utils/method_chain')
|
6
7
|
autoload(:Mixins, 'ribbon/intercom/utils/mixins')
|
7
8
|
|
8
9
|
BASIC_TYPES = [
|
9
|
-
String, Symbol, TrueClass, FalseClass, Integer, Float, NilClass,
|
10
|
+
String, Symbol, TrueClass, FalseClass, Integer, Float, NilClass,
|
11
|
+
Date, Time, DateTime,
|
12
|
+
Hash, Array, Range
|
10
13
|
].freeze
|
11
14
|
|
12
15
|
class << self
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Ribbon::Intercom
|
2
|
+
module Utils
|
3
|
+
class MethodChain
|
4
|
+
class << self
|
5
|
+
def begin(&block)
|
6
|
+
new(&block)
|
7
|
+
end
|
8
|
+
end # Class Methods
|
9
|
+
|
10
|
+
##
|
11
|
+
# Need to override all public instance methods so they can be captured correctly.
|
12
|
+
public_instance_methods.each { |meth|
|
13
|
+
define_method(meth) { |*args|
|
14
|
+
_add_method(meth, *args)
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
def initialize(&block)
|
19
|
+
@_end_block = block
|
20
|
+
end
|
21
|
+
|
22
|
+
def end
|
23
|
+
@_end_block.call(@_methods)
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def method_missing(meth, *args, &block)
|
29
|
+
_add_method(meth, *args)
|
30
|
+
end
|
31
|
+
|
32
|
+
def _add_method(meth, *args)
|
33
|
+
(@_methods ||= []) << [meth, *args]
|
34
|
+
self
|
35
|
+
end
|
36
|
+
end # MethodChain
|
37
|
+
end # Utils
|
38
|
+
end # Ribbon::Intercom
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ribbon-intercom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Honer
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-05-
|
12
|
+
date: 2015-05-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -172,6 +172,8 @@ files:
|
|
172
172
|
- lib/ribbon/intercom/package.rb
|
173
173
|
- lib/ribbon/intercom/packageable.rb
|
174
174
|
- lib/ribbon/intercom/packageable/mixin.rb
|
175
|
+
- lib/ribbon/intercom/packet.rb
|
176
|
+
- lib/ribbon/intercom/packet/method_queue.rb
|
175
177
|
- lib/ribbon/intercom/railtie.rb
|
176
178
|
- lib/ribbon/intercom/service.rb
|
177
179
|
- lib/ribbon/intercom/service/channel.rb
|
@@ -180,6 +182,7 @@ files:
|
|
180
182
|
- lib/ribbon/intercom/service/channel/stores/redis_store.rb
|
181
183
|
- lib/ribbon/intercom/service/channel/stores/store.rb
|
182
184
|
- lib/ribbon/intercom/utils.rb
|
185
|
+
- lib/ribbon/intercom/utils/method_chain.rb
|
183
186
|
- lib/ribbon/intercom/utils/mixins.rb
|
184
187
|
- lib/ribbon/intercom/utils/mixins/mock_safe.rb
|
185
188
|
- lib/ribbon/intercom/utils/signer.rb
|