didww-v3 1.3.1 → 4.0.0

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests.yml +5 -1
  3. data/.rubocop.yml +3 -0
  4. data/CHANGELOG.md +51 -2
  5. data/Gemfile +2 -1
  6. data/README.md +10 -1
  7. data/Rakefile +1 -0
  8. data/bin/console +1 -0
  9. data/didww-v3.gemspec +3 -1
  10. data/lib/didww/{middleware.rb → base_middleware.rb} +5 -4
  11. data/lib/didww/callback/const.rb +14 -0
  12. data/lib/didww/callback/request_validator.rb +77 -0
  13. data/lib/didww/client.rb +98 -39
  14. data/lib/didww/complex_objects/base.rb +2 -3
  15. data/lib/didww/complex_objects/capacity_order_item.rb +1 -0
  16. data/lib/didww/complex_objects/configurations/base.rb +143 -2
  17. data/lib/didww/complex_objects/configurations/h323_configuration.rb +1 -0
  18. data/lib/didww/complex_objects/configurations/iax2_configuration.rb +1 -0
  19. data/lib/didww/complex_objects/configurations/pstn_configuration.rb +1 -0
  20. data/lib/didww/complex_objects/configurations/sip_configuration.rb +34 -3
  21. data/lib/didww/complex_objects/configurations.rb +1 -0
  22. data/lib/didww/complex_objects/did_order_item.rb +15 -12
  23. data/lib/didww/complex_objects/export_filters.rb +26 -0
  24. data/lib/didww/encrypt.rb +101 -0
  25. data/lib/didww/jsonapi_middleware.rb +21 -0
  26. data/lib/didww/resource/address.rb +37 -0
  27. data/lib/didww/resource/address_verification.rb +56 -0
  28. data/lib/didww/resource/area.rb +12 -0
  29. data/lib/didww/{resources → resource}/available_did.rb +2 -0
  30. data/lib/didww/{resources → resource}/balance.rb +1 -0
  31. data/lib/didww/{resources → resource}/base.rb +2 -2
  32. data/lib/didww/{resources → resource}/capacity_pool.rb +1 -0
  33. data/lib/didww/resource/city.rb +14 -0
  34. data/lib/didww/{resources → resource}/country.rb +1 -0
  35. data/lib/didww/{resources → resource}/did.rb +5 -3
  36. data/lib/didww/{resources → resource}/did_group.rb +13 -25
  37. data/lib/didww/{resources → resource}/did_group_type.rb +1 -0
  38. data/lib/didww/{resources → resource}/did_reservation.rb +1 -0
  39. data/lib/didww/resource/encrypted_file.rb +58 -0
  40. data/lib/didww/{resources/cdr_export.rb → resource/export.rb} +24 -5
  41. data/lib/didww/resource/identity.rb +78 -0
  42. data/lib/didww/resource/nanpa_prefix.rb +18 -0
  43. data/lib/didww/{resources → resource}/order.rb +20 -12
  44. data/lib/didww/resource/permanent_supporting_document.rb +15 -0
  45. data/lib/didww/{resources → resource}/pop.rb +1 -0
  46. data/lib/didww/resource/proof.rb +19 -0
  47. data/lib/didww/resource/proof_type.rb +14 -0
  48. data/lib/didww/resource/public_key.rb +12 -0
  49. data/lib/didww/{resources → resource}/qty_based_pricing.rb +1 -0
  50. data/lib/didww/{resources → resource}/region.rb +1 -0
  51. data/lib/didww/resource/requirement.rb +61 -0
  52. data/lib/didww/resource/requirement_validation.rb +10 -0
  53. data/lib/didww/{resources → resource}/shared_capacity_group.rb +1 -0
  54. data/lib/didww/{resources → resource}/stock_keeping_unit.rb +1 -0
  55. data/lib/didww/resource/supporting_document_template.rb +14 -0
  56. data/lib/didww/{resources/trunk.rb → resource/voice_in_trunk.rb} +40 -4
  57. data/lib/didww/{resources/trunk_group.rb → resource/voice_in_trunk_group.rb} +3 -2
  58. data/lib/didww/resource/voice_out_trunk.rb +75 -0
  59. data/lib/didww/resource/voice_out_trunk_regenerate_credential.rb +11 -0
  60. data/lib/didww/types/ip_addresses.rb +23 -0
  61. data/lib/didww/types/strings.rb +21 -0
  62. data/lib/didww/types.rb +12 -0
  63. data/lib/didww/version.rb +2 -1
  64. data/lib/didww.rb +6 -1
  65. metadata +63 -28
  66. data/lib/didww/complex_objects/cdr_export_filter.rb +0 -23
  67. data/lib/didww/complex_objects/configurations/const.rb +0 -149
  68. data/lib/didww/resources/city.rb +0 -9
  69. data/lib/didww/resources/trunk/const.rb +0 -46
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module ComplexObject
3
4
  module Configuration
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module ComplexObject
3
4
  module Configuration
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module ComplexObject
3
4
  module Configuration
@@ -147,7 +148,7 @@ module DIDWW
147
148
  property :transport_protocol_id, type: :integer
148
149
  # Type: Integer
149
150
  # Nullable: No
150
- # Description: The transport layer that will be responsible for the actual transmission of SIP requests and responses (1 - UDP, 2 - TCP)
151
+ # Description: The transport layer that will be responsible for the actual transmission of SIP requests and responses. See TRANSPORT_PROTOCOLS for available values.
151
152
 
152
153
  property :max_transfers, type: :integer
153
154
  # Nullable: No
@@ -157,6 +158,36 @@ module DIDWW
157
158
  # Nullable: No
158
159
  # Description: Max count of 301/302 redirects
159
160
 
161
+ property :media_encryption_mode, type: :string
162
+ # Type: String
163
+ # Nullable: No
164
+ # Description: The Media encryption mode for RTP traffic. See MEDIA_ENCRYPTION_MODES for available values.
165
+
166
+ property :stir_shaken_mode, type: :string
167
+ # Type: String
168
+ # Nullable: No
169
+ # Description: The STIR/SHAKEN mode for sending identity via SIP. See STIR_SHAKEN_MODES for available values.
170
+
171
+ property :allowed_rtp_ips, type: :ip_addresses
172
+ # Type: Array of strings
173
+ # Nullable: Yes
174
+ # Description: Allowed IP addresses for RTP connection.
175
+
176
+ MEDIA_ENCRYPTION_MODES = [
177
+ 'disabled',
178
+ 'srtp_sdes',
179
+ 'srtp_dtls',
180
+ 'zrtp'
181
+ ].freeze
182
+
183
+ STIR_SHAKEN_MODES = [
184
+ 'disabled',
185
+ 'original',
186
+ 'pai',
187
+ 'original_pai',
188
+ 'verstat'
189
+ ].freeze
190
+
160
191
  DEFAULTS = {
161
192
  username: DID_PLACEHOLDER,
162
193
  port: '5060',
@@ -176,7 +207,7 @@ module DIDWW
176
207
  transport_protocol_id: 1
177
208
  }.freeze
178
209
 
179
- RECOMMENDED = DEFAULTS.merge({
210
+ RECOMMENDED = DEFAULTS.merge(
180
211
  #-- Authentication
181
212
  auth_user: '',
182
213
  auth_password: '',
@@ -190,7 +221,7 @@ module DIDWW
190
221
  #-- Advanced Signalling Settings
191
222
  sst_enabled: false,
192
223
  sst_session_expires: '',
193
- }).freeze
224
+ ).freeze
194
225
 
195
226
  def sst_refresh_method
196
227
  SST_REFRESH_METHODS[sst_refresh_method_id]
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'didww/complex_objects/configurations/base'
2
3
  require 'didww/complex_objects/configurations/sip_configuration'
3
4
  require 'didww/complex_objects/configurations/iax2_configuration'
@@ -1,21 +1,24 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module ComplexObject
3
4
  class DidOrderItem < Base
4
5
  # passed at order creation
5
- property :qty, type: :int
6
- property :available_did_id, type: :string
7
- property :did_reservation_id, type: :string
8
- property :sku_id, type: :string
6
+ property :qty, type: :int
7
+ property :available_did_id, type: :string
8
+ property :did_reservation_id, type: :string
9
+ property :sku_id, type: :string
10
+ property :billing_cycles_count, type: :string
11
+ property :nanpa_prefix_id, type: :string
9
12
 
10
13
  # returned
11
- property :setup_price, type: :decimal
12
- property :monthly_price, type: :decimal
13
- property :nrc, type: :decimal
14
- property :mrc, type: :decimal
15
- property :propated_mrc, type: :boolean
16
- property :billed_from, type: :string
17
- property :billed_to, type: :string
18
- property :did_group_id, type: :string
14
+ property :setup_price, type: :decimal
15
+ property :monthly_price, type: :decimal
16
+ property :nrc, type: :decimal
17
+ property :mrc, type: :decimal
18
+ property :propated_mrc, type: :boolean
19
+ property :billed_from, type: :string
20
+ property :billed_to, type: :string
21
+ property :did_group_id, type: :string
19
22
  end
20
23
  end
21
24
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ require 'json_api_client/schema'
3
+
4
+ module DIDWW
5
+ module ComplexObject
6
+ class ExportFilters < Base
7
+ # Type casting for JsonApiClient parser/setters
8
+ def self.cast_single_object(hash)
9
+ new(hash)
10
+ end
11
+
12
+ property :year, type: :integer
13
+ property :month, type: :integer
14
+ property :day, type: :integer # only for CDR Out
15
+ property :did_number, type: :string # only for CDR in
16
+ property :voice_out_trunk_id, type: :string # only for CDR Out
17
+
18
+ def as_json(*)
19
+ result = attributes.as_json.with_indifferent_access
20
+ result[:'voice_out_trunk.id'] = result.delete(:voice_out_trunk_id) if result.key?(:voice_out_trunk_id)
21
+ result
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+ require 'openssl'
3
+ require 'openssl/oaep'
4
+ require 'net/http'
5
+
6
+ module DIDWW
7
+ # Allows to encrypt file on Ruby-side before uploading to `/v3/encrypted_files`.
8
+ # @example
9
+ # file_content_1 = File.read('file_to_send_1.jpg', mode: 'rb')
10
+ # file_content_2 = File.read('file_to_send_1.pdf', mode: 'rb')
11
+ # enc = DIDWW::Encrypt.new
12
+ # enc_data_1 = enc.encrypt(file_content_1)
13
+ # enc_data_2 = enc.encrypt(file_content_2)
14
+ # enc_io_1 = Faraday::UploadIO.new(StringIO.new(enc_data_1), 'application/octet-stream')
15
+ # enc_io_2 = Faraday::UploadIO.new(StringIO.new(enc_data_2), 'application/octet-stream')
16
+ # DIDWW::Resource::EncryptedFile.upload(
17
+ # encryption_fingerprint: enc.encryption_fingerprint,
18
+ # items: [
19
+ # { file: enc_io_1, description: 'file_to_send_1.jpg' },
20
+ # { file: enc_io_2, description: 'file_to_send_2.pdf' }
21
+ # ]
22
+ # ) # => Array if IDs
23
+ #
24
+ class Encrypt
25
+ AES_ALGO = [256, :CBC]
26
+ AES_KEY_LEN = 32
27
+ AES_IV_LEN = 16
28
+ LABEL = ''
29
+ SEPARATOR = ':::'
30
+
31
+ class << self
32
+ # @param binary [String]
33
+ # @return [String]
34
+ def encrypt(binary)
35
+ new.encrypt(binary)
36
+ end
37
+ end
38
+
39
+ attr_reader :public_keys, :encryption_fingerprint
40
+
41
+ def initialize
42
+ reset!
43
+ end
44
+
45
+ # @param binary [String] binary content of a file.
46
+ # @return [String] binary content of an encrypted file.
47
+ def encrypt(binary)
48
+ aes_key, aes_iv, encrypted_aes = encrypt_aes(binary)
49
+ aes_credentials = aes_key + aes_iv
50
+ encrypted_rsa_a = encrypt_rsa_oaep(public_keys[0], aes_credentials)
51
+ encrypted_rsa_b = encrypt_rsa_oaep(public_keys[1], aes_credentials)
52
+ encrypted_rsa_a + encrypted_rsa_b + encrypted_aes
53
+ end
54
+
55
+ # Resets public keys and fingerprint.
56
+ def reset!
57
+ @public_keys = fetch_public_keys
58
+ @encryption_fingerprint = calculate_fingerprint
59
+ end
60
+
61
+ private
62
+
63
+ # @return [Array(String,String)] public keys.
64
+ def fetch_public_keys
65
+ DIDWW::Resource::PublicKey.find.map(&:key)
66
+ end
67
+
68
+ def calculate_fingerprint
69
+ public_keys.map { |pub_key| fingerprint_for(pub_key) }.join(SEPARATOR)
70
+ end
71
+
72
+ # @param public_key [String] PEM public key.
73
+ # @return [String] hexstring digest SHA1 for public key binary.
74
+ def fingerprint_for(public_key)
75
+ public_key += "\n" unless public_key[-1] == "\n"
76
+ public_key_base64 = public_key.split("\n")[1..-2].join
77
+ public_key_bin = Base64.decode64(public_key_base64)
78
+ OpenSSL::Digest::SHA1.hexdigest(public_key_bin)
79
+ end
80
+
81
+ # @param public_key [String]
82
+ # @param text [String]
83
+ def encrypt_rsa_oaep(public_key, text)
84
+ rsa = OpenSSL::PKey::RSA.new(public_key)
85
+ rsa.public_encrypt_oaep(text, LABEL, OpenSSL::Digest::SHA256)
86
+ end
87
+
88
+ # @param binary [String]
89
+ # @return [Array(String,String,String)] binaries key, vector, encrypted data.
90
+ def encrypt_aes(binary)
91
+ key = SecureRandom.random_bytes(AES_KEY_LEN)
92
+ iv = SecureRandom.random_bytes(AES_IV_LEN)
93
+ cipher = OpenSSL::Cipher::AES.new(*AES_ALGO)
94
+ cipher.encrypt
95
+ cipher.key = key
96
+ cipher.iv = iv
97
+ encrypted = cipher.update(binary) + cipher.final
98
+ [key, iv, encrypted]
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+ module DIDWW
3
+ # :nodoc:
4
+ class JsonapiMiddleware < Faraday::Middleware
5
+ def call(request_env)
6
+ headers = {}
7
+ headers['Content-Type'] = 'application/vnd.api+json'
8
+ headers['Api-Key'] = DIDWW::Client.api_key
9
+ headers['User-Agent'] = "didww-v3 Ruby gem v#{VERSION}"
10
+ headers['x-didww-api-version'] = DIDWW::Client.api_version unless DIDWW::Client.api_version.blank?
11
+
12
+ request_env[:request_headers].merge!(headers)
13
+ request_env.url.host = URI(DIDWW::Client.api_base_url).host
14
+
15
+ @app.call(request_env).on_complete do |response_env|
16
+ # do something with the response
17
+ # response_env[:response_headers].merge!(...)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+ module DIDWW
3
+ module Resource
4
+ class Address < Base
5
+
6
+ has_one :identity, class_name: 'Identity'
7
+ has_one :country, class_name: 'Country'
8
+ has_many :proofs, class_name: 'Proof'
9
+ has_many :city, class_name: 'City'
10
+ has_many :area, class_name: 'Area'
11
+
12
+ property :city_name, type: :string
13
+ # Type: String
14
+ # Description:
15
+
16
+ property :postal_code, type: :string
17
+ # Type: String
18
+ # Description:
19
+
20
+ property :address, type: :string
21
+ # Type: String
22
+ # Description:
23
+
24
+ property :description, type: :string
25
+ # Type: String
26
+ # Description:
27
+
28
+ property :created_at, type: :date
29
+ # Type: Date
30
+ # Description:
31
+
32
+ property :verified, type: :boolean
33
+ # Type: Boolean
34
+ # Description:
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+ module DIDWW
3
+ module Resource
4
+ class AddressVerification < Base
5
+ STATUS_PENDING = 'Pending'
6
+ STATUS_APPROVED = 'Approved'
7
+ STATUS_REJECTED = 'Rejected'
8
+ STATUSES = [
9
+ STATUS_PENDING,
10
+ STATUS_APPROVED,
11
+ STATUS_REJECTED
12
+ ].freeze
13
+
14
+ has_one :address, class_name: 'Address'
15
+ has_many :dids, class_name: 'Did'
16
+ has_many :onetime_files, class_name: 'EncryptedFile'
17
+
18
+ property :service_description, type: :string
19
+ # Type: String
20
+ # Description:
21
+
22
+ property :status, type: :string
23
+ # Type: String
24
+ # Description:
25
+
26
+ property :reject_reasons, type: :string
27
+ # Type: String
28
+ # Description:
29
+
30
+ property :created_at, type: :date
31
+ # Type: Date
32
+ # Description:
33
+
34
+ property :callback_url, type: :string
35
+ # Type: String
36
+ # Description: valid URI for callbacks
37
+
38
+ property :callback_method, type: :string
39
+ # Type: String
40
+ # Description: GET or POST
41
+
42
+ def pending?
43
+ status == STATUS_PENDING
44
+ end
45
+
46
+ def approved?
47
+ status == STATUS_APPROVED
48
+ end
49
+
50
+ def rejected?
51
+ status == STATUS_REJECTED
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+ module DIDWW
3
+ module Resource
4
+ class Area < Base
5
+ has_one :country, class_name: 'Country'
6
+
7
+ property :name, type: :string
8
+ # Type: String
9
+ # Description: Regulatory Area name
10
+ end
11
+ end
12
+ end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module Resource
3
4
  class AvailableDid < Base
4
5
  has_one :did_group
6
+ has_one :nanpa_prefix
5
7
 
6
8
  property :number, type: :string
7
9
  # Type: String
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module Resource
3
4
  class Balance < Base
@@ -1,5 +1,5 @@
1
- require 'didww/middleware'
2
- require 'didww/complex_objects/base'
1
+ # frozen_string_literal: true
2
+ require 'didww/jsonapi_middleware'
3
3
 
4
4
  module DIDWW
5
5
  module Resource
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module Resource
3
4
  class CapacityPool < Base
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ module DIDWW
3
+ module Resource
4
+ class City < Base
5
+ has_one :country, class_name: 'Country'
6
+ has_one :region, class_name: 'Region'
7
+ has_one :area, class_name: 'Area'
8
+
9
+ property :name, type: :string
10
+ # Type: String
11
+ # Description: City name
12
+ end
13
+ end
14
+ end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module Resource
3
4
  class Country < Base
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module Resource
3
4
  class Did < Base
4
- has_one :trunk
5
- has_one :trunk_group
5
+ has_one :voice_in_trunk
6
+ has_one :voice_in_trunk_group
6
7
  has_one :capacity_pool
7
8
  has_one :shared_capacity_group
9
+ has_one :address_verification
8
10
 
9
11
  property :blocked, type: :boolean
10
12
  # Type: Boolean
@@ -18,7 +20,7 @@ module DIDWW
18
20
  # Type: Boolean
19
21
  # Description: Identifier for terminated DIDs that will be removed from service at the end of the billing cycle.
20
22
 
21
- property :pending_removal, type: :boolean
23
+ property :billing_cycles_count, type: :integer
22
24
  # Type: Boolean
23
25
  # Description: Identifier for DIDs that are pending removal from your account.
24
26
 
@@ -1,23 +1,16 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module Resource
3
4
  class DidGroup < Base
4
- module CONST
5
- # Possible values for did_group.features array
6
- FEATURE_VOICE = 'voice' .freeze
7
- FEATURE_T38 = 't38' .freeze
8
- FEATURE_SMS = 'sms' .freeze
9
- FEATURES = {
10
- FEATURE_VOICE => 'Voice' .freeze,
11
- FEATURE_T38 => 'T.38 Fax' .freeze,
12
- FEATURE_SMS => 'SMS' .freeze
13
- }.freeze
14
-
15
- def features_human
16
- Array.wrap(features).map { |f| FEATURES[f] }
17
- end
18
- end
19
-
20
- include CONST
5
+ # Possible values for did_group.features array
6
+ FEATURE_VOICE = 'voice' .freeze
7
+ FEATURE_T38 = 't38' .freeze
8
+ FEATURE_SMS = 'sms' .freeze
9
+ FEATURES = {
10
+ FEATURE_VOICE => 'Voice' .freeze,
11
+ FEATURE_T38 => 'T.38 Fax' .freeze,
12
+ FEATURE_SMS => 'SMS' .freeze
13
+ }.freeze
21
14
 
22
15
  has_one :country, class: Country
23
16
  has_one :city, class: City
@@ -30,10 +23,6 @@ module DIDWW
30
23
  # Type: String
31
24
  # Description: DID Group prefix (city or area calling code)
32
25
 
33
- property :local_prefix, type: :string
34
- # Type: String
35
- # Description: DID Group local prefix
36
-
37
26
  property :features, type: :complex_object # TODO implement array of strings?
38
27
  # Type: Array of strings
39
28
  # Description: Features available for the DID Group, including voice, sms and t38. A DID Group may have multiple features.
@@ -60,11 +49,10 @@ module DIDWW
60
49
  # is_available
61
50
  # Type: Boolean
62
51
  # Description: Defines if numbers in this DID Group are currently in stock.
63
- #
64
- # restrictions
65
- # Type: String
66
- # Description: Describes possible restrictions for the DID Group, such as "End User Registration is Required".
67
52
 
53
+ def features_human
54
+ Array.wrap(features).map { |f| FEATURES[f] }
55
+ end
68
56
  end
69
57
  end
70
58
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module Resource
3
4
  class DidGroupType < Base
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module DIDWW
2
3
  module Resource
3
4
  class DidReservation < Base
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+ module DIDWW
3
+ module Resource
4
+ class EncryptedFile < Base
5
+ class UploadError < StandardError
6
+ end
7
+
8
+ property :description, type: :string
9
+ # Type: String
10
+ # Description:
11
+
12
+ property :expire_at, type: :date
13
+ # Type: Date
14
+ # Description:
15
+
16
+ # @return [Faraday::Connection]
17
+ def self.upload_connection
18
+ Faraday.new(url: site) do |connection|
19
+ connection.request :multipart
20
+ connection.request :url_encoded
21
+ connection.adapter Faraday.default_adapter
22
+ connection.use DIDWW::BaseMiddleware
23
+ end
24
+ end
25
+
26
+ # @param files [Rack::Multipart::UploadedFile,(#tempfile,#content_type,#original_filename)]
27
+ # @return [Array<String>]
28
+ # @raise [DIDWW::Resource::EncryptedFile::UploadError]
29
+ def self.upload_files(files, fingerprint)
30
+ items = files.map do |file|
31
+ {
32
+ file: Faraday::UploadIO.new(file.tempfile, file.content_type),
33
+ description: file.original_filename
34
+ }
35
+ end
36
+ payload = { encryption_fingerprint: fingerprint, items: items }
37
+ upload(payload)
38
+ end
39
+
40
+ # @param payload [Hash]
41
+ # encryption_fingerprint [String] DIDWW::Encrypt#encryption_fingerprint
42
+ # items [Array]
43
+ # file [Faraday::UploadIO] upload io
44
+ # description [String,nil] optional description
45
+ # @return [Array<String>]
46
+ # @raise [DIDWW::Resource::EncryptedFile::UploadError]
47
+ def self.upload(payload)
48
+ connection = upload_connection
49
+ response = connection.post('/v3/encrypted_files', encrypted_files: payload)
50
+ if response.status == 201
51
+ JSON.parse(response.body, symbolize_names: true)[:ids]
52
+ else
53
+ raise UploadError, "Code: #{response.status} #{response.body}"
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,13 +1,24 @@
1
+ # frozen_string_literal: true
1
2
  require 'forwardable'
2
- require 'didww/complex_objects/cdr_export_filter'
3
3
  require 'down/http'
4
+ require 'didww/callback/const'
4
5
 
5
6
  module DIDWW
6
7
  module Resource
7
- class CdrExport < Base
8
+ class Export < Base
9
+ include DIDWW::Callback::CONST
8
10
  extend Forwardable
9
11
 
10
- property :filters, type: :cdr_export_filter
12
+ STATUS_COMPLETED = 'Completed'
13
+
14
+ EXPORT_TYPE_CDR_IN = 'cdr_in'
15
+ EXPORT_TYPE_CDR_OUT = 'cdr_out'
16
+ EXPORT_TYPES = [
17
+ EXPORT_TYPE_CDR_IN,
18
+ EXPORT_TYPE_CDR_OUT
19
+ ].freeze
20
+
21
+ property :filters, type: :export_filters
11
22
  # Type: CDR Export Filters Object
12
23
  # Nullable: No
13
24
  # Description: Filters
@@ -27,7 +38,15 @@ module DIDWW
27
38
  # Nullable: true
28
39
  # Description: url of csv file for downloading. available only when status is "Completed"
29
40
 
30
- def_delegators :filters, :year, :month, :did_number, :year=, :month=, :did_number=
41
+ property :callback_url, type: :string
42
+ # Type: String
43
+ # Description: valid URI for callbacks
44
+
45
+ property :callback_method, type: :string
46
+ # Type: String
47
+ # Description: GET or POST
48
+
49
+ property :export_type, type: :string
31
50
 
32
51
  def initialize(params = {})
33
52
  super params.reverse_merge(filters: {})
@@ -39,7 +58,7 @@ module DIDWW
39
58
  end
40
59
 
41
60
  def complete?
42
- status == 'Completed'
61
+ status == STATUS_COMPLETED
43
62
  end
44
63
  alias_method :completed?, :complete?
45
64
  end