twilio-ruby 3.12.2 → 3.12.3
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 +8 -8
- data/CHANGES.md +7 -0
- data/README.md +9 -0
- data/docs/usage/basics.rst +13 -0
- data/docs/usage/token-generation.rst +18 -3
- data/lib/twilio-ruby.rb +22 -0
- data/lib/twilio-ruby/rest/client.rb +11 -3
- data/lib/twilio-ruby/util/capability.rb +6 -3
- data/lib/twilio-ruby/util/configuration.rb +7 -0
- data/lib/twilio-ruby/util/request_validator.rb +3 -2
- data/lib/twilio-ruby/version.rb +1 -1
- data/spec/rest/client_spec.rb +59 -0
- data/spec/twilio_spec.rb +15 -0
- data/spec/util/capability_spec.rb +167 -118
- data/spec/util/configuration_spec.rb +13 -0
- data/spec/util/request_validator_spec.rb +29 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YTAxY2JmOWY5NjY3MTMyNTA1ZTVhMWE1NmMyZmIxYzI3NjNhYWVlYw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NTQwYTVkMDFhMGUzNzAyMzE0NGQyN2U2YmJiMWQ5ZmE2NzZkZjVmNg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZjY4MTY2ZmRlY2M0YzJhMzA3OTMxMTBlZmEwZjlkNzgxNWJmMTRiODQ4NDRh
|
10
|
+
OWUxYjEwOWQ5MDczNGI3MTEwZGM3ZmZkNWM5YzU1ZjNiY2NjZGI0ZTIwZTBl
|
11
|
+
N2JiOGQ1YTE5YTE0MDNkYWVjMjI3ZDRhMmQ3YzJhMmFiZGZlZDg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTA2ZWZhZDdiZDRiOWYwY2MxOThjM2RlNDkyMzZjOWUyNWI0ZjI5ZTQ3Mjc3
|
14
|
+
NjAxOWNjMjFlNmVhMWE3OGM5YzExNTJjNWNmNGUzMDFlMGZlYTRjMTk3MGZk
|
15
|
+
MDNlYTUxYzkwNDRiMWVjNDY1YjY3OGVlZjU5NDAwMWMxN2YwNTU=
|
data/CHANGES.md
CHANGED
data/README.md
CHANGED
@@ -42,6 +42,15 @@ auth_token = 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy'
|
|
42
42
|
|
43
43
|
# set up a client to talk to the Twilio REST API
|
44
44
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
45
|
+
|
46
|
+
# alternatively, you can preconfigure the client like so
|
47
|
+
Twilio.configure do |config|
|
48
|
+
config.account_sid = account_sid
|
49
|
+
config.auth_token = auth_token
|
50
|
+
end
|
51
|
+
|
52
|
+
# and then you can create a new client without parameters
|
53
|
+
@client = Twilio::REST::Client.new
|
45
54
|
```
|
46
55
|
|
47
56
|
### Send an SMS
|
data/docs/usage/basics.rst
CHANGED
@@ -27,6 +27,19 @@ Once you have your credentials, you can create create a new :class:`Client` and
|
|
27
27
|
|
28
28
|
@client = Twilio::REST::Client.new account_sid, auth_token
|
29
29
|
|
30
|
+
You can also configure the client using the top level configure method, like so:
|
31
|
+
|
32
|
+
.. code-block:: ruby
|
33
|
+
|
34
|
+
require 'twilio-ruby'
|
35
|
+
|
36
|
+
Twilio.configure do |config|
|
37
|
+
config.account_sid = "ACXXXXXXXXXXXXXXXXX"
|
38
|
+
config.auth_token = "YYYYYYYYYYYYYYYYYY"
|
39
|
+
end
|
40
|
+
|
41
|
+
@client = Twilio::REST::Client.new
|
42
|
+
|
30
43
|
|
31
44
|
Listing Resources
|
32
45
|
-------------------
|
@@ -17,11 +17,11 @@ security and authorization. The `Capability Token documentation
|
|
17
17
|
<http://www.twilio.com/docs/tokens>`_ explains in depth the purpose and
|
18
18
|
features of these tokens.
|
19
19
|
|
20
|
-
:class:`
|
21
|
-
tokens. You'll need your Twilio AccountSid and AuthToken.
|
20
|
+
:class:`Twilio::Util::Capability` is responsible for the creation of these
|
21
|
+
capability tokens. You'll need your Twilio AccountSid and AuthToken.
|
22
22
|
|
23
23
|
.. code-block:: ruby
|
24
|
-
|
24
|
+
|
25
25
|
require 'twilio-ruby'
|
26
26
|
|
27
27
|
# Find these values at twilio.com/user/account
|
@@ -30,6 +30,21 @@ tokens. You'll need your Twilio AccountSid and AuthToken.
|
|
30
30
|
|
31
31
|
@capability = Twilio::Util::Capability.new account_sid, auth_token
|
32
32
|
|
33
|
+
You can also configure capability tokens using the top level configure method,
|
34
|
+
like so:
|
35
|
+
|
36
|
+
.. code-block:: ruby
|
37
|
+
|
38
|
+
require 'twilio-ruby'
|
39
|
+
|
40
|
+
Twilio.configure do |config|
|
41
|
+
config.account_sid = "ACXXXXXXXXXXXXXXXXX"
|
42
|
+
config.auth_token = "YYYYYYYYYYYYYYYYYY"
|
43
|
+
end
|
44
|
+
|
45
|
+
@capability = Twilio::Util::Capability.new
|
46
|
+
|
47
|
+
|
33
48
|
|
34
49
|
Allow Incoming Connections
|
35
50
|
==============================
|
data/lib/twilio-ruby.rb
CHANGED
@@ -5,10 +5,12 @@ require 'multi_json'
|
|
5
5
|
require 'cgi'
|
6
6
|
require 'openssl'
|
7
7
|
require 'base64'
|
8
|
+
require 'forwardable'
|
8
9
|
require 'jwt'
|
9
10
|
|
10
11
|
require 'twilio-ruby/version' unless defined?(Twilio::VERSION)
|
11
12
|
require 'twilio-ruby/util'
|
13
|
+
require 'twilio-ruby/util/configuration'
|
12
14
|
require 'twilio-ruby/util/request_validator'
|
13
15
|
require 'twilio-ruby/util/capability'
|
14
16
|
require 'twilio-ruby/twiml/response'
|
@@ -59,3 +61,23 @@ require 'twilio-ruby/rest/transcriptions'
|
|
59
61
|
require 'twilio-ruby/rest/notifications'
|
60
62
|
require 'twilio-ruby/rest/client'
|
61
63
|
require 'rack/twilio_webhook_authentication'
|
64
|
+
|
65
|
+
module Twilio
|
66
|
+
extend SingleForwardable
|
67
|
+
|
68
|
+
def_delegators :configuration, :account_sid, :auth_token
|
69
|
+
|
70
|
+
##
|
71
|
+
# Pre-configure with account SID and auth token so that you don't need to
|
72
|
+
# pass them to various initializers each time.
|
73
|
+
def self.configure(&block)
|
74
|
+
yield configuration
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Returns an existing or instantiates a new configuration object.
|
79
|
+
def self.configuration
|
80
|
+
@configuration ||= Util::Configuration.new
|
81
|
+
end
|
82
|
+
private_class_method :configuration
|
83
|
+
end
|
@@ -85,7 +85,8 @@ module Twilio
|
|
85
85
|
|
86
86
|
##
|
87
87
|
# Instantiate a new HTTP client to talk to Twilio. The parameters
|
88
|
-
# +account_sid+ and +auth_token+ are required
|
88
|
+
# +account_sid+ and +auth_token+ are required, unless you have configured
|
89
|
+
# them already using the block configure syntax, and used to generate the
|
89
90
|
# HTTP basic auth header in each request. The +options+ parameter is a
|
90
91
|
# hash of connection configuration options. the following keys are
|
91
92
|
# supported:
|
@@ -148,9 +149,16 @@ module Twilio
|
|
148
149
|
#
|
149
150
|
# The number of times to retry a request that has failed before throwing
|
150
151
|
# an exception. Defaults to one.
|
151
|
-
def initialize(
|
152
|
-
|
152
|
+
def initialize(*args)
|
153
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
153
154
|
@config = DEFAULTS.merge! options
|
155
|
+
|
156
|
+
@account_sid = args[0] || Twilio.account_sid
|
157
|
+
@auth_token = args[1] || Twilio.auth_token
|
158
|
+
if @account_sid.nil? || @auth_token.nil?
|
159
|
+
raise ArgumentError, 'Account SID and auth token are required'
|
160
|
+
end
|
161
|
+
|
154
162
|
set_up_connection
|
155
163
|
set_up_subresources
|
156
164
|
end
|
@@ -4,9 +4,12 @@ module Twilio
|
|
4
4
|
|
5
5
|
include Twilio::Util
|
6
6
|
|
7
|
-
def initialize(account_sid, auth_token)
|
8
|
-
@account_sid = account_sid
|
9
|
-
@auth_token = auth_token
|
7
|
+
def initialize(account_sid = nil, auth_token = nil)
|
8
|
+
@account_sid = account_sid || Twilio.account_sid
|
9
|
+
@auth_token = auth_token || Twilio.auth_token
|
10
|
+
if @account_sid.nil? || @auth_token.nil?
|
11
|
+
raise ArgumentError, 'Account SID and auth token are required'
|
12
|
+
end
|
10
13
|
@capabilities = []
|
11
14
|
end
|
12
15
|
|
@@ -2,8 +2,9 @@ module Twilio
|
|
2
2
|
module Util
|
3
3
|
class RequestValidator
|
4
4
|
|
5
|
-
def initialize(auth_token)
|
6
|
-
@auth_token = auth_token
|
5
|
+
def initialize(auth_token = nil)
|
6
|
+
@auth_token = auth_token || Twilio.auth_token
|
7
|
+
raise ArgumentError, 'Auth token is required' if @auth_token.nil?
|
7
8
|
end
|
8
9
|
|
9
10
|
def validate(url, params, signature)
|
data/lib/twilio-ruby/version.rb
CHANGED
data/spec/rest/client_spec.rb
CHANGED
@@ -1,6 +1,65 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Twilio::REST::Client do
|
4
|
+
describe 'config at class level' do
|
5
|
+
after(:each) do
|
6
|
+
Twilio.instance_variable_set('@configuration', nil)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should set the account sid and auth token with a config block' do
|
10
|
+
Twilio.configure do |config|
|
11
|
+
config.account_sid = 'someSid'
|
12
|
+
config.auth_token = 'someToken'
|
13
|
+
end
|
14
|
+
|
15
|
+
client = Twilio::REST::Client.new
|
16
|
+
expect(client.account_sid).to eq('someSid')
|
17
|
+
expect(client.instance_variable_get('@auth_token')).to eq('someToken')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should overwrite account sid and auth token if passed to initializer' do
|
21
|
+
Twilio.configure do |config|
|
22
|
+
config.account_sid = 'someSid'
|
23
|
+
config.auth_token = 'someToken'
|
24
|
+
end
|
25
|
+
|
26
|
+
client = Twilio::REST::Client.new 'otherSid', 'otherToken'
|
27
|
+
expect(client.account_sid).to eq('otherSid')
|
28
|
+
expect(client.instance_variable_get('@auth_token')).to eq('otherToken')
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should overwrite the account sid if only the sid is given' do
|
32
|
+
Twilio.configure do |config|
|
33
|
+
config.account_sid = 'someSid'
|
34
|
+
config.auth_token = 'someToken'
|
35
|
+
end
|
36
|
+
|
37
|
+
client = Twilio::REST::Client.new 'otherSid'
|
38
|
+
expect(client.account_sid).to eq('otherSid')
|
39
|
+
expect(client.instance_variable_get('@auth_token')).to eq('someToken')
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should allow options after setting up auth with config' do
|
43
|
+
Twilio.configure do |config|
|
44
|
+
config.account_sid = 'someSid'
|
45
|
+
config.auth_token = 'someToken'
|
46
|
+
end
|
47
|
+
|
48
|
+
client = Twilio::REST::Client.new :host => 'api.faketwilio.com'
|
49
|
+
|
50
|
+
connection = client.instance_variable_get('@connection')
|
51
|
+
expect(connection.address).to eq('api.faketwilio.com')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should throw an argument error if the sid and token isn\'t set' do
|
55
|
+
expect { Twilio::REST::Client.new }.to raise_error(ArgumentError)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should throw an argument error if only the account_sid is set' do
|
59
|
+
expect { Twilio::REST::Client.new 'someSid' }.to raise_error(ArgumentError)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
4
63
|
it 'should not raise an error if the response body is empty' do
|
5
64
|
FakeWeb.register_uri(:any, %r/api\.twilio\.com/, :body => '')
|
6
65
|
twilio = Twilio::REST::Client.new('someSid', 'someToken')
|
data/spec/twilio_spec.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
describe Twilio do
|
2
|
+
after(:each) do
|
3
|
+
Twilio.instance_variable_set('@configuration', nil)
|
4
|
+
end
|
5
|
+
|
6
|
+
it 'should set the account sid and auth token with a config block' do
|
7
|
+
Twilio.configure do |config|
|
8
|
+
config.account_sid = 'someSid'
|
9
|
+
config.auth_token = 'someToken'
|
10
|
+
end
|
11
|
+
|
12
|
+
expect(Twilio.account_sid).to eq('someSid')
|
13
|
+
expect(Twilio.auth_token).to eq('someToken')
|
14
|
+
end
|
15
|
+
end
|
@@ -1,137 +1,186 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Twilio::Util::Capability do
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
describe 'config' do
|
5
|
+
after(:each) do
|
6
|
+
Twilio.instance_variable_set('@configuration', nil)
|
7
|
+
end
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
it 'should set the account sid and auth token from a configuration block' do
|
10
|
+
Twilio.configure do |config|
|
11
|
+
config.account_sid = 'someSid'
|
12
|
+
config.auth_token = 'someToken'
|
13
|
+
end
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
expect(decoded['iss']).not_to be_nil
|
17
|
-
expect(decoded['exp']).not_to be_nil
|
18
|
-
end
|
15
|
+
capability = Twilio::Util::Capability.new
|
16
|
+
expect(capability.instance_variable_get('@account_sid')).to eq('someSid')
|
17
|
+
expect(capability.instance_variable_get('@auth_token')).to eq('someToken')
|
18
|
+
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
it 'should overwrite account sid and auth token if passed to initializer' do
|
21
|
+
Twilio.configure do |config|
|
22
|
+
config.account_sid = 'someSid'
|
23
|
+
config.auth_token = 'someToken'
|
24
|
+
end
|
25
25
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
expect(decoded['exp']).to eq(seconds + 3600)
|
31
|
-
end
|
26
|
+
capability = Twilio::Util::Capability.new'otherSid', 'otherToken'
|
27
|
+
expect(capability.instance_variable_get('@account_sid')).to eq('otherSid')
|
28
|
+
expect(capability.instance_variable_get('@auth_token')).to eq('otherToken')
|
29
|
+
end
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
expect(decoded['exp']).to eq(seconds + ttl)
|
39
|
-
end
|
31
|
+
it 'should overwrite the account sid if only the sid is given' do
|
32
|
+
Twilio.configure do |config|
|
33
|
+
config.account_sid = 'someSid'
|
34
|
+
config.auth_token = 'someToken'
|
35
|
+
end
|
40
36
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
expect(queries(decoded['scope'])).to eq([['incoming', {'clientName' => 'andrew'}]])
|
46
|
-
end
|
37
|
+
capability = Twilio::Util::Capability.new 'otherSid'
|
38
|
+
expect(capability.instance_variable_get('@account_sid')).to eq('otherSid')
|
39
|
+
expect(capability.instance_variable_get('@auth_token')).to eq('someToken')
|
40
|
+
end
|
47
41
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
token = @capability.generate
|
52
|
-
decoded, header = JWT.decode token, 'myAuthToken'
|
53
|
-
expect(queries(decoded['scope'])).to eq([
|
54
|
-
['incoming', {'clientName' => 'andrew'}],
|
55
|
-
['incoming', {'clientName' => 'bridget'}]
|
56
|
-
])
|
57
|
-
end
|
42
|
+
it 'should throw an argument error if the sid and token isn\'t set' do
|
43
|
+
expect { Twilio::Util::Capability.new }.to raise_error(ArgumentError)
|
44
|
+
end
|
58
45
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
decoded, header = JWT.decode token, 'myAuthToken'
|
63
|
-
expect(queries(decoded['scope'])).to eq([['outgoing', {'appSid' => 'myAppSid'}]])
|
46
|
+
it 'should throw an argument error if only the account_sid is set' do
|
47
|
+
expect { Twilio::Util::Capability.new 'someSid' }.to raise_error(ArgumentError)
|
48
|
+
end
|
64
49
|
end
|
65
50
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
params_hash = {'appSid' => 'myAppSid', 'appParams' => app_params}
|
71
|
-
@capability.instance_eval {url_encode(params_hash)}
|
72
|
-
token = @capability.generate
|
73
|
-
decoded, header= JWT.decode token, 'myAuthToken'
|
74
|
-
expect(queries(decoded['scope'])).to eq([['outgoing', params_hash]])
|
75
|
-
end
|
51
|
+
describe 'with a capability' do
|
52
|
+
before :each do
|
53
|
+
@capability = Twilio::Util::Capability.new 'myAccountSid', 'myAuthToken'
|
54
|
+
end
|
76
55
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
@capability.allow_client_outgoing 'myAppSid'
|
81
|
-
token = @capability.generate
|
82
|
-
decoded, header = JWT.decode token, 'myAuthToken'
|
83
|
-
expect(queries(decoded['scope'])).to eq([
|
84
|
-
['incoming', {'clientName' => 'andrew'}],
|
85
|
-
['outgoing', {'clientName' => 'andrew', 'appSid' => 'myAppSid'}]
|
86
|
-
])
|
87
|
-
end
|
56
|
+
def queries(q)
|
57
|
+
q.scan(/scope:client:(incoming|outgoing)\?(\S+)/).map{|(type, query)| [type, Rack::Utils.parse_query(query)]}
|
58
|
+
end
|
88
59
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
end
|
60
|
+
it 'should return a valid jwt when #generate is called' do
|
61
|
+
token = @capability.generate
|
62
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
63
|
+
expect(decoded['scope']).not_to be_nil
|
64
|
+
expect(decoded['iss']).not_to be_nil
|
65
|
+
expect(decoded['exp']).not_to be_nil
|
66
|
+
end
|
97
67
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
68
|
+
it 'should properly set the iss key in the payload' do
|
69
|
+
token = @capability.generate
|
70
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
71
|
+
expect(decoded['iss']).to eq('myAccountSid')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should properly set the exp key based on the default hour ttl' do
|
75
|
+
seconds = Time.now.to_i
|
76
|
+
token = @capability.generate
|
77
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
78
|
+
expect(decoded['exp']).to eq(seconds + 3600)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'should properly set the exp key based on the ttl passed to #generate' do
|
82
|
+
ttl = rand 10000
|
83
|
+
seconds = Time.now.to_i
|
84
|
+
token = @capability.generate ttl
|
85
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
86
|
+
expect(decoded['exp']).to eq(seconds + ttl)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should generate a proper incoming client scope string' do
|
90
|
+
@capability.allow_client_incoming 'andrew'
|
91
|
+
token = @capability.generate
|
92
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
93
|
+
expect(queries(decoded['scope'])).to eq([['incoming', {'clientName' => 'andrew'}]])
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should generate multiple proper incoming client scope strings' do
|
97
|
+
@capability.allow_client_incoming 'andrew'
|
98
|
+
@capability.allow_client_incoming 'bridget'
|
99
|
+
token = @capability.generate
|
100
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
101
|
+
expect(queries(decoded['scope'])).to eq([
|
102
|
+
['incoming', {'clientName' => 'andrew'}],
|
103
|
+
['incoming', {'clientName' => 'bridget'}]
|
104
|
+
])
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should generate a proper outgoing client scope string' do
|
108
|
+
@capability.allow_client_outgoing 'myAppSid'
|
109
|
+
token = @capability.generate
|
110
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
111
|
+
expect(queries(decoded['scope'])).to eq([['outgoing', {'appSid' => 'myAppSid'}]])
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should generate a proper outgoing client scope string with parameters' do
|
115
|
+
app_params_hash = {'key' => 'a value', :foo => 'bar/baz'}
|
116
|
+
@capability.allow_client_outgoing 'myAppSid', app_params_hash
|
117
|
+
app_params = @capability.instance_eval {url_encode(app_params_hash)}
|
118
|
+
params_hash = {'appSid' => 'myAppSid', 'appParams' => app_params}
|
119
|
+
@capability.instance_eval {url_encode(params_hash)}
|
120
|
+
token = @capability.generate
|
121
|
+
decoded, header= JWT.decode token, 'myAuthToken'
|
122
|
+
expect(queries(decoded['scope'])).to eq([['outgoing', params_hash]])
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should generate a proper outgoing client scope string based on the ' +
|
126
|
+
'client name when calling #allow_client_incoming first' do
|
127
|
+
@capability.allow_client_incoming 'andrew'
|
128
|
+
@capability.allow_client_outgoing 'myAppSid'
|
129
|
+
token = @capability.generate
|
130
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
131
|
+
expect(queries(decoded['scope'])).to eq([
|
132
|
+
['incoming', {'clientName' => 'andrew'}],
|
133
|
+
['outgoing', {'clientName' => 'andrew', 'appSid' => 'myAppSid'}]
|
134
|
+
])
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'should generate a proper outgoing client scope string based on the ' +
|
138
|
+
'client name when calling #allow_client_incoming second' do
|
139
|
+
@capability.allow_client_outgoing 'myAppSid'
|
140
|
+
@capability.allow_client_incoming 'andrew'
|
141
|
+
token = @capability.generate
|
142
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
143
|
+
expect(queries(decoded['scope'])).to eq([["incoming", {"clientName"=>"andrew"}], ["outgoing", {"clientName"=>"andrew", "appSid"=>"myAppSid"}]])
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should generate a proper outgoing client scope string with parameters ' +
|
147
|
+
'and a client name when calling #allow_client_incoming first' do
|
148
|
+
@capability.allow_client_incoming 'andrew'
|
149
|
+
app_params_hash = {'key' => 'a value', :foo => 'bar/baz'}
|
150
|
+
@capability.allow_client_outgoing 'myAppSid', app_params_hash
|
151
|
+
app_params = @capability.instance_eval {url_encode(app_params_hash)}
|
152
|
+
params_hash = {'appSid' => 'myAppSid', 'appParams' => app_params, 'clientName' => 'andrew'}
|
153
|
+
@capability.instance_eval {url_encode(params_hash)}
|
154
|
+
token = @capability.generate
|
155
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
156
|
+
scopes = queries(decoded['scope'])
|
157
|
+
expect(scopes.shift).to eq(["incoming", {"clientName"=>"andrew"}])
|
158
|
+
scope = scopes.shift
|
159
|
+
expect(scope.first).to eq('outgoing')
|
160
|
+
expect(Rack::Utils.parse_query(scope.last['appParams'])).to eq({'key' => 'a value', 'foo' => 'bar/baz'})
|
161
|
+
expect(scope.last["clientName"]).to eq("andrew")
|
162
|
+
expect(scope.last["appSid"]).to eq("myAppSid")
|
163
|
+
expect(scopes).to be_empty
|
164
|
+
end
|
117
165
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
166
|
+
it 'should generate a proper outgoing client scope string with parameters ' +
|
167
|
+
'and a client name when calling #allow_client_incoming second' do
|
168
|
+
app_params_hash = {'key' => 'a value', :foo => 'bar/baz'}
|
169
|
+
@capability.allow_client_outgoing 'myAppSid', app_params_hash
|
170
|
+
@capability.allow_client_incoming 'andrew'
|
171
|
+
app_params = @capability.instance_eval {url_encode(app_params_hash)}
|
172
|
+
params_hash = {'appSid' => 'myAppSid', 'appParams' => app_params, 'clientName' => 'andrew'}
|
173
|
+
@capability.instance_eval {url_encode(params_hash)}
|
174
|
+
token = @capability.generate
|
175
|
+
decoded, header = JWT.decode token, 'myAuthToken'
|
176
|
+
scopes = queries(decoded['scope'])
|
177
|
+
expect(scopes.shift).to eq(["incoming", {"clientName"=>"andrew"}])
|
178
|
+
scope = scopes.shift
|
179
|
+
expect(scope.first).to eq('outgoing')
|
180
|
+
expect(Rack::Utils.parse_query(scope.last['appParams'])).to eq({'key' => 'a value', 'foo' => 'bar/baz'})
|
181
|
+
expect(scope.last["clientName"]).to eq("andrew")
|
182
|
+
expect(scope.last["appSid"]).to eq("myAppSid")
|
183
|
+
expect(scopes).to be_empty
|
184
|
+
end
|
136
185
|
end
|
137
186
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
describe Twilio::Util::Configuration do
|
2
|
+
it 'should have an account sid attribute' do
|
3
|
+
config = Twilio::Util::Configuration.new
|
4
|
+
config.account_sid = 'someSid'
|
5
|
+
expect(config.account_sid).to eq('someSid')
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should have an auth token attribute' do
|
9
|
+
config = Twilio::Util::Configuration.new
|
10
|
+
config.auth_token = 'someToken'
|
11
|
+
expect(config.auth_token).to eq('someToken')
|
12
|
+
end
|
13
|
+
end
|
@@ -1,6 +1,34 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Twilio::Util::RequestValidator do
|
4
|
+
describe 'configuration' do
|
5
|
+
after(:each) do
|
6
|
+
Twilio.instance_variable_set('@configuration', nil)
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should set the auth token from a configuration block' do
|
10
|
+
Twilio.configure do |config|
|
11
|
+
config.auth_token = 'someToken'
|
12
|
+
end
|
13
|
+
|
14
|
+
validator = Twilio::Util::RequestValidator.new
|
15
|
+
expect(validator.instance_variable_get('@auth_token')).to eq('someToken')
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should overwrite the auth token if passed to initializer' do
|
19
|
+
Twilio.configure do |config|
|
20
|
+
config.auth_token = 'someToken'
|
21
|
+
end
|
22
|
+
|
23
|
+
validator = Twilio::Util::RequestValidator.new 'otherToken'
|
24
|
+
expect(validator.instance_variable_get('@auth_token')).to eq('otherToken')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should throw an argument error if the auth token isn\'t set' do
|
28
|
+
expect { Twilio::Util::RequestValidator.new }.to raise_error(ArgumentError)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
4
32
|
it 'should properly validate a Twilio Voice request' do
|
5
33
|
token = '2bd9e9638872de601313dc77410d3b23'
|
6
34
|
validator = Twilio::Util::RequestValidator.new token
|
@@ -62,4 +90,4 @@ describe Twilio::Util::RequestValidator do
|
|
62
90
|
signature = 'mxeiv65lEe0b8L6LdVw2jgJi8yw='
|
63
91
|
expect(validator.validate(url, params, signature)).to eq(true)
|
64
92
|
end
|
65
|
-
end
|
93
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: twilio-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.12.
|
4
|
+
version: 3.12.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Benton
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: multi_json
|
@@ -175,6 +175,7 @@ files:
|
|
175
175
|
- lib/twilio-ruby/twiml/response.rb
|
176
176
|
- lib/twilio-ruby/util.rb
|
177
177
|
- lib/twilio-ruby/util/capability.rb
|
178
|
+
- lib/twilio-ruby/util/configuration.rb
|
178
179
|
- lib/twilio-ruby/util/request_validator.rb
|
179
180
|
- lib/twilio-ruby/version.rb
|
180
181
|
- spec/rack/twilio_webhook_authentication_spec.rb
|
@@ -191,7 +192,9 @@ files:
|
|
191
192
|
- spec/rest/recording_spec.rb
|
192
193
|
- spec/spec_helper.rb
|
193
194
|
- spec/support/fakeweb.rb
|
195
|
+
- spec/twilio_spec.rb
|
194
196
|
- spec/util/capability_spec.rb
|
197
|
+
- spec/util/configuration_spec.rb
|
195
198
|
- spec/util/request_validator_spec.rb
|
196
199
|
- spec/util/url_encode_spec.rb
|
197
200
|
- twilio-ruby.gemspec
|
@@ -241,6 +244,8 @@ test_files:
|
|
241
244
|
- spec/rest/recording_spec.rb
|
242
245
|
- spec/spec_helper.rb
|
243
246
|
- spec/support/fakeweb.rb
|
247
|
+
- spec/twilio_spec.rb
|
244
248
|
- spec/util/capability_spec.rb
|
249
|
+
- spec/util/configuration_spec.rb
|
245
250
|
- spec/util/request_validator_spec.rb
|
246
251
|
- spec/util/url_encode_spec.rb
|