signalwire 2.3.4 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d31f18c614ab0890b0c3000c45f607b636c8c3a3b7ad51d1e9dffae4c3b30165
4
- data.tar.gz: 6ef1eeb8106c935d12beb8edafb67004d14c012761c43c675a9ce4d430c794d6
3
+ metadata.gz: df430132083360896fd829e7137d80fa718d4f8fb7870c24c7b334d802f8de61
4
+ data.tar.gz: ec2b8b710595d900db60988bc5c28873b932bc965bbe5c82172a38b198478c52
5
5
  SHA512:
6
- metadata.gz: 4535d5d33d7d8152ffd349d0fbeb4cb544fc71931fb72f93c2c866eda4957249ace7b5337472193ebd58f0f6a987f546a226edc97618fb8bef03652162b534db
7
- data.tar.gz: 6887060feada342534a3b4a365eb058e93276aa50ecd8e88456d1b4495e6aee7aa47be22e26adc22dfb292e24a0291ffe3376e06b6359d27fa6d0aaffeaba457
6
+ metadata.gz: 11b434f415f50072036be156b1c2ba5926851d6a7e408aa0c1c05f7755143fd34b7b5eeb309fe43f53a5764961d45d335531f2dd40a79b94a76a35e7582579af
7
+ data.tar.gz: 847521247be584ebcfa30ae4131b58f475468e412280ca8f17bd01fffa278e78712f7a706fd67756f4311e045eece5da72f2954e51b3b2ffa290fd90e3c24974
@@ -0,0 +1,10 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: weekly
7
+ - package-ecosystem: github-actions
8
+ directory: "/"
9
+ schedule:
10
+ interval: weekly
@@ -0,0 +1,25 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [ "main" ]
6
+ pull_request:
7
+ branches: [ "main" ]
8
+
9
+ jobs:
10
+ test:
11
+ name: Test
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ ruby-version: ['2.6', '2.7', '3.0', '3.1', '3.2']
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - name: Set up Ruby
20
+ uses: ruby/setup-ruby@v1
21
+ with:
22
+ ruby-version: ${{ matrix.ruby-version }}
23
+ bundler-cache: true
24
+ - name: Run tests
25
+ run: bundle exec rspec
data/CHANGELOG.md CHANGED
@@ -5,6 +5,14 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ ## [2.5.0] - 2023-10-26
9
+ ### Added
10
+ - Add Middleware `SignalwireWebhookAuthentication`
11
+
12
+ ## [2.4.0] - 2023-10-13
13
+ ### Added
14
+ - Add Webhook `ValidateRequest`
15
+
8
16
  ## [2.3.4] - 2020-09-09
9
17
  ### Fixed
10
18
  - Correctly ignore non-call events and clear handlers on call end
data/README.md CHANGED
@@ -1,7 +1,8 @@
1
1
  # SignalWire Ruby
2
2
 
3
3
 
4
- [![Build Status](https://ci.signalwire.com/api/badges/signalwire/signalwire-ruby/status.svg)](https://ci.signalwire.com/signalwire/signalwire-ruby) [![Gem Version](https://badge.fury.io/rb/signalwire.svg)](https://badge.fury.io/rb/signalwire)
4
+ [![CI](https://github.com/signalwire/signalwire-ruby/actions/workflows/ci.yml/badge.svg)](https://github.com/signalwire/signalwire-ruby/actions/workflows/ci.yml)
5
+ [![Gem Version](https://badge.fury.io/rb/signalwire.svg)](https://badge.fury.io/rb/signalwire)
5
6
 
6
7
  The Relay SDK for Ruby enables Ruby developers to connect and use SignalWire's Relay APIs within their own Ruby code. Our Relay SDK allows developers to build or add robust and innovative communication services to their applications.
7
8
 
@@ -34,5 +35,5 @@ Relay SDK forRuby follows Semantic Versioning 2.0 as defined at <http://semver.o
34
35
 
35
36
  ## License
36
37
 
37
- Relay SDK for Ruby is copyright © 2018-2019
38
- [SignalWire](http://signalwire.com). It is free software, and may be redistributed under the terms specified in the [MIT-LICENSE](https://github.com//signalwire/signalwire-ruby/blob/master/LICENSE) file.
38
+ Relay SDK for Ruby is copyright © 2018-2023
39
+ [SignalWire](http://signalwire.com). It is free software, and may be redistributed under the terms specified in the [MIT-LICENSE](https://github.com//signalwire/signalwire-ruby/blob/master/LICENSE) file.
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rack/media_type'
4
+
5
+ module Rack
6
+ class SignalwireWebhookAuthentication
7
+ FORM_URLENCODED_MEDIA_TYPE = Rack::MediaType.type('application/x-www-form-urlencoded')
8
+
9
+ def initialize(app, private_key, *paths, &private_key_lookup)
10
+ @app = app
11
+ @private_key = private_key
12
+ define_singleton_method(:get_private_key, private_key_lookup) if block_given?
13
+ @path_regex = Regexp.union(paths)
14
+ end
15
+
16
+ def call(env)
17
+ return @app.call(env) unless env['PATH_INFO'].match(@path_regex)
18
+ request = Rack::Request.new(env)
19
+ original_url = request.url
20
+ params = extract_params!(request)
21
+ private_key = @private_key || get_private_key(params['AccountSid'])
22
+ validator = Signalwire::Webhook::ValidateRequest.new(private_key)
23
+ signature = env['HTTP_X_SIGNALWIRE_SIGNATURE'] || env['HTTP_X_TWILIO_SIGNATURE'] || ''
24
+ if validator.validate(original_url, params, signature)
25
+ @app.call(env)
26
+ else
27
+ [
28
+ 403,
29
+ { 'Content-Type' => 'text/plain' },
30
+ ['Signalwire Request Validation Failed.']
31
+ ]
32
+ end
33
+ end
34
+
35
+ def extract_params!(request)
36
+ return {} unless request.post?
37
+
38
+ if request.media_type == FORM_URLENCODED_MEDIA_TYPE
39
+ request.POST
40
+ else
41
+ request.body.rewind
42
+ body = request.body.read
43
+ request.body.rewind
44
+ body
45
+ end
46
+ end
47
+
48
+ private :extract_params!
49
+
50
+ end
51
+ end
@@ -10,6 +10,7 @@ require 'signalwire/sdk/voice_response'
10
10
  require 'signalwire/sdk/fax_response'
11
11
  require 'signalwire/sdk/messaging_response'
12
12
  require 'signalwire/rest/client'
13
+ require 'signalwire/webhook/validate_request'
13
14
 
14
15
  module Signalwire
15
16
  module Sdk
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Signalwire
4
- VERSION = '2.3.4'
4
+ VERSION = '2.5.0'
5
5
  end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openssl'
4
+
5
+ module Signalwire::Webhook
6
+ class ValidateRequest
7
+ attr_reader :private_key
8
+
9
+ def initialize(private_key)
10
+ @private_key = private_key
11
+ raise ArgumentError, 'Private key is required' if @private_key.nil?
12
+ end
13
+
14
+ def validate(url, raw_body, header)
15
+ return false if header.nil? || url.nil?
16
+
17
+ # compatibility validation for POST parameters of x-www-form-urlencoded requests
18
+ if raw_body.is_a?(Hash)
19
+ return validate_with_compatibility_api(url, raw_body, header)
20
+ end
21
+
22
+ # relay json validation
23
+ payload = url + raw_body
24
+ expected_signature = compute_signature(payload)
25
+ valid = secure_compare(expected_signature, header)
26
+
27
+ return true if valid
28
+
29
+ # fallback compatibilty json validation
30
+ validate_with_compatibility_api(url, raw_body, header)
31
+ end
32
+
33
+ private
34
+
35
+ def validate_with_compatibility_api(url, params, signature)
36
+ validator = Twilio::Security::RequestValidator.new(private_key)
37
+ validator.validate(url, params, signature)
38
+ end
39
+
40
+ def compute_signature(payload)
41
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha1'), private_key, payload)
42
+ end
43
+
44
+ # Constant time string comparison, from ActiveSupport
45
+ def secure_compare(a, b)
46
+ return false if a.nil? || b.nil?
47
+ return false unless a.bytesize == b.bytesize
48
+
49
+ l = a.unpack "C#{a.bytesize}"
50
+
51
+ res = 0
52
+ b.each_byte { |byte| res |= byte ^ l.shift }
53
+ res == 0
54
+ end
55
+ end
56
+ end
data/signalwire.gemspec CHANGED
@@ -27,17 +27,18 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency 'bundler', '~> 2.1'
28
28
  spec.add_development_dependency 'bundler-audit', '~> 0.6'
29
29
  spec.add_development_dependency 'guard-rspec', '~> 4.7'
30
- spec.add_development_dependency 'rake', '~> 12.3'
30
+ spec.add_development_dependency 'rack', '~> 2.0'
31
+ spec.add_development_dependency 'rake', '~> 13.0'
31
32
  spec.add_development_dependency 'rdoc', '~> 6.1'
32
33
  spec.add_development_dependency 'rspec', '~> 3.0'
33
34
  spec.add_development_dependency 'rubocop', '~> 0.67'
34
35
  spec.add_development_dependency 'ruby-prof', '~> 0.17'
35
36
  spec.add_development_dependency 'simplecov', '~> 0.16'
36
- spec.add_development_dependency 'vcr', '~> 4.0'
37
+ spec.add_development_dependency 'vcr', '~> 5.0'
37
38
  spec.add_development_dependency 'webmock', '~> 3.5'
38
39
 
39
40
  spec.add_dependency 'twilio-ruby', '~> 5.0'
40
- spec.add_dependency 'faye-websocket', '~> 0.10'
41
+ spec.add_dependency 'faye-websocket', '~> 0.11'
41
42
  spec.add_dependency 'concurrent-ruby', '~> 1.1'
42
43
  spec.add_dependency 'has-guarded-handlers', '~> 1.6.3'
43
44
  spec.add_dependency 'logger', '~> 1.3'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: signalwire
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.4
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - SignalWire Team
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-09-09 00:00:00.000000000 Z
11
+ date: 2023-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,20 +52,34 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '4.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
73
  - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '12.3'
75
+ version: '13.0'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
80
  - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '12.3'
82
+ version: '13.0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rdoc
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -142,14 +156,14 @@ dependencies:
142
156
  requirements:
143
157
  - - "~>"
144
158
  - !ruby/object:Gem::Version
145
- version: '4.0'
159
+ version: '5.0'
146
160
  type: :development
147
161
  prerelease: false
148
162
  version_requirements: !ruby/object:Gem::Requirement
149
163
  requirements:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
- version: '4.0'
166
+ version: '5.0'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: webmock
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -184,14 +198,14 @@ dependencies:
184
198
  requirements:
185
199
  - - "~>"
186
200
  - !ruby/object:Gem::Version
187
- version: '0.10'
201
+ version: '0.11'
188
202
  type: :runtime
189
203
  prerelease: false
190
204
  version_requirements: !ruby/object:Gem::Requirement
191
205
  requirements:
192
206
  - - "~>"
193
207
  - !ruby/object:Gem::Version
194
- version: '0.10'
208
+ version: '0.11'
195
209
  - !ruby/object:Gem::Dependency
196
210
  name: concurrent-ruby
197
211
  requirement: !ruby/object:Gem::Requirement
@@ -234,7 +248,7 @@ dependencies:
234
248
  - - "~>"
235
249
  - !ruby/object:Gem::Version
236
250
  version: '1.3'
237
- description:
251
+ description:
238
252
  email:
239
253
  - open.source@signalwire.com
240
254
  executables: []
@@ -242,7 +256,8 @@ extensions: []
242
256
  extra_rdoc_files: []
243
257
  files:
244
258
  - ".document"
245
- - ".drone.yml"
259
+ - ".github/dependabot.yml"
260
+ - ".github/workflows/ci.yml"
246
261
  - ".gitignore"
247
262
  - ".rspec"
248
263
  - ".rubocop.yml"
@@ -272,6 +287,7 @@ files:
272
287
  - examples/relay/tasking/tasking_receive.rb
273
288
  - examples/relay/tasking/tasking_send.rb
274
289
  - examples/relay/wait_for_ending.rb
290
+ - lib/rack/signalwire_webhook_authentication.rb
275
291
  - lib/signalwire.rb
276
292
  - lib/signalwire/blade.rb
277
293
  - lib/signalwire/blade/connection.rb
@@ -350,12 +366,13 @@ files:
350
366
  - lib/signalwire/sdk/twilio_set_host.rb
351
367
  - lib/signalwire/sdk/voice_response.rb
352
368
  - lib/signalwire/version.rb
369
+ - lib/signalwire/webhook/validate_request.rb
353
370
  - signalwire.gemspec
354
371
  homepage: https://github.com/signalwire/signalwire-ruby
355
372
  licenses:
356
373
  - MIT
357
374
  metadata: {}
358
- post_install_message:
375
+ post_install_message:
359
376
  rdoc_options: []
360
377
  require_paths:
361
378
  - lib
@@ -370,8 +387,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
370
387
  - !ruby/object:Gem::Version
371
388
  version: '0'
372
389
  requirements: []
373
- rubygems_version: 3.1.2
374
- signing_key:
390
+ rubygems_version: 3.4.21
391
+ signing_key:
375
392
  specification_version: 4
376
393
  summary: Ruby client for Signalwire
377
394
  test_files: []
data/.drone.yml DELETED
@@ -1,14 +0,0 @@
1
- kind: pipeline
2
- name: default
3
-
4
- steps:
5
- - name: test
6
- image: ruby:2.6
7
- commands:
8
- - gem install bundler
9
- - bundle install --jobs=3 --retry=3
10
- - bundle exec rspec
11
-
12
- trigger:
13
- event: push
14
-