bows 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/lib/ribbon/intercom.rb +42 -0
  3. data/lib/ribbon/intercom/client.rb +61 -0
  4. data/lib/ribbon/intercom/client/mock_sdk.rb +13 -0
  5. data/lib/ribbon/intercom/client/sdk.rb +99 -0
  6. data/lib/ribbon/intercom/client/sdk/adapters.rb +10 -0
  7. data/lib/ribbon/intercom/client/sdk/adapters/adapter.rb +77 -0
  8. data/lib/ribbon/intercom/client/sdk/adapters/adapter/response.rb +13 -0
  9. data/lib/ribbon/intercom/client/sdk/adapters/http_adapter.rb +32 -0
  10. data/lib/ribbon/intercom/client/sdk/adapters/http_adapter/connection.rb +34 -0
  11. data/lib/ribbon/intercom/client/sdk/adapters/local_adapter.rb +55 -0
  12. data/lib/ribbon/intercom/client/sdk/adapters/mock_adapter.rb +40 -0
  13. data/lib/ribbon/intercom/errors.rb +66 -0
  14. data/lib/ribbon/intercom/package.rb +121 -0
  15. data/lib/ribbon/intercom/packageable.rb +6 -0
  16. data/lib/ribbon/intercom/packageable/mixin.rb +29 -0
  17. data/lib/ribbon/intercom/packet.rb +52 -0
  18. data/lib/ribbon/intercom/packet/method_queue.rb +28 -0
  19. data/lib/ribbon/intercom/railtie.rb +14 -0
  20. data/lib/ribbon/intercom/service.rb +273 -0
  21. data/lib/ribbon/intercom/service/channel.rb +203 -0
  22. data/lib/ribbon/intercom/service/channel/stores.rb +9 -0
  23. data/lib/ribbon/intercom/service/channel/stores/mock_store.rb +40 -0
  24. data/lib/ribbon/intercom/service/channel/stores/redis_store.rb +196 -0
  25. data/lib/ribbon/intercom/service/channel/stores/store.rb +31 -0
  26. data/lib/ribbon/intercom/utils.rb +72 -0
  27. data/lib/ribbon/intercom/utils/method_chain.rb +38 -0
  28. data/lib/ribbon/intercom/utils/mixins.rb +5 -0
  29. data/lib/ribbon/intercom/utils/mixins/mock_safe.rb +26 -0
  30. data/lib/ribbon/intercom/utils/signer.rb +71 -0
  31. data/lib/ribbon/intercom/version.rb +5 -0
  32. data/lib/tasks/intercom.rake +24 -0
  33. metadata +215 -0
@@ -0,0 +1,31 @@
1
+ module Ribbon::Intercom
2
+ class Service
3
+ module Channel::Stores
4
+ class Store
5
+ def open_channel(params={})
6
+ Channel.new(self, params)
7
+ end
8
+
9
+ def token_exists?(token)
10
+ raise NotImplementedError
11
+ end
12
+
13
+ def lookup_channel(token)
14
+ raise NotImplementedError
15
+ end
16
+
17
+ def persist(channel)
18
+ raise NotImplementedError
19
+ end
20
+
21
+ def delete(channel)
22
+ raise NotImplementedError
23
+ end
24
+
25
+ def with_lock(channel, &block)
26
+ raise NotImplementedError
27
+ end
28
+ end # Store
29
+ end # Channel::Stores
30
+ end # Service
31
+ end # Ribbon::Intercom
@@ -0,0 +1,72 @@
1
+ require 'date'
2
+
3
+ module Ribbon::Intercom
4
+ module Utils
5
+ autoload(:Signer, 'ribbon/intercom/utils/signer')
6
+ autoload(:MethodChain, 'ribbon/intercom/utils/method_chain')
7
+ autoload(:Mixins, 'ribbon/intercom/utils/mixins')
8
+
9
+ BASIC_TYPES = [
10
+ String, Symbol, TrueClass, FalseClass, Integer, Float, NilClass,
11
+ Date, Time, DateTime,
12
+ Hash, Array, Range
13
+ ].freeze
14
+
15
+ class << self
16
+ def basic_type?(object)
17
+ case object
18
+ when *BASIC_TYPES then true
19
+ else false
20
+ end
21
+ end
22
+
23
+ def walk(object, context=nil, &block)
24
+ case object
25
+ when Hash
26
+ Hash[
27
+ object.map { |key, val|
28
+ [walk(key, :hash_key, &block), walk(val, :hash_value, &block)]
29
+ }
30
+ ]
31
+ when Array
32
+ object.map { |obj| walk(obj, :array_elem, &block) }
33
+ when Range
34
+ Range.new(
35
+ walk(object.begin, :range_begin, &block),
36
+ walk(object.end, :range_end, &block),
37
+ object.exclude_end?
38
+ )
39
+ else
40
+ yield object, context
41
+ end
42
+ end
43
+
44
+ ##
45
+ # Raises an error if the object is or contains any non-basic types.
46
+ def sanitize(object)
47
+ walk(object) { |object|
48
+ if basic_type?(object)
49
+ object
50
+ else
51
+ raise Errors::UnsafeValueError, object.inspect
52
+ end
53
+ }
54
+ end
55
+
56
+ def symbolize_keys(hash)
57
+ hash.inject({}){|memo,(k,v)| memo[k.to_sym] = v; memo}
58
+ end
59
+
60
+ def classify(str)
61
+ str.split("_").map(&:capitalize).join
62
+ end
63
+
64
+ ##
65
+ # Returns an identifier for the method (e.g., A::B::C#method_name)
66
+ def method_identifier(subject, method)
67
+ scope = subject.is_a?(Class) ? subject.name : subject.class.name
68
+ scope + (subject.is_a?(Class) ? '.' : '#') + method.to_s
69
+ end
70
+ end # Class methods
71
+ end # Utils
72
+ end # Ribbon::Intercom
@@ -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
@@ -0,0 +1,5 @@
1
+ module Ribbon::Intercom
2
+ module Utils::Mixins
3
+ autoload(:MockSafe, 'ribbon/intercom/utils/mixins/mock_safe')
4
+ end # Utils::Mixin
5
+ end # Ribbon::Intercom
@@ -0,0 +1,26 @@
1
+ module Ribbon::Intercom
2
+ module Utils::Mixins
3
+ module MockSafe
4
+ ##
5
+ # Return a mock safe version of this package.
6
+ def mock_safe
7
+ dup.tap { |obj| obj.mock_safe! }
8
+ end
9
+
10
+ ##
11
+ # Make this package mock safe.
12
+ def mock_safe!
13
+ unless mock_safe?
14
+ @_mock_safe = true
15
+
16
+ # For RSpec: Allow any method to be mocked on this instance.
17
+ define_singleton_method(:respond_to?) { |*args| true }
18
+ end
19
+ end
20
+
21
+ def mock_safe?
22
+ !!@_mock_safe
23
+ end
24
+ end # MockSafe
25
+ end # Utils::Mixin
26
+ end # Ribbon::Intercom
@@ -0,0 +1,71 @@
1
+ require 'securerandom'
2
+ require 'openssl'
3
+
4
+ module Ribbon::Intercom
5
+ module Utils
6
+ class Signer
7
+ class << self
8
+ def random_key
9
+ SecureRandom.random_bytes(32)
10
+ end
11
+
12
+ def random_salt
13
+ SecureRandom.random_bytes(8)
14
+ end
15
+ end
16
+
17
+ attr_reader :key
18
+
19
+ def initialize(key=self.class.random_key)
20
+ raise ArgumentError, "key must be defined" unless key
21
+ @key = key.dup.freeze
22
+ @_digest = OpenSSL::Digest::SHA256.new
23
+ end
24
+
25
+ def sign(data)
26
+ unless data.is_a?(String) && data.encoding == Encoding::BINARY
27
+ raise ArgumentError, "data must be a binary encoded string"
28
+ end
29
+
30
+ salt = self.class.random_salt
31
+ signature = _sign(salt, data)
32
+ _encode(signature, salt, data)
33
+ end
34
+
35
+ def verify(signed_data)
36
+ unless signed_data.is_a?(String) && signed_data.encoding == Encoding::BINARY
37
+ raise ArgumentError, "signed_data must be a binary encoded string"
38
+ end
39
+
40
+ signature, salt, data = _decode(signed_data)
41
+ data if _sign(salt, data) == signature
42
+ end
43
+
44
+ private
45
+
46
+ def _sign(salt, data)
47
+ OpenSSL::HMAC.digest(@_digest, key, salt + data)
48
+ end
49
+
50
+ def _encode(signature, salt, data)
51
+ "\x01" + signature + salt + data
52
+ end
53
+
54
+ def _decode(signed_data)
55
+ index = 0
56
+ version = signed_data[index]
57
+
58
+ index += version.length
59
+ signature = signed_data.slice(index, @_digest.length)
60
+
61
+ index += signature.length
62
+ salt = signed_data.slice(index, 8)
63
+
64
+ index += salt.length
65
+ data = signed_data.slice(index..-1)
66
+
67
+ [signature, salt, data]
68
+ end
69
+ end # Signer
70
+ end # Utils
71
+ end # Ribbon::Intercom
@@ -0,0 +1,5 @@
1
+ module Ribbon
2
+ module Intercom
3
+ VERSION = '0.0.1'
4
+ end
5
+ end
@@ -0,0 +1,24 @@
1
+ require 'optparse'
2
+ require 'ribbon/intercom'
3
+ require 'json'
4
+
5
+ namespace :intercom do
6
+ namespace :client do
7
+ task :rotate_secret, [:service] => :environment do |t, args|
8
+ service = args[:service]
9
+ puts "New #{service} secret: #{Intercom[service].rotate_secret}"
10
+ end
11
+ end
12
+
13
+ namespace :service do
14
+ task :open_channel, [:service_name, :channel_name, :permissions] => :environment do |t, args|
15
+ service = Intercom::Utils.classify(args[:service_name])
16
+ channel_name = args[:channel_name]
17
+ permissions = args[:permissions].split(" ")
18
+
19
+ channel = Intercom::const_get(service).open_channel(name: channel_name, may: permissions)
20
+ secret = channel.rotate_secret!
21
+ puts "New channel: #{channel_name} with token: #{channel.token} and secret: #{secret} with permissions: #{channel.permissions.to_a.inspect}"
22
+ end
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,215 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bows
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Robert Honer
8
+ - Kayvon Ghaffari
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-06-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.5'
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.5.2
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - "~>"
29
+ - !ruby/object:Gem::Version
30
+ version: '1.5'
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.5.2
34
+ - !ruby/object:Gem::Dependency
35
+ name: bcrypt
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 3.1.3
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 3.1.3
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: 3.1.3
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 3.1.3
54
+ - !ruby/object:Gem::Dependency
55
+ name: redis
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ - !ruby/object:Gem::Dependency
69
+ name: ribbon-config
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.1.0
75
+ type: :runtime
76
+ prerelease: false
77
+ version_requirements: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: 0.1.0
82
+ - !ruby/object:Gem::Dependency
83
+ name: rspec
84
+ requirement: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ type: :development
90
+ prerelease: false
91
+ version_requirements: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ - !ruby/object:Gem::Dependency
97
+ name: rspec-rails
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: sqlite3
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ - !ruby/object:Gem::Dependency
125
+ name: rails
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 4.0.0
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: 4.0.0
138
+ - !ruby/object:Gem::Dependency
139
+ name: mock_redis
140
+ requirement: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ type: :development
146
+ prerelease: false
147
+ version_requirements: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ description: A standard for authenticating requests among services
153
+ email:
154
+ - robert@ribbonpayments.com
155
+ - kayvon@ribbon.co
156
+ executables: []
157
+ extensions: []
158
+ extra_rdoc_files: []
159
+ files:
160
+ - lib/ribbon/intercom.rb
161
+ - lib/ribbon/intercom/client.rb
162
+ - lib/ribbon/intercom/client/mock_sdk.rb
163
+ - lib/ribbon/intercom/client/sdk.rb
164
+ - lib/ribbon/intercom/client/sdk/adapters.rb
165
+ - lib/ribbon/intercom/client/sdk/adapters/adapter.rb
166
+ - lib/ribbon/intercom/client/sdk/adapters/adapter/response.rb
167
+ - lib/ribbon/intercom/client/sdk/adapters/http_adapter.rb
168
+ - lib/ribbon/intercom/client/sdk/adapters/http_adapter/connection.rb
169
+ - lib/ribbon/intercom/client/sdk/adapters/local_adapter.rb
170
+ - lib/ribbon/intercom/client/sdk/adapters/mock_adapter.rb
171
+ - lib/ribbon/intercom/errors.rb
172
+ - lib/ribbon/intercom/package.rb
173
+ - lib/ribbon/intercom/packageable.rb
174
+ - lib/ribbon/intercom/packageable/mixin.rb
175
+ - lib/ribbon/intercom/packet.rb
176
+ - lib/ribbon/intercom/packet/method_queue.rb
177
+ - lib/ribbon/intercom/railtie.rb
178
+ - lib/ribbon/intercom/service.rb
179
+ - lib/ribbon/intercom/service/channel.rb
180
+ - lib/ribbon/intercom/service/channel/stores.rb
181
+ - lib/ribbon/intercom/service/channel/stores/mock_store.rb
182
+ - lib/ribbon/intercom/service/channel/stores/redis_store.rb
183
+ - lib/ribbon/intercom/service/channel/stores/store.rb
184
+ - lib/ribbon/intercom/utils.rb
185
+ - lib/ribbon/intercom/utils/method_chain.rb
186
+ - lib/ribbon/intercom/utils/mixins.rb
187
+ - lib/ribbon/intercom/utils/mixins/mock_safe.rb
188
+ - lib/ribbon/intercom/utils/signer.rb
189
+ - lib/ribbon/intercom/version.rb
190
+ - lib/tasks/intercom.rake
191
+ homepage: http://github.com/ribbon/intercom
192
+ licenses:
193
+ - BSD
194
+ metadata: {}
195
+ post_install_message:
196
+ rdoc_options: []
197
+ require_paths:
198
+ - lib
199
+ required_ruby_version: !ruby/object:Gem::Requirement
200
+ requirements:
201
+ - - ">="
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
204
+ required_rubygems_version: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
209
+ requirements: []
210
+ rubyforge_project:
211
+ rubygems_version: 2.4.3
212
+ signing_key:
213
+ specification_version: 4
214
+ summary: A standard for authenticating requests among services
215
+ test_files: []