ribbon-intercom 0.4.0 → 0.4.1

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
  SHA1:
3
- metadata.gz: dbc66058ef3f67f202ae929f759b20a1ca45a0f7
4
- data.tar.gz: d5eee408147e0cf447120c6f2ee8150cba30cec9
3
+ metadata.gz: c41ac1f0f1b5608ce40ce2610cc29cf28a8d7bc6
4
+ data.tar.gz: d975fe767bcc9bc0cc9bd3a6da43ba81b8054c88
5
5
  SHA512:
6
- metadata.gz: ed1f4b07d38b1fca0657cc08ec4fac171ae9fc65a7132f9afe4f46a9043d6104d4fec26ade902ab93bed155102365fdf56518dfbf93b0a2695805173b8d834b3
7
- data.tar.gz: 723e68476ea49afd0cf055e2ce6adcfb8636ea6c7d12625abfa9ff2486a1502bc4507af01a7fbfc5f4d8935ee1b0bc82de2a9e223547e99ec9513a6cd9e8fe81
6
+ metadata.gz: e5f12d2757fa4c8a1e1343df7b44ae31228d5a24572a6bfafba6356eacbb362f65d5530e778f68af3fafe9d99aef2fb4f672783b8b924d1ea29009a1bcb351a4
7
+ data.tar.gz: 44453cbf103d87a761d25b92934c501bc09c96b5a85d4cca97675303dd8c87cd65c7fd8c944a8de0fbdba45cc1b5cdde170aa8ca4c06c22dd7f508ff721ec1a1
@@ -84,7 +84,7 @@ module Ribbon::Intercom
84
84
  def _process_response(packet)
85
85
  _handle_response_error(packet) if packet.error?
86
86
 
87
- _init_packages(packet.retval)
87
+ Package.init_packages(packet.retval, self)
88
88
  packet
89
89
  end
90
90
 
@@ -94,20 +94,6 @@ module Ribbon::Intercom
94
94
  raise 'packet contains no error' unless packet.error?
95
95
  raise packet.error
96
96
  end
97
-
98
- ##
99
- # Walks the object and initializes all packages (i.e., sets them up to be
100
- # accessed by the end-user on the client).
101
- def _init_packages(object)
102
- Utils.walk(object) { |object|
103
- if object.is_a?(Package)
104
- object.sdk = dup
105
- object.mock_safe! if mock_safe?
106
- end
107
-
108
- object
109
- }
110
- end
111
97
  end # SDK
112
98
  end # Client
113
99
  end # Ribbon::Intercom
@@ -4,6 +4,49 @@ module Ribbon::Intercom
4
4
  class Package
5
5
  include Utils::Mixins::MockSafe
6
6
 
7
+ class << self
8
+ ##
9
+ # Package up any non-basic objects that include Packageable::Mixin.
10
+ def package(subject)
11
+ Utils.walk(subject) { |subject, context|
12
+ if Utils.basic_type?(subject)
13
+ subject
14
+ elsif context == :hash_key
15
+ # Hash keys must be basic types.
16
+ raise Errors::UnsafeResponseError, subject.inspect
17
+ elsif subject.is_a?(Packageable::Mixin)
18
+ _package_obj(subject, package(subject.package_data))
19
+ elsif subject.is_a?(Class) && subject < Packageable::Mixin
20
+ _package_obj(subject)
21
+ else
22
+ raise Errors::UnsafeResponseError, subject.inspect
23
+ end
24
+ }
25
+ end
26
+
27
+ def _package_obj(subject, data=nil)
28
+ new(encode_subject(subject), data)
29
+ end
30
+
31
+ def encode_subject(subject)
32
+ Marshal.dump(subject)
33
+ end
34
+
35
+ def decode_subject(encoded_subject)
36
+ Marshal.load(encoded_subject)
37
+ end
38
+
39
+ ##
40
+ # Walks the object and initializes all packages (i.e., sets them up to be
41
+ # accessed by the end-user on the client).
42
+ def init_packages(object, sdk)
43
+ Utils.walk(object) { |object|
44
+ object.send(:_init, sdk) if object.is_a?(Package)
45
+ object
46
+ }
47
+ end
48
+ end # Class Methods
49
+
7
50
  attr_reader :sdk
8
51
 
9
52
  def initialize(subject_data=nil, data=nil)
@@ -11,10 +54,11 @@ module Ribbon::Intercom
11
54
  @_data = data
12
55
  end
13
56
 
14
- def sdk=(sdk)
15
- @sdk = sdk
16
- end
17
-
57
+ ##
58
+ # Begin a method chain (must be completed with `#end`).
59
+ #
60
+ # When `#end` is called on the method chain, the chain will be resolved
61
+ # remotely. This allows the chain of methods to be executed in one round-trip.
18
62
  def begin
19
63
  Utils::MethodChain.begin { |methods|
20
64
  queue = Packet::MethodQueue.new
@@ -29,12 +73,26 @@ module Ribbon::Intercom
29
73
  if @_data && @_data.key?(meth)
30
74
  @_data[meth]
31
75
  elsif sdk
32
- _send_method_queue(Packet::MethodQueue.new.enqueue(meth, *args))
76
+ _call(meth, *args)
33
77
  else
34
78
  super
35
79
  end
36
80
  end
37
81
 
82
+ ##
83
+ # Call a method on the subject remotely.
84
+ def _call(method_name, *args)
85
+ _send_method_queue(Packet::MethodQueue.new.enqueue(method_name, *args))
86
+ end
87
+
88
+ ##
89
+ # Initializes the package on the client-side.
90
+ def _init(sdk)
91
+ @sdk = sdk
92
+ self.class.init_packages(@_data, sdk)
93
+ mock_safe! if sdk.mock_safe?
94
+ end
95
+
38
96
  def _send_method_queue(method_queue)
39
97
  _process_response(
40
98
  sdk.send_packet(
@@ -55,7 +113,7 @@ module Ribbon::Intercom
55
113
 
56
114
  def _process_response(packet)
57
115
  @_subject_data = packet.subject
58
- @_data = packet.package_data
116
+ @_data = self.class.init_packages(packet.package_data, sdk)
59
117
 
60
118
  packet.retval
61
119
  end
@@ -22,9 +22,7 @@ module Ribbon::Intercom
22
22
  ##
23
23
  # Returns the package data for the instance as a hash.
24
24
  def package_data
25
- Utils.sanitize(
26
- self.class._package_with_methods.map { |meth| [meth, public_send(meth)] }.to_h
27
- )
25
+ self.class._package_with_methods.map { |meth| [meth, public_send(meth)] }.to_h
28
26
  end
29
27
  end # Mixin
30
28
  end # Service::Subject
@@ -66,8 +66,19 @@ module Ribbon::Intercom
66
66
  store.lookup_channel(token)
67
67
  end
68
68
 
69
+ ##
70
+ # Check that the channel has sufficient permissions to call the method.
71
+ #
72
+ # The `send` method is forbidden because it breaks the encapsulation guaranteed
73
+ # by intercom (i.e., private methods can't be called).
74
+ #
75
+ # In addition to the permissions granted to the channel, all channels have
76
+ # implicit permission to call public methods on basic types.
69
77
  def sufficient_permissions?(base, intercom_method)
70
- Utils.basic_type?(base) || channel.may?(Utils.method_identifier(base, intercom_method))
78
+ intercom_method != :send && (
79
+ Utils.basic_type?(base) ||
80
+ channel.may?(Utils.method_identifier(base, intercom_method))
81
+ )
71
82
  end
72
83
 
73
84
  def call(env)
@@ -123,7 +134,7 @@ module Ribbon::Intercom
123
134
 
124
135
  def _load_subject
125
136
  if (encoded_subject=request_packet.subject) && !encoded_subject.empty?
126
- @subject = _decode_subject(encoded_subject)
137
+ @subject = Package.decode_subject(encoded_subject)
127
138
  _error!(Errors::InvalidSubjectSignatureError) unless @subject
128
139
  else
129
140
  @subject = self
@@ -150,7 +161,7 @@ module Ribbon::Intercom
150
161
  base = base.public_send(meth, *args)
151
162
  }
152
163
 
153
- _package(base)
164
+ Package.package(base)
154
165
  rescue NoMethodError => error
155
166
  if error.name == intercom_method
156
167
  _error!(Errors::InvalidMethodError, intercom_method)
@@ -173,11 +184,11 @@ module Ribbon::Intercom
173
184
  Packet.new.tap { |packet|
174
185
  unless self == subject # Order matters here! See: issue#52
175
186
  # Need to send subject back in case it was modified by the methods.
176
- packet.subject = _encode_subject(subject)
187
+ packet.subject = Package.encode_subject(subject)
177
188
 
178
189
  if subject.is_a?(Packageable::Mixin)
179
190
  # Need to send the package data back in case it changed, too.
180
- packet.package_data = subject.package_data
191
+ packet.package_data = Package.package(subject.package_data)
181
192
  end
182
193
  end
183
194
 
@@ -189,42 +200,6 @@ module Ribbon::Intercom
189
200
  _respond!(status, {}, packet.encode)
190
201
  end
191
202
 
192
- ##
193
- # Package up any non-basic objects that include Packageable::Mixin.
194
- def _package(object)
195
- Utils.walk(object) { |object, context|
196
- if Utils.basic_type?(object)
197
- object
198
- elsif context == :hash_key
199
- # Hash keys must be basic types.
200
- _error!(Errors::UnsafeResponseError, object.inspect)
201
- elsif object.is_a?(Packageable::Mixin)
202
- _package_obj(object, object.package_data)
203
- elsif object.is_a?(Class) && object < Packageable::Mixin
204
- _package_obj(object)
205
- else
206
- _error!(Errors::UnsafeResponseError, object.inspect)
207
- end
208
- }
209
- end
210
-
211
- def _package_obj(object, data=nil)
212
- Package.new(_encode_subject(object), data)
213
- end
214
-
215
- ##
216
- # Marshal dumps the subject and signs the resulting bytes with the channel.
217
- def _encode_subject(subject)
218
- channel.sign(Marshal.dump(subject))
219
- end
220
-
221
- ##
222
- # Decodes the subject sent from the client.
223
- def _decode_subject(encoded_subject)
224
- marshalled_subject = channel.verify(encoded_subject)
225
- marshalled_subject && Marshal.load(marshalled_subject)
226
- end
227
-
228
203
  def _request_authenticated?
229
204
  auth = Rack::Auth::Basic::Request.new(env)
230
205
 
@@ -1,5 +1,5 @@
1
1
  module Ribbon
2
2
  module Intercom
3
- VERSION = '0.4.0'
3
+ VERSION = '0.4.1'
4
4
  end
5
5
  end
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.0
4
+ version: 0.4.1
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-21 00:00:00.000000000 Z
12
+ date: 2015-05-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack