plivo 4.6.0 → 4.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +1 -1
- data/examples/jwt.rb +23 -0
- data/lib/plivo.rb +1 -0
- data/lib/plivo/base_client.rb +1 -1
- data/lib/plivo/jwt.rb +120 -0
- data/lib/plivo/resources/conferences.rb +5 -11
- data/lib/plivo/resources/messages.rb +6 -0
- data/lib/plivo/utils.rb +73 -1
- data/lib/plivo/version.rb +1 -2
- data/plivo.gemspec +1 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d2abbec45f547e53a13a247ee7bdb26f31989ecd
|
4
|
+
data.tar.gz: 104fb33b21b5b76110bf5a8c1e163fdfe1aff1aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 04c349f9f8d3679c55758fa6cf3f99ea2f259b5d433197c1c24e1fd624e625ae879330d9f207a241a1bf2f368ce0025714c99f74d46a7ea5ec15d05b76048d92
|
7
|
+
data.tar.gz: 600404b7732b9943bd1a302ca05baa68e38da599eff55f86a4c90bdb6dfb6af60c282fa9e842a31a25ffefb2a87df487e7b35b161eac6b56ee97d0d030a0e53e
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [4.8.1](https://github.com/plivo/plivo-ruby/releases/tag/v4.8.1) (2020-06-05)
|
4
|
+
- Fix Record a Conference API response.
|
5
|
+
|
6
|
+
## [4.8.0](https://github.com/plivo/plivo-ruby/releases/tag/v4.8.0) (2020-05-28)
|
7
|
+
- Add JWT helper functions.
|
8
|
+
|
9
|
+
## [4.7.1](https://github.com/plivo/plivo-ruby/releases/tag/v4.7.1) (2020-05-06)
|
10
|
+
- Fix Send MMS with existing media_ids.
|
11
|
+
|
12
|
+
## [4.7.0](https://github.com/plivo/plivo-ruby/releases/tag/v4.7.0) (2020-04-29)
|
13
|
+
- Add V3 signature helper functions.
|
14
|
+
|
15
|
+
## [4.6.1](https://github.com/plivo/plivo-ruby/releases/tag/v4.6.1) (2020-04-02)
|
16
|
+
- Add nil check for API requests.
|
17
|
+
|
3
18
|
## [4.6.0](https://github.com/plivo/plivo-ruby/releases/tag/v4.6.0) (2020-03-31)
|
4
19
|
- Add application cascade delete support.
|
5
20
|
|
data/README.md
CHANGED
data/examples/jwt.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'plivo'
|
3
|
+
|
4
|
+
include Plivo
|
5
|
+
|
6
|
+
AUTH_ID = 'MADADADADADADADADADA'
|
7
|
+
AUTH_TOKEN = 'AUTH_TOKEN'
|
8
|
+
|
9
|
+
begin
|
10
|
+
acctkn = Plivo::Token::AccessToken.new(
|
11
|
+
AUTH_ID,
|
12
|
+
AUTH_TOKEN,
|
13
|
+
'{username}',
|
14
|
+
'{uid}'
|
15
|
+
)
|
16
|
+
# update token validity (from, lifetime, till)
|
17
|
+
acctkn.update_validity(Time.now, 300)
|
18
|
+
# add voice grants (incoming, outgoing)
|
19
|
+
acctkn.add_voice_grants(Plivo::Token::VoiceGrants.new(true, true))
|
20
|
+
puts acctkn.to_jwt
|
21
|
+
rescue ValidationError => e
|
22
|
+
puts 'Exception: ' + e.message
|
23
|
+
end
|
data/lib/plivo.rb
CHANGED
data/lib/plivo/base_client.rb
CHANGED
@@ -167,7 +167,7 @@ module Plivo
|
|
167
167
|
req.body = data
|
168
168
|
end
|
169
169
|
else
|
170
|
-
if data.has_key? 'is_callinsights_request'
|
170
|
+
if !data.nil? && (data.has_key? 'is_callinsights_request')
|
171
171
|
callinsight_base_url = data['callinsight_base_url']
|
172
172
|
resource_path = data['request_url']
|
173
173
|
data.delete('is_callinsights_request')
|
data/lib/plivo/jwt.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'openssl'
|
4
|
+
require 'uri'
|
5
|
+
require 'base64'
|
6
|
+
require 'date'
|
7
|
+
require 'jwt'
|
8
|
+
|
9
|
+
module Plivo
|
10
|
+
module Token
|
11
|
+
include Utils
|
12
|
+
|
13
|
+
class VoiceGrants
|
14
|
+
attr_reader :incoming_allow, :outgoing_allow
|
15
|
+
|
16
|
+
def initialize(incoming = nil, outgoing = nil)
|
17
|
+
Utils.valid_param?(:incoming, incoming, [TrueClass, FalseClass], false)
|
18
|
+
Utils.valid_param?(:outgoing, outgoing, [TrueClass, FalseClass], false)
|
19
|
+
@incoming_allow = incoming
|
20
|
+
@outgoing_allow = outgoing
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_hash
|
24
|
+
hash = {}
|
25
|
+
instance_variables.each { |var| hash[var.to_s.delete('@')] = instance_variable_get(var) }
|
26
|
+
hash
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class AccessToken
|
31
|
+
attr_reader :uid, :username, :valid_from, :lifetime, :grants
|
32
|
+
def initialize(auth_id = nil, auth_token = nil, username = nil, uid = nil)
|
33
|
+
configure_credentials(auth_id, auth_token)
|
34
|
+
Utils.valid_param?(:username, username, [String, Symbol], true)
|
35
|
+
@username = username
|
36
|
+
|
37
|
+
Utils.valid_param?(:uid, uid, [String, Symbol], false)
|
38
|
+
uid ||= username + '-' + Time.now.to_i
|
39
|
+
@uid = uid
|
40
|
+
update_validity
|
41
|
+
end
|
42
|
+
|
43
|
+
def update_validity(valid_from = nil, lifetime = nil, valid_till = nil)
|
44
|
+
Utils.valid_param?(:valid_from, valid_from, [Time, Integer], false)
|
45
|
+
Utils.valid_param?(:lifetime, lifetime, [Integer], false)
|
46
|
+
Utils.valid_param?(:valid_till, valid_till, [Time, Integer], false)
|
47
|
+
|
48
|
+
if valid_from.nil?
|
49
|
+
@lifetime = lifetime || 84_600
|
50
|
+
@valid_from = if valid_till.nil?
|
51
|
+
Time.now
|
52
|
+
else
|
53
|
+
Time.at(valid_till.to_i - @lifetime).utc
|
54
|
+
end
|
55
|
+
|
56
|
+
elsif valid_till.nil?
|
57
|
+
@lifetime = lifetime || 84_600
|
58
|
+
@valid_from = valid_from
|
59
|
+
else
|
60
|
+
unless lifetime.nil?
|
61
|
+
raise Exceptions::ValidationError, 'use any 2 of valid_from, lifetime and valid_till'
|
62
|
+
end
|
63
|
+
|
64
|
+
@valid_from = valid_from
|
65
|
+
@lifetime = valid_till.to_i - valid_from.to_i
|
66
|
+
end
|
67
|
+
|
68
|
+
return unless @lifetime < 180 || @lifetime > 84_600
|
69
|
+
|
70
|
+
raise Exceptions::ValidationError, 'validity out of [180, 84600] seconds'
|
71
|
+
end
|
72
|
+
|
73
|
+
def auth_id
|
74
|
+
@auth_credentials[:auth_id]
|
75
|
+
end
|
76
|
+
|
77
|
+
def add_voice_grants(grants)
|
78
|
+
Utils.valid_param?(:grants, grants, [VoiceGrants], true)
|
79
|
+
@grants = grants
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_jwt
|
83
|
+
payload = {
|
84
|
+
jti: uid,
|
85
|
+
sub: username,
|
86
|
+
iss: auth_id,
|
87
|
+
nbf: valid_from.to_i,
|
88
|
+
exp: valid_from.to_i + lifetime,
|
89
|
+
grants: {
|
90
|
+
voice: grants.to_hash || {}
|
91
|
+
}
|
92
|
+
}
|
93
|
+
JWT.encode payload, key, 'HS256', {typ: 'JWT', cty: 'plivo;v=1'}
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def key
|
99
|
+
@auth_credentials[:auth_token]
|
100
|
+
end
|
101
|
+
|
102
|
+
def configure_credentials(auth_id, auth_token)
|
103
|
+
# Fetches and sets the right credentials
|
104
|
+
auth_id ||= ENV['PLIVO_AUTH_ID']
|
105
|
+
auth_token ||= ENV['PLIVO_AUTH_TOKEN']
|
106
|
+
|
107
|
+
raise Exceptions::AuthenticationError, 'Couldn\'t find auth credentials' unless
|
108
|
+
auth_id && auth_token
|
109
|
+
|
110
|
+
raise Exceptions::AuthenticationError, "Invalid auth_id: '#{auth_id}'" unless
|
111
|
+
Utils.valid_account?(auth_id)
|
112
|
+
|
113
|
+
@auth_credentials = {
|
114
|
+
auth_id: auth_id,
|
115
|
+
auth_token: auth_token
|
116
|
+
}
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -186,18 +186,12 @@ module Plivo
|
|
186
186
|
end
|
187
187
|
|
188
188
|
def to_s
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
189
|
+
response_json = {}
|
190
|
+
response_variables = self.instance_variables.drop(5)
|
191
|
+
response_variables.each do |variable|
|
192
|
+
response_json[variable.to_s[1..-1]] = self.instance_variable_get(variable)
|
193
193
|
end
|
194
|
-
|
195
|
-
conference_name: @conference_name,
|
196
|
-
conference_run_time: @conference_run_time,
|
197
|
-
conference_member_count: @conference_member_count,
|
198
|
-
members: members_json,
|
199
|
-
api_id: @api_id
|
200
|
-
}.to_s
|
194
|
+
return response_json.to_s
|
201
195
|
end
|
202
196
|
|
203
197
|
def to_json_member(member)
|
@@ -69,6 +69,7 @@ module Plivo
|
|
69
69
|
# @option options [String] :log If set to false, the content of this message will not be logged on the Plivo infrastructure and the dst value will be masked (e.g., 141XXXXX528). Default is set to true.
|
70
70
|
# @option options [String] :trackable set to false
|
71
71
|
#@option options[List]: media_urls Minimum one media url should be present in Media urls list to send mms. Maximum allowd 10 media urls inside the list (e.g, media_urls : ['https//example.com/test.jpg', 'https://example.com/abcd.gif'])
|
72
|
+
#@option options[List]: media_ids Minimum one media ids should be present in Media ids list to send mms. Maximum allowd 10 media ids inside the list (e.g, media_ids : ['1fs211ba-355b-11ea-bbc9-02121c1190q7'])
|
72
73
|
|
73
74
|
def create(src, dst, text = nil, options = nil, powerpack_uuid = nil)
|
74
75
|
valid_param?(:src, src, [Integer, String, Symbol], false)
|
@@ -130,6 +131,10 @@ module Plivo
|
|
130
131
|
valid_param?(:media_urls, options[:media_urls], Array, true)
|
131
132
|
params[:media_urls] = options[:media_urls]
|
132
133
|
end
|
134
|
+
if options.key?(:media_ids) &&
|
135
|
+
valid_param?(:media_ids, options[:media_ids], Array, true)
|
136
|
+
params[:media_ids] = options[:media_ids]
|
137
|
+
end
|
133
138
|
perform_create(params)
|
134
139
|
end
|
135
140
|
|
@@ -148,6 +153,7 @@ module Plivo
|
|
148
153
|
# @option options [Int] :offset Denotes the number of value items by which the results should be offset. Eg:- If the result contains a 1000 values and limit is set to 10 and offset is set to 705, then values 706 through 715 are displayed in the results. This parameter is also used for pagination of the results.
|
149
154
|
# @option options [String] :error_code Delivery Response code returned by the carrier attempting the delivery. See Supported error codes {https://www.plivo.com/docs/api/message/#standard-plivo-error-codes}.
|
150
155
|
#@option options[List]: media_urls Minimum one media url should be present in Media urls list to send mms. Maximum allowd 10 media urls inside the list (e.g, media_urls : ['https//example.com/test.jpg', 'https://example.com/abcd.gif'])
|
156
|
+
#@option options[List]: media_ids Minimum one media ids should be present in Media ids list to send mms. Maximum allowd 10 media ids inside the list (e.g, media_ids : ['1fs211ba-355b-11ea-bbc9-02121c1190q7'])
|
151
157
|
def list(options = nil)
|
152
158
|
return perform_list if options.nil?
|
153
159
|
valid_param?(:options, options, Hash, true)
|
data/lib/plivo/utils.rb
CHANGED
@@ -101,11 +101,83 @@ module Plivo
|
|
101
101
|
# @param [String] auth_token
|
102
102
|
def valid_signature?(uri, nonce, signature, auth_token)
|
103
103
|
parsed_uri = URI.parse(uri)
|
104
|
-
uri_details = {
|
104
|
+
uri_details = {host: parsed_uri.host, path: parsed_uri.path}
|
105
105
|
uri_builder_module = parsed_uri.scheme == 'https' ? URI::HTTPS : URI::HTTP
|
106
106
|
data_to_sign = uri_builder_module.build(uri_details).to_s + nonce
|
107
107
|
sha256_digest = OpenSSL::Digest.new('sha256')
|
108
108
|
Base64.encode64(OpenSSL::HMAC.digest(sha256_digest, auth_token, data_to_sign)).strip() == signature
|
109
109
|
end
|
110
|
+
|
111
|
+
def generate_url?(uri, params, method)
|
112
|
+
uri.sub!("+", "%20")
|
113
|
+
parsed_uri = URI.parse(uri)
|
114
|
+
uri = parsed_uri.scheme + "://" + parsed_uri.host + parsed_uri.path
|
115
|
+
if params.to_s.length > 0 || parsed_uri.query.to_s.length > 0
|
116
|
+
uri += "?"
|
117
|
+
end
|
118
|
+
if parsed_uri.query.to_s.length > 0
|
119
|
+
parsed_uri_query = URI.decode(parsed_uri.query)
|
120
|
+
if method == "GET"
|
121
|
+
queryParamMap = getMapFromQueryString?(parsed_uri_query)
|
122
|
+
params.keys.sort.each { |key|
|
123
|
+
queryParamMap[key] = params[key]
|
124
|
+
}
|
125
|
+
uri += GetSortedQueryParamString?(queryParamMap, true)
|
126
|
+
else
|
127
|
+
uri += GetSortedQueryParamString?(getMapFromQueryString?(parsed_uri_query), true) + "." + GetSortedQueryParamString?(params, false)
|
128
|
+
uri = uri.chomp(".")
|
129
|
+
end
|
130
|
+
else
|
131
|
+
if method == "GET"
|
132
|
+
uri += GetSortedQueryParamString?(params, true)
|
133
|
+
else
|
134
|
+
uri += GetSortedQueryParamString?(params, false)
|
135
|
+
end
|
136
|
+
end
|
137
|
+
return uri
|
138
|
+
end
|
139
|
+
|
140
|
+
def getMapFromQueryString?(query)
|
141
|
+
mp = Hash.new
|
142
|
+
if query.to_s.length == 0
|
143
|
+
return mp
|
144
|
+
end
|
145
|
+
keyValuePairs = query.split("&")
|
146
|
+
keyValuePairs.each { |key|
|
147
|
+
params = key.split("=", 2)
|
148
|
+
if params.length == 2
|
149
|
+
mp[params[0]] = params[1]
|
150
|
+
end
|
151
|
+
}
|
152
|
+
return mp
|
153
|
+
end
|
154
|
+
|
155
|
+
def GetSortedQueryParamString?(params, queryParams)
|
156
|
+
url = ""
|
157
|
+
if queryParams
|
158
|
+
params.keys.sort.each { |key|
|
159
|
+
url += key + "=" + params[key] + "&"
|
160
|
+
}
|
161
|
+
url = url.chomp("&")
|
162
|
+
else
|
163
|
+
params.keys.sort.each { |key|
|
164
|
+
url += key.to_s + params[key].to_s
|
165
|
+
}
|
166
|
+
end
|
167
|
+
return url
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
def compute_signatureV3?(url, auth_token, nonce)
|
172
|
+
sha256_digest = OpenSSL::Digest.new('sha256')
|
173
|
+
new_url = url + "." + nonce
|
174
|
+
return Base64.encode64(OpenSSL::HMAC.digest(sha256_digest, auth_token, new_url)).strip()
|
175
|
+
end
|
176
|
+
|
177
|
+
def valid_signatureV3?(uri, nonce, signature, auth_token, method, params={})
|
178
|
+
new_url = generate_url?(uri, params, method)
|
179
|
+
generated_signature = compute_signatureV3?(new_url, auth_token, nonce)
|
180
|
+
return signature.split(",").include? generated_signature
|
181
|
+
end
|
110
182
|
end
|
111
183
|
end
|
data/lib/plivo/version.rb
CHANGED
data/plivo.gemspec
CHANGED
@@ -34,6 +34,7 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_dependency 'faraday', '~> 0.9'
|
35
35
|
spec.add_dependency 'faraday_middleware', '~> 0.12.2'
|
36
36
|
spec.add_dependency 'htmlentities'
|
37
|
+
spec.add_dependency 'jwt'
|
37
38
|
|
38
39
|
spec.add_development_dependency 'bundler', '>= 1.14', '<3.0'
|
39
40
|
spec.add_development_dependency 'rake', '~> 10.0'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: plivo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The Plivo SDKs Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: jwt
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: bundler
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,6 +164,7 @@ files:
|
|
150
164
|
- Rakefile
|
151
165
|
- ci/config.yml
|
152
166
|
- examples/conference_bridge.rb
|
167
|
+
- examples/jwt.rb
|
153
168
|
- examples/multi_party_call.rb
|
154
169
|
- examples/phlos.rb
|
155
170
|
- lib/plivo.rb
|
@@ -159,6 +174,7 @@ files:
|
|
159
174
|
- lib/plivo/base/response.rb
|
160
175
|
- lib/plivo/base_client.rb
|
161
176
|
- lib/plivo/exceptions.rb
|
177
|
+
- lib/plivo/jwt.rb
|
162
178
|
- lib/plivo/phlo_client.rb
|
163
179
|
- lib/plivo/resources.rb
|
164
180
|
- lib/plivo/resources/accounts.rb
|