twilio-ruby 5.0.0.rc10 → 5.0.0.rc11
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/rack/twilio_webhook_authentication.rb +3 -3
- data/lib/twilio-ruby/jwt/access_token.rb +111 -0
- data/lib/twilio-ruby/{util → jwt}/capability.rb +9 -9
- data/lib/twilio-ruby/jwt/task_router.rb +203 -0
- data/lib/twilio-ruby/{util → security}/request_validator.rb +1 -1
- data/lib/twilio-ruby/version.rb +1 -1
- data/lib/twilio-ruby.rb +11 -13
- data/spec/jwt/access_token_spec.rb +114 -0
- data/spec/{util → jwt}/capability_spec.rb +18 -18
- data/spec/jwt/task_router_spec.rb +110 -0
- data/spec/jwt/task_router_taskqueue_spec.rb +111 -0
- data/spec/jwt/task_router_worker_spec.rb +146 -0
- data/spec/jwt/task_router_workspace_spec.rb +110 -0
- data/spec/rack/twilio_webhook_authentication_spec.rb +7 -7
- data/spec/{util → security}/request_validator_spec.rb +5 -5
- data/twilio-ruby.gemspec +0 -1
- metadata +19 -31
- data/lib/twilio-ruby/task_router/capability.rb +0 -87
- data/lib/twilio-ruby/task_router.rb +0 -0
- data/lib/twilio-ruby/util/access_token.rb +0 -70
- data/lib/twilio-ruby/util/client_config.rb +0 -29
- data/spec/task_router_spec.rb +0 -114
- data/spec/util/access_token_spec.rb +0 -103
- data/spec/util/client_config_spec.rb +0 -21
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Twilio::JWT::AccessToken do
|
4
|
+
|
5
|
+
it 'should generate a token for no grants' do
|
6
|
+
scat = Twilio::JWT::AccessToken.new 'AC123', 'SK123','secret'
|
7
|
+
token = scat.to_s
|
8
|
+
expect(token).not_to be_nil
|
9
|
+
payload, header = JWT.decode token, 'secret'
|
10
|
+
|
11
|
+
expect(payload['iss']).to eq('SK123')
|
12
|
+
expect(payload['sub']).to eq('AC123')
|
13
|
+
expect(payload['exp']).not_to be_nil
|
14
|
+
expect(payload['exp']).to be >= Time.now.to_i
|
15
|
+
expect(payload['jti']).not_to be_nil
|
16
|
+
expect(payload['jti']).to start_with payload['iss']
|
17
|
+
expect(payload['nbf']).to be_nil
|
18
|
+
expect(payload['grants']).not_to be_nil
|
19
|
+
expect(payload['grants'].count).to eq(0)
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should generate a nbf' do
|
23
|
+
now = Time.now.to_i - 1
|
24
|
+
scat = Twilio::JWT::AccessToken.new 'AC123', 'SK123','secret'
|
25
|
+
scat.identity = 'abc'
|
26
|
+
scat.nbf = now
|
27
|
+
|
28
|
+
token = scat.to_s
|
29
|
+
expect(token).not_to be_nil
|
30
|
+
payload, header = JWT.decode token, 'secret'
|
31
|
+
|
32
|
+
expect(payload['iss']).to eq('SK123')
|
33
|
+
expect(payload['sub']).to eq('AC123')
|
34
|
+
expect(payload['nbf']).not_to be_nil
|
35
|
+
expect(payload['nbf']).to eq(now)
|
36
|
+
expect(payload['exp']).not_to be_nil
|
37
|
+
expect(payload['exp']).to be >= Time.now.to_i
|
38
|
+
expect(payload['jti']).not_to be_nil
|
39
|
+
expect(payload['jti']).to start_with payload['iss']
|
40
|
+
expect(payload['grants']).not_to be_nil
|
41
|
+
expect(payload['grants'].count).to eq(1)
|
42
|
+
expect(payload['grants']['identity']).to eq('abc')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should be able to add conversation grant' do
|
46
|
+
scat = Twilio::JWT::AccessToken.new 'AC123', 'SK123','secret'
|
47
|
+
scat.add_grant(Twilio::JWT::AccessToken::ConversationsGrant.new)
|
48
|
+
|
49
|
+
token = scat.to_s
|
50
|
+
expect(token).not_to be_nil
|
51
|
+
payload, header = JWT.decode token, 'secret'
|
52
|
+
|
53
|
+
expect(payload['iss']).to eq('SK123')
|
54
|
+
expect(payload['sub']).to eq('AC123')
|
55
|
+
expect(payload['exp']).not_to be_nil
|
56
|
+
expect(payload['exp']).to be >= Time.now.to_i
|
57
|
+
expect(payload['jti']).not_to be_nil
|
58
|
+
expect(payload['jti']).to start_with payload['iss']
|
59
|
+
expect(payload['grants']).not_to be_nil
|
60
|
+
expect(payload['grants'].count).to eq(1)
|
61
|
+
expect(payload['grants']['rtc']).not_to be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should be able to add endpoint grants' do
|
65
|
+
scat = Twilio::JWT::AccessToken.new 'AC123', 'SK123','secret'
|
66
|
+
|
67
|
+
grant = Twilio::JWT::AccessToken::IpMessagingGrant.new
|
68
|
+
grant.push_credential_sid = 'CR123'
|
69
|
+
grant.deployment_role_sid = 'DR123'
|
70
|
+
grant.service_sid = 'IS123'
|
71
|
+
grant.endpoint_id = 'EP123'
|
72
|
+
scat.add_grant(grant)
|
73
|
+
|
74
|
+
token = scat.to_s
|
75
|
+
expect(token).not_to be_nil
|
76
|
+
payload, header = JWT.decode token, 'secret'
|
77
|
+
|
78
|
+
expect(payload['iss']).to eq('SK123')
|
79
|
+
expect(payload['sub']).to eq('AC123')
|
80
|
+
expect(payload['exp']).not_to be_nil
|
81
|
+
expect(payload['exp']).to be >= Time.now.to_i
|
82
|
+
expect(payload['jti']).not_to be_nil
|
83
|
+
expect(payload['jti']).to start_with payload['iss']
|
84
|
+
expect(payload['grants']).not_to be_nil
|
85
|
+
expect(payload['grants'].count).to eq(1)
|
86
|
+
expect(payload['grants']['ip_messaging']).not_to be_nil
|
87
|
+
expect(payload['grants']['ip_messaging']['service_sid']).to eq('IS123')
|
88
|
+
expect(payload['grants']['ip_messaging']['endpoint_id']).to eq('EP123')
|
89
|
+
expect(payload['grants']['ip_messaging']['push_credential_sid']).to eq('CR123')
|
90
|
+
expect(payload['grants']['ip_messaging']['deployment_role_sid']).to eq('DR123')
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should add rest grants' do
|
94
|
+
scat = Twilio::JWT::AccessToken.new 'AC123', 'SK123','secret'
|
95
|
+
scat.add_grant(Twilio::JWT::AccessToken::ConversationsGrant.new)
|
96
|
+
scat.add_grant(Twilio::JWT::AccessToken::IpMessagingGrant.new)
|
97
|
+
|
98
|
+
token = scat.to_s
|
99
|
+
expect(token).not_to be_nil
|
100
|
+
payload, header = JWT.decode token, 'secret'
|
101
|
+
|
102
|
+
expect(payload['iss']).to eq('SK123')
|
103
|
+
expect(payload['sub']).to eq('AC123')
|
104
|
+
expect(payload['exp']).not_to be_nil
|
105
|
+
expect(payload['exp']).to be >= Time.now.to_i
|
106
|
+
expect(payload['jti']).not_to be_nil
|
107
|
+
expect(payload['jti']).to start_with payload['iss']
|
108
|
+
expect(payload['grants']).not_to be_nil
|
109
|
+
expect(payload['grants'].count).to eq(2)
|
110
|
+
expect(payload['grants']['rtc']).not_to be_nil
|
111
|
+
expect(payload['grants']['ip_messaging']).not_to be_nil
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Twilio::
|
3
|
+
describe Twilio::JWT::Capability do
|
4
4
|
describe 'config' do
|
5
5
|
after(:each) do
|
6
6
|
Twilio.instance_variable_set('@configuration', nil)
|
@@ -12,7 +12,7 @@ describe Twilio::Util::Capability do
|
|
12
12
|
config.auth_token = 'someToken'
|
13
13
|
end
|
14
14
|
|
15
|
-
capability = Twilio::
|
15
|
+
capability = Twilio::JWT::Capability.new
|
16
16
|
expect(capability.instance_variable_get('@account_sid')).to eq('someSid')
|
17
17
|
expect(capability.instance_variable_get('@auth_token')).to eq('someToken')
|
18
18
|
end
|
@@ -23,7 +23,7 @@ describe Twilio::Util::Capability do
|
|
23
23
|
config.auth_token = 'someToken'
|
24
24
|
end
|
25
25
|
|
26
|
-
capability = Twilio::
|
26
|
+
capability = Twilio::JWT::Capability.new'otherSid', 'otherToken'
|
27
27
|
expect(capability.instance_variable_get('@account_sid')).to eq('otherSid')
|
28
28
|
expect(capability.instance_variable_get('@auth_token')).to eq('otherToken')
|
29
29
|
end
|
@@ -34,23 +34,23 @@ describe Twilio::Util::Capability do
|
|
34
34
|
config.auth_token = 'someToken'
|
35
35
|
end
|
36
36
|
|
37
|
-
capability = Twilio::
|
37
|
+
capability = Twilio::JWT::Capability.new 'otherSid'
|
38
38
|
expect(capability.instance_variable_get('@account_sid')).to eq('otherSid')
|
39
39
|
expect(capability.instance_variable_get('@auth_token')).to eq('someToken')
|
40
40
|
end
|
41
41
|
|
42
42
|
it 'should throw an argument error if the sid and token isn\'t set' do
|
43
|
-
expect { Twilio::
|
43
|
+
expect { Twilio::JWT::Capability.new }.to raise_error(ArgumentError)
|
44
44
|
end
|
45
45
|
|
46
46
|
it 'should throw an argument error if only the account_sid is set' do
|
47
|
-
expect { Twilio::
|
47
|
+
expect { Twilio::JWT::Capability.new 'someSid' }.to raise_error(ArgumentError)
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
51
|
describe 'with a capability' do
|
52
52
|
before :each do
|
53
|
-
@capability = Twilio::
|
53
|
+
@capability = Twilio::JWT::Capability.new 'myAccountSid', 'myAuthToken'
|
54
54
|
end
|
55
55
|
|
56
56
|
def queries(q)
|
@@ -99,9 +99,9 @@ describe Twilio::Util::Capability do
|
|
99
99
|
token = @capability.generate
|
100
100
|
decoded, header = JWT.decode token, 'myAuthToken'
|
101
101
|
expect(queries(decoded['scope'])).to eq([
|
102
|
-
|
103
|
-
|
104
|
-
|
102
|
+
['incoming', {'clientName' => 'andrew'}],
|
103
|
+
['incoming', {'clientName' => 'bridget'}]
|
104
|
+
])
|
105
105
|
end
|
106
106
|
|
107
107
|
it 'should generate a proper outgoing client scope string' do
|
@@ -123,19 +123,19 @@ describe Twilio::Util::Capability do
|
|
123
123
|
end
|
124
124
|
|
125
125
|
it 'should generate a proper outgoing client scope string based on the ' +
|
126
|
-
|
126
|
+
'client name when calling #allow_client_incoming first' do
|
127
127
|
@capability.allow_client_incoming 'andrew'
|
128
128
|
@capability.allow_client_outgoing 'myAppSid'
|
129
129
|
token = @capability.generate
|
130
130
|
decoded, header = JWT.decode token, 'myAuthToken'
|
131
131
|
expect(queries(decoded['scope'])).to eq([
|
132
|
-
|
133
|
-
|
134
|
-
|
132
|
+
['incoming', {'clientName' => 'andrew'}],
|
133
|
+
['outgoing', {'clientName' => 'andrew', 'appSid' => 'myAppSid'}]
|
134
|
+
])
|
135
135
|
end
|
136
136
|
|
137
137
|
it 'should generate a proper outgoing client scope string based on the ' +
|
138
|
-
|
138
|
+
'client name when calling #allow_client_incoming second' do
|
139
139
|
@capability.allow_client_outgoing 'myAppSid'
|
140
140
|
@capability.allow_client_incoming 'andrew'
|
141
141
|
token = @capability.generate
|
@@ -144,7 +144,7 @@ describe Twilio::Util::Capability do
|
|
144
144
|
end
|
145
145
|
|
146
146
|
it 'should generate a proper outgoing client scope string with parameters ' +
|
147
|
-
|
147
|
+
'and a client name when calling #allow_client_incoming first' do
|
148
148
|
@capability.allow_client_incoming 'andrew'
|
149
149
|
app_params_hash = {'key' => 'a value', :foo => 'bar/baz'}
|
150
150
|
@capability.allow_client_outgoing 'myAppSid', app_params_hash
|
@@ -164,7 +164,7 @@ describe Twilio::Util::Capability do
|
|
164
164
|
end
|
165
165
|
|
166
166
|
it 'should generate a proper outgoing client scope string with parameters ' +
|
167
|
-
|
167
|
+
'and a client name when calling #allow_client_incoming second' do
|
168
168
|
app_params_hash = {'key' => 'a value', :foo => 'bar/baz'}
|
169
169
|
@capability.allow_client_outgoing 'myAppSid', app_params_hash
|
170
170
|
@capability.allow_client_incoming 'andrew'
|
@@ -183,4 +183,4 @@ describe Twilio::Util::Capability do
|
|
183
183
|
expect(scopes).to be_empty
|
184
184
|
end
|
185
185
|
end
|
186
|
-
end
|
186
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Twilio::JWT::TaskRouterCapability do
|
4
|
+
describe 'with a capability' do
|
5
|
+
before :each do
|
6
|
+
@capability = Twilio::JWT::TaskRouterCapability.new 'AC123', 'foobar', 'WS456', 'WS456'
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should return a valid jwt when #generate_token is called' do
|
10
|
+
token = @capability.generate_token
|
11
|
+
decoded, header = JWT.decode token, 'foobar'
|
12
|
+
expect(decoded['policies']).not_to be_nil
|
13
|
+
expect(decoded['iss']).not_to be_nil
|
14
|
+
expect(decoded['exp']).not_to be_nil
|
15
|
+
expect(decoded['account_sid']).to eq('AC123')
|
16
|
+
expect(decoded['workspace_sid']).to eq('WS456')
|
17
|
+
expect(decoded['channel']).to eq('WS456')
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should properly set the iss key in the payload' do
|
21
|
+
token = @capability.generate_token
|
22
|
+
decoded, header = JWT.decode token, 'foobar'
|
23
|
+
expect(decoded['iss']).to eq('AC123')
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'should properly set exp based on the default 1-hour ttl' do
|
27
|
+
seconds = Time.now.to_i
|
28
|
+
token = @capability.generate_token
|
29
|
+
decoded, header = JWT.decode token, 'foobar'
|
30
|
+
expect(decoded['exp']).to eq(seconds + 3600)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should properly set exp based on the ttl arg to #generate_token' do
|
34
|
+
seconds = Time.now.to_i
|
35
|
+
ttl = rand 10000
|
36
|
+
token = @capability.generate_token ttl
|
37
|
+
decoded, header = JWT.decode token, 'foobar'
|
38
|
+
expect(decoded['exp']).to eq(seconds + ttl)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should allow websocket operations and fetching the workspace by default' do
|
42
|
+
token = @capability.generate_token
|
43
|
+
decoded, header = JWT.decode token, 'foobar'
|
44
|
+
expect(decoded['policies'].size).to eq(3)
|
45
|
+
get_policy = {
|
46
|
+
"url" => 'https://event-bridge.twilio.com/v1/wschannels/AC123/WS456',
|
47
|
+
"method" => 'GET',
|
48
|
+
"query_filter" => {},
|
49
|
+
"post_filter" => {},
|
50
|
+
"allow" => true
|
51
|
+
}
|
52
|
+
expect(decoded['policies'][0]).to eq(get_policy)
|
53
|
+
post_policy = {
|
54
|
+
"url" => 'https://event-bridge.twilio.com/v1/wschannels/AC123/WS456',
|
55
|
+
"method" => 'POST',
|
56
|
+
"query_filter" => {},
|
57
|
+
"post_filter" => {},
|
58
|
+
"allow" => true
|
59
|
+
}
|
60
|
+
expect(decoded['policies'][1]).to eq(post_policy)
|
61
|
+
|
62
|
+
workspace_fetch_policy = {
|
63
|
+
'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456',
|
64
|
+
'method' => 'GET',
|
65
|
+
'query_filter' => {},
|
66
|
+
'post_filter' => {},
|
67
|
+
'allow' => true
|
68
|
+
}
|
69
|
+
expect(decoded['policies'][2]).to eq(workspace_fetch_policy)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should add a policy when #allow_fetch_subresources is called' do
|
73
|
+
token = @capability.generate_token
|
74
|
+
decoded, header = JWT.decode token, 'foobar'
|
75
|
+
policies_size = decoded['policies'].size
|
76
|
+
|
77
|
+
@capability.allow_fetch_subresources
|
78
|
+
token = @capability.generate_token
|
79
|
+
decoded, header = JWT.decode token, 'foobar'
|
80
|
+
workspace_fetch_policy = {
|
81
|
+
'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/**',
|
82
|
+
'method' => 'GET',
|
83
|
+
'query_filter' => {},
|
84
|
+
'post_filter' => {},
|
85
|
+
'allow' => true
|
86
|
+
}
|
87
|
+
expect(decoded['policies'][-1]).to eq(workspace_fetch_policy)
|
88
|
+
expect(decoded['policies'].size).to eq(policies_size+1)
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should add a policy when #allow_update_subresources is called' do
|
92
|
+
token = @capability.generate_token
|
93
|
+
decoded, header = JWT.decode token, 'foobar'
|
94
|
+
policies_size = decoded['policies'].size
|
95
|
+
|
96
|
+
@capability.allow_updates_subresources
|
97
|
+
token = @capability.generate_token
|
98
|
+
decoded, header = JWT.decode token, 'foobar'
|
99
|
+
workspace_update_policy = {
|
100
|
+
'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/**',
|
101
|
+
'method' => 'POST',
|
102
|
+
'query_filter' => {},
|
103
|
+
'post_filter' => {},
|
104
|
+
'allow' => true
|
105
|
+
}
|
106
|
+
expect(decoded['policies'][-1]).to eq(workspace_update_policy)
|
107
|
+
expect(decoded['policies'].size).to eq(policies_size+1)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Twilio::JWT::TaskQueueCapability do
|
4
|
+
describe 'with a capability' do
|
5
|
+
before :each do
|
6
|
+
@capability = Twilio::JWT::TaskQueueCapability.new 'AC123', 'foobar', 'WS456', 'WQ789'
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should return a valid jwt when #generate_token is called' do
|
10
|
+
token = @capability.generate_token
|
11
|
+
decoded, header = JWT.decode token, 'foobar'
|
12
|
+
expect(decoded['policies']).not_to be_nil
|
13
|
+
expect(decoded['iss']).not_to be_nil
|
14
|
+
expect(decoded['exp']).not_to be_nil
|
15
|
+
expect(decoded['account_sid']).to eq('AC123')
|
16
|
+
expect(decoded['workspace_sid']).to eq('WS456')
|
17
|
+
expect(decoded['taskqueue_sid']).to eq('WQ789')
|
18
|
+
expect(decoded['channel']).to eq('WQ789')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should properly set the iss key in the payload' do
|
22
|
+
token = @capability.generate_token
|
23
|
+
decoded, header = JWT.decode token, 'foobar'
|
24
|
+
expect(decoded['iss']).to eq('AC123')
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should properly set exp based on the default 1-hour ttl' do
|
28
|
+
seconds = Time.now.to_i
|
29
|
+
token = @capability.generate_token
|
30
|
+
decoded, header = JWT.decode token, 'foobar'
|
31
|
+
expect(decoded['exp']).to eq(seconds + 3600)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should properly set exp based on the ttl arg to #generate_token' do
|
35
|
+
seconds = Time.now.to_i
|
36
|
+
ttl = rand 10000
|
37
|
+
token = @capability.generate_token ttl
|
38
|
+
decoded, header = JWT.decode token, 'foobar'
|
39
|
+
expect(decoded['exp']).to eq(seconds + ttl)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should allow websocket operations and fetching the workspace by default' do
|
43
|
+
token = @capability.generate_token
|
44
|
+
decoded, header = JWT.decode token, 'foobar'
|
45
|
+
expect(decoded['policies'].size).to eq(3)
|
46
|
+
get_policy = {
|
47
|
+
"url" => 'https://event-bridge.twilio.com/v1/wschannels/AC123/WQ789',
|
48
|
+
"method" => 'GET',
|
49
|
+
"query_filter" => {},
|
50
|
+
"post_filter" => {},
|
51
|
+
"allow" => true
|
52
|
+
}
|
53
|
+
expect(decoded['policies'][0]).to eq(get_policy)
|
54
|
+
post_policy = {
|
55
|
+
"url" => 'https://event-bridge.twilio.com/v1/wschannels/AC123/WQ789',
|
56
|
+
"method" => 'POST',
|
57
|
+
"query_filter" => {},
|
58
|
+
"post_filter" => {},
|
59
|
+
"allow" => true
|
60
|
+
}
|
61
|
+
expect(decoded['policies'][1]).to eq(post_policy)
|
62
|
+
|
63
|
+
taskqueue_fetch_policy = {
|
64
|
+
'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/TaskQueues/WQ789',
|
65
|
+
'method' => 'GET',
|
66
|
+
'query_filter' => {},
|
67
|
+
'post_filter' => {},
|
68
|
+
'allow' => true
|
69
|
+
}
|
70
|
+
expect(decoded['policies'][2]).to eq(taskqueue_fetch_policy)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should add a policy when #allow_fetch_subresources is called' do
|
74
|
+
token = @capability.generate_token
|
75
|
+
decoded, header = JWT.decode token, 'foobar'
|
76
|
+
policies_size = decoded['policies'].size
|
77
|
+
|
78
|
+
@capability.allow_fetch_subresources
|
79
|
+
token = @capability.generate_token
|
80
|
+
decoded, header = JWT.decode token, 'foobar'
|
81
|
+
taskqueue_fetch_policy = {
|
82
|
+
'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/TaskQueues/WQ789/**',
|
83
|
+
'method' => 'GET',
|
84
|
+
'query_filter' => {},
|
85
|
+
'post_filter' => {},
|
86
|
+
'allow' => true
|
87
|
+
}
|
88
|
+
expect(decoded['policies'][-1]).to eq(taskqueue_fetch_policy)
|
89
|
+
expect(decoded['policies'].size).to eq(policies_size+1)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should add a policy when #allow_update_subresources is called' do
|
93
|
+
token = @capability.generate_token
|
94
|
+
decoded, header = JWT.decode token, 'foobar'
|
95
|
+
policies_size = decoded['policies'].size
|
96
|
+
|
97
|
+
@capability.allow_updates_subresources
|
98
|
+
token = @capability.generate_token
|
99
|
+
decoded, header = JWT.decode token, 'foobar'
|
100
|
+
taskqueue_update_policy = {
|
101
|
+
'url' => 'https://taskrouter.twilio.com/v1/Workspaces/WS456/TaskQueues/WQ789/**',
|
102
|
+
'method' => 'POST',
|
103
|
+
'query_filter' => {},
|
104
|
+
'post_filter' => {},
|
105
|
+
'allow' => true
|
106
|
+
}
|
107
|
+
expect(decoded['policies'][-1]).to eq(taskqueue_update_policy)
|
108
|
+
expect(decoded['policies'].size).to eq(policies_size+1)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|