cloudinary 1.27.0 → 2.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 46b21a3d7dd2411acaaeb35016f2ff7b648aeae5c1d077870f38e858ce1abedf
4
- data.tar.gz: 5825bea0988e97e71df1d93fde04739b502230cda987f90415cb46f55df8b6b7
3
+ metadata.gz: 1244ab3ce91f6fda0b07e5438ed79f896cde743306efb9c3ac58e5a5f1d4a6dc
4
+ data.tar.gz: a36510b3d2a2e1b788c2455e5def6f314b78b0b94def573a75a4750e96498b6c
5
5
  SHA512:
6
- metadata.gz: 24c1334398c9c24ce9b0b536e991fb76aa633e1bda93b5e8dcccc1d2ac2f747e4645f52b61ad3b6db7bb9a59a092df602c35b964a05661c151fb6026cd1954c0
7
- data.tar.gz: f8f3cdbe7b7374532f5dae2f5dca3543697a2fb2398050b4a7874d6527b3e87ffc84970684aefe25c65f255ba9ec89e15470e28658c28287df781e4ee2144799
6
+ metadata.gz: 7ba876181927174ec445d3abd04c79cc03af3837713c234ea9a89651131b6dd4c4be6e3ec02d155596d4f2ce821b269600adda74210408af066b04e0671169fb
7
+ data.tar.gz: 8bcbb47be56d985537d237fcd5989979555ba0d622bf8a6a3f60484e8b31ffd7d0682353ce4768e4f732edb3fe1a909e001640226fc8fe085ff35cc321b662c6
data/.travis.yml CHANGED
@@ -1,22 +1,16 @@
1
- dist: focal
1
+ dist: jammy
2
2
  language: ruby
3
3
  rvm:
4
- - 2.6.7
5
- - 2.7.4
6
- - 3.0.2
4
+ - 3.1.4
5
+ - 3.2.2
6
+ - 3.3.0
7
7
 
8
8
  matrix:
9
9
  include:
10
- - name: "Ruby 1.9"
11
- dist: precise
12
- rvm: 1.9.3
13
- before_install:
14
- - gem install bundler -v 1.17.3
15
- - name: "Ruby 2.5.9"
16
- dist: xenial
17
- rvm: ruby-2.5.9
18
- before_install:
19
- - gem install bundler -v 2.3.26
10
+ # There is an OpenSSL issue on Jammy with Ruby 3.0
11
+ - name: "Ruby: 3.0.6"
12
+ dist: focal
13
+ rvm: 3.0.6
20
14
 
21
15
  before_script: >
22
16
  export CLOUDINARY_URL=$(bash tools/get_test_cloud.sh);
data/CHANGELOG.md CHANGED
@@ -1,3 +1,129 @@
1
+ 2.3.0 / 2025-02-20
2
+ ==================
3
+
4
+ New functionality and features
5
+ ------------------------------
6
+
7
+ * Add support for `429 Too Many Requests` HTTP status code
8
+ * Add support for `allow_dynamic_list_values` parameter in `MetadataField`
9
+ * Add support for `config` Admin API
10
+
11
+ 2.2.0 / 2024-09-08
12
+ ==================
13
+
14
+ New functionality and features
15
+ ------------------------------
16
+
17
+ * Add support for ActiveStorage model service configuration
18
+
19
+ Other Changes
20
+ -------------
21
+
22
+ * Fix asset type detection in ActiveStorage
23
+ * Add explicit `ostruct` dependency
24
+
25
+ 2.1.2 / 2024-08-18
26
+ ==================
27
+
28
+ * Fix ActiveStorage type detection for email files
29
+ * Add `changelog_uri` to `gemspec`
30
+
31
+ 2.1.1 / 2024-05-28
32
+ ==================
33
+
34
+ * Fix regression in `cloudinary_url` generation
35
+
36
+ 2.1.0 / 2024-05-27
37
+ ==================
38
+
39
+ New functionality and features
40
+ ------------------------------
41
+
42
+ * Add support for `rename_folder` Admin API
43
+ * Add support for `delete_access_key` in Provisioning API
44
+
45
+ Other Changes
46
+ -------------
47
+
48
+ * Fix detection of base64 encoded files with complex MIME type
49
+ * Fix `fetch` url generation with Active Storage `folder` configuration
50
+ * Fix usage of deprecated `File.exists?` method
51
+
52
+ 2.0.2 / 2024-04-09
53
+ ==================
54
+
55
+ * Fix CarrierWave `store!` method
56
+
57
+ 2.0.1 / 2024-04-09
58
+ ==================
59
+
60
+ * Fix rake tasks
61
+
62
+ 2.0.0 / 2024-04-08
63
+ ==================
64
+
65
+ Breaking Changes
66
+ ----------------
67
+
68
+ * Set minimal Ruby version to `3.0`
69
+ * For older Rubies use version `1.x` of this library
70
+ * Replace `rest-client` with `faraday`
71
+ * Set config `secure` to `true` by default
72
+ * All delivery URLs are set to be `https://` by default
73
+ * To disable - set `secure` to `false` in config/options
74
+ * Add support for URL Analytics
75
+ * Adds analytics signature query parameter to the delivery URLs
76
+ * To disable - set `analytics` to `false` in config/options
77
+ * Remove deprecated methods
78
+ * `Cloudinary::Utils.unsigned_download_url`
79
+ * use `Cloudinary::Utils.cloudinary_url` instead
80
+ * `Cloudinary::Utils.signed_download_url`
81
+ * use `Cloudinary::Utils.cloudinary_url` instead
82
+ * `Cloudinary::Utils.zip_download_url`
83
+ * use `Cloudinary::Utils.download_zip_url` instead
84
+ * `cl_zip_download_url`
85
+ * use `cl_download_zip_url` instead
86
+ * Remove deprecated constants
87
+
88
+ New functionality and features
89
+ ------------------------------
90
+
91
+ * Add support for `analyze` API
92
+ * Support chunked uploads with CarrierWave
93
+ * Filter users by last login in `users` Provisioning API
94
+
95
+ 1.29.0 / 2024-02-26
96
+ ==================
97
+
98
+ New functionality and features
99
+ ------------------------------
100
+
101
+ * Add support for `context` parameter in `url_for_direct_upload`
102
+ * Add support for `use_fetch_format` parameter in `cl_video_tag`
103
+ * Add support for `fields` parameter in Search and Admin APIs
104
+ * Add support for access keys management in Account Provisioning API
105
+
106
+ Other Changes
107
+ -------------
108
+
109
+ * Avoid early loading of `ActionView::Base`
110
+ * Fix `sqlite3` dependency version
111
+ * Add Rails 7.x to supported versions on `README.md`
112
+
113
+ 1.28.0 / 2023-11-06
114
+ ==================
115
+
116
+ New functionality and features
117
+ ------------------------------
118
+
119
+ * Add support for `image_file` parameter in `visual_search` Admin API
120
+ * Add support for `on_success` upload parameter
121
+
122
+ Other Changes
123
+ -------------
124
+
125
+ * Replace `update_all` to `update_column` in CarrierWave storage
126
+
1
127
  1.27.0 / 2023-07-31
2
128
  ==================
3
129
 
data/README.md CHANGED
@@ -40,11 +40,13 @@ the [Ruby on Rails SDK Guide](https://cloudinary.com/documentation/rails_integra
40
40
 
41
41
  | SDK Version | Ruby 1.9.3 | Ruby 2.x | Ruby 3.x |
42
42
  |-------------|------------|----------|----------|
43
- | 1.x | v | v | v |
43
+ | 1.x | | | |
44
+ | 2.x | ✘ | ✘ | ✔ |
44
45
 
45
- | SDK Version | Rails 5.x | Rails 6.x |
46
- |-------------|-----------|-----------|
47
- | 1.x | v | v |
46
+ | SDK Version | Rails 5.x | Rails 6.x | Rails 7.x |
47
+ |-------------|-----------|-----------|-----------|
48
+ | 1.x | | | ✔ |
49
+ | 2.x | ✘ | ✔ | ✔ |
48
50
 
49
51
  ## Installation
50
52
 
@@ -64,7 +66,7 @@ require 'cloudinary'
64
66
  - [See full documentation](https://cloudinary.com/documentation/rails_image_manipulation).
65
67
 
66
68
  ```ruby
67
- cl_image_tag("sample.jpg", :width => 100, :height => 150, :crop => :fill)
69
+ cl_image_tag("sample.jpg", width: 100, height: 150, crop: "fill")
68
70
  ```
69
71
 
70
72
  ### Upload
data/cloudinary.gemspec CHANGED
@@ -7,63 +7,38 @@ Gem::Specification.new do |s|
7
7
  s.version = Cloudinary::VERSION
8
8
  s.authors = ["Nadav Soferman","Itai Lahan","Tal Lev-Ami"]
9
9
  s.email = ["nadav.soferman@cloudinary.com","itai.lahan@cloudinary.com","tal.levami@cloudinary.com"]
10
- s.homepage = "http://cloudinary.com"
10
+ s.homepage = "https://cloudinary.com"
11
11
  s.license = "MIT"
12
12
 
13
13
  s.summary = %q{Client library for easily using the Cloudinary service}
14
14
  s.description = %q{Client library for easily using the Cloudinary service}
15
15
 
16
- s.rubyforge_project = "cloudinary"
16
+ s.metadata = {
17
+ "changelog_uri" => "https://github.com/cloudinary/cloudinary_gem/blob/master/CHANGELOG.md"
18
+ }
17
19
 
18
- s.files = `git ls-files`.split("\n").select { |f| !f.start_with?("test", "spec", "features", "samples") } + Dir.glob("vendor/assets/javascripts/*/*") + Dir.glob("vendor/assets/html/*")
20
+ s.files = `git ls-files`.split("\n").select { |f| !f.start_with?("test", "spec", "features", "samples") } +
21
+ Dir.glob("vendor/assets/javascripts/*/*") + Dir.glob("vendor/assets/html/*")
19
22
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
23
  s.require_paths = ["lib"]
21
24
 
22
- s.add_dependency "aws_cf_signer"
23
-
24
- if RUBY_VERSION >= "2.0.0"
25
- s.add_dependency "rest-client", ">= 2.0.0"
26
- else
27
- s.add_dependency "rest-client"
28
- end
29
-
30
- if RUBY_VERSION >= "3.0.0"
31
- s.add_development_dependency "rexml"
32
- end
33
-
34
- s.add_development_dependency "actionpack"
35
- s.add_development_dependency "nokogiri"
36
-
37
- if RUBY_VERSION >= "2.2.0"
38
- s.add_development_dependency "rake", ">= 13.0.1"
39
- else
40
- s.add_development_dependency "rake", "<= 12.2.1"
41
- end
42
- if RUBY_VERSION >= "2.7.0"
43
- s.add_development_dependency "sqlite3"
44
- else
45
- s.add_development_dependency "sqlite3", "< 1.6.0"
46
- end
47
-
48
- s.add_development_dependency "rspec", '>=3.5'
49
- s.add_development_dependency "rspec-retry"
50
-
51
- if RUBY_VERSION >= "3.0.0"
52
- s.add_development_dependency "rails", "~> 6.0.3"
53
- elsif RUBY_VERSION >= "2.2.2"
54
- s.add_development_dependency "rails", "~> 5.2"
55
- end
56
-
57
- s.add_development_dependency "railties", "<= 4.2.7" if RUBY_VERSION <= "1.9.3"
58
- s.add_development_dependency "rspec-rails"
59
-
60
- s.add_development_dependency "rubyzip"
61
-
62
- if RUBY_VERSION <= "2.4.0"
63
- s.add_development_dependency "simplecov", "<= 0.17.1" # support testing Ruby 1.9
64
- s.add_development_dependency 'loofah', '~>2.19.1'
65
- s.add_development_dependency "rails-html-sanitizer", "<1.5.0"
66
- else
67
- s.add_development_dependency "simplecov", "> 0.18.0"
68
- end
25
+ s.required_ruby_version = '~> 3'
26
+
27
+ s.add_dependency "faraday", ">= 2.0.1", "< 3.0.0"
28
+ s.add_dependency "faraday-multipart", "~> 1.0", ">= 1.0.4"
29
+ s.add_dependency 'faraday-follow_redirects', '~> 0.3.0'
30
+ s.add_dependency "ostruct"
31
+
32
+ s.add_development_dependency "rails", ">= 6.1.7", "< 8.0.0"
33
+ s.add_development_dependency "rexml", ">= 3.2.5", "< 4.0.0"
34
+ s.add_development_dependency "actionpack", ">= 6.1.7", "< 8.0.0"
35
+ s.add_development_dependency "nokogiri", ">= 1.12.5", "< 2.0.0"
36
+ s.add_development_dependency "rake", ">= 13.0.6", "< 14.0.0"
37
+ s.add_development_dependency "sqlite3", ">= 1.4.2", "< 2.0.0"
38
+ s.add_development_dependency "rspec", ">= 3.11.2", "< 4.0.0"
39
+ s.add_development_dependency "rspec-retry", ">= 0.6.2", "< 1.0.0"
40
+ s.add_development_dependency "railties", ">= 6.0.4", "< 8.0.0"
41
+ s.add_development_dependency "rspec-rails", ">= 6.0.4", "< 7.0.0"
42
+ s.add_development_dependency "rubyzip", ">= 2.3.0", "< 3.0.0"
43
+ s.add_development_dependency "simplecov", ">= 0.21.2", "< 1.0.0"
69
44
  end
@@ -17,7 +17,13 @@ module CloudinaryHelper
17
17
  alias cloudinary_url_internal_original cloudinary_url_internal
18
18
 
19
19
  def cloudinary_url_internal(source, options = {})
20
- source = ActiveStorage::Blob.service.public_id(source) if defined? ActiveStorage::Blob.service.public_id
20
+ service_instance, options = ActiveStorage::Service::CloudinaryService.fetch_service_instance_and_config(source, options)
21
+ service_instance ||= ActiveStorage::Blob.service
22
+
23
+ if defined?(service_instance.public_id) && options.fetch(:type, "").to_s != "fetch"
24
+ source = service_instance.public_id(source)
25
+ end
26
+
21
27
  cloudinary_url_internal_original(source, options)
22
28
  end
23
29
  end
@@ -39,10 +45,12 @@ module ActiveStorage
39
45
  begin
40
46
  extra_headers = checksum.nil? ? {} : {Headers::CONTENT_MD5 => checksum}
41
47
  options = @options.merge(options)
48
+ resource_type = resource_type(io, key)
49
+ options[:format] = ext_for_file(key) if resource_type == "raw"
42
50
  Cloudinary::Uploader.upload_large(
43
51
  io,
44
52
  public_id: public_id_internal(key),
45
- resource_type: resource_type(io, key),
53
+ resource_type: resource_type,
46
54
  context: {active_storage_key: key, checksum: checksum},
47
55
  extra_headers: extra_headers,
48
56
  **options
@@ -54,9 +62,10 @@ module ActiveStorage
54
62
  end
55
63
 
56
64
  def url(key, filename: nil, content_type: '', **options)
65
+ key = find_blob_or_use_key(key)
57
66
  instrument :url, key: key do |payload|
58
67
  url = Cloudinary::Utils.cloudinary_url(
59
- full_public_id_internal(key),
68
+ full_public_id_internal(key, options),
60
69
  resource_type: resource_type(nil, key, content_type),
61
70
  format: ext_for_file(key, filename, content_type),
62
71
  **@options.merge(options.symbolize_keys)
@@ -81,7 +90,9 @@ module ActiveStorage
81
90
  # through direct upload (client side js), filename is missing, and that leads to inconsistent/broken URLs.
82
91
  # To avoid that, we explicitly pass file format in options.
83
92
  options[:format] = ext_for_file(key) if options[:resource_type] == "raw"
93
+ context = options.delete(:context)
84
94
  options[:context] = {active_storage_key: key}
95
+ options[:context].reverse_merge!(context) if context.respond_to?(:merge)
85
96
  options.delete(:file)
86
97
  payload[:url] = api_uri("upload", options)
87
98
  end
@@ -95,6 +106,7 @@ module ActiveStorage
95
106
  end
96
107
 
97
108
  def delete(key)
109
+ key = find_blob_or_use_key(key)
98
110
  instrument :delete, key: key do
99
111
  options = {
100
112
  resource_type: resource_type(nil, key),
@@ -111,6 +123,7 @@ module ActiveStorage
111
123
  end
112
124
 
113
125
  def exist?(key)
126
+ key = find_blob_or_use_key(key)
114
127
  instrument :exist, key: key do |payload|
115
128
  begin
116
129
  options = {
@@ -147,8 +160,7 @@ module ActiveStorage
147
160
 
148
161
  # Return the partial content in the byte +range+ of the file at the +key+.
149
162
  def download_chunk(key, range)
150
- url = Cloudinary::Utils.unsigned_download_url(public_id(key), resource_type: resource_type(nil, key))
151
- uri = URI(url)
163
+ uri = URI(url(key))
152
164
  instrument :download, key: key do
153
165
  req = Net::HTTP::Get.new(uri)
154
166
  range_end = case
@@ -184,6 +196,33 @@ module ActiveStorage
184
196
  full_public_id_internal(public_id)
185
197
  end
186
198
 
199
+ def self.fetch_service_instance_and_config(source, options)
200
+ return [nil, options] unless defined?(ActiveStorage::BlobKey) && source.is_a?(ActiveStorage::BlobKey) &&
201
+ source.respond_to?(:attributes) && source.attributes.key?(:service_name)
202
+
203
+ service_name = source.attributes[:service_name]
204
+
205
+ begin
206
+ service_instance = ActiveStorage::Blob.services.fetch(service_name.to_sym)
207
+
208
+ unless service_instance.instance_of?(ActiveStorage::Service::CloudinaryService)
209
+ Rails.logger.error "Expected service instance #{service_instance.class.name} to be of type ActiveStorage::Service::CloudinaryService."
210
+ return [nil, options]
211
+ end
212
+
213
+ service_config = Rails.application.config.active_storage.service_configurations.fetch(service_name)
214
+ options = service_config.merge(options)
215
+ rescue NameError => e
216
+ Rails.logger.error "Failed to retrieve the service instance for #{service_name}: #{e.message}"
217
+ return [nil, options]
218
+ rescue => e
219
+ Rails.logger.error "An unexpected error occurred: #{e.message}"
220
+ return [nil, options]
221
+ end
222
+
223
+ [service_instance, options]
224
+ end
225
+
187
226
  private
188
227
 
189
228
  def api_uri(action, options)
@@ -227,10 +266,12 @@ module ActiveStorage
227
266
  end
228
267
 
229
268
  # Returns the full public id including folder.
230
- def full_public_id_internal(key)
269
+ def full_public_id_internal(key, options = {})
231
270
  public_id = public_id_internal(key)
232
271
 
233
- return public_id unless @options[:folder]
272
+ options = @options.merge(options)
273
+
274
+ return public_id if !options[:folder] || options.fetch(:type, "").to_s == "fetch"
234
275
 
235
276
  File.join(@options.fetch(:folder), public_id)
236
277
  end
@@ -247,7 +288,7 @@ module ActiveStorage
247
288
  case type
248
289
  when 'video', 'audio'
249
290
  'video'
250
- when 'text'
291
+ when 'text', 'message'
251
292
  'raw'
252
293
  when 'application'
253
294
  case subtype
@@ -270,5 +311,19 @@ module ActiveStorage
270
311
  end
271
312
  content_type_to_resource_type(content_type)
272
313
  end
314
+
315
+ def find_blob_or_use_key(key)
316
+ if key.is_a?(ActiveStorage::BlobKey)
317
+ key
318
+ else
319
+ begin
320
+ blob = ActiveStorage::Blob.find_by(key: key)
321
+ blob ? ActiveStorage::BlobKey.new(blob.attributes.as_json) : key
322
+ rescue ActiveRecord::StatementInvalid => e
323
+ # Return the original key if an error occurs
324
+ key
325
+ end
326
+ end
327
+ end
273
328
  end
274
329
  end
@@ -13,10 +13,10 @@ class Cloudinary::AccountApi
13
13
  # @param [Object] options additional options
14
14
  def self.create_sub_account(name, cloud_name = nil, custom_attributes = {}, enabled = nil, base_account = nil, options = {})
15
15
  params = {
16
- name: name,
17
- cloud_name: cloud_name,
18
- custom_attributes: custom_attributes,
19
- enabled: enabled,
16
+ name: name,
17
+ cloud_name: cloud_name,
18
+ custom_attributes: custom_attributes,
19
+ enabled: enabled,
20
20
  base_sub_account_id: base_account
21
21
  }
22
22
 
@@ -35,10 +35,10 @@ class Cloudinary::AccountApi
35
35
  # @param [Object] options additional options
36
36
  def self.update_sub_account(sub_account_id, name = nil, cloud_name = nil, custom_attributes = nil, enabled = nil, options = {})
37
37
  params = {
38
- name: name,
39
- cloud_name: cloud_name,
38
+ name: name,
39
+ cloud_name: cloud_name,
40
40
  custom_attributes: custom_attributes,
41
- enabled: enabled
41
+ enabled: enabled
42
42
  }
43
43
 
44
44
  call_account_api(:put, ['sub_accounts', sub_account_id], params, options.merge(content_type: :json))
@@ -53,8 +53,8 @@ class Cloudinary::AccountApi
53
53
  def self.sub_accounts(enabled = nil, ids = [], prefix = nil, options = {})
54
54
  params = {
55
55
  enabled: enabled,
56
- ids: ids,
57
- prefix: prefix
56
+ ids: ids,
57
+ prefix: prefix
58
58
  }
59
59
 
60
60
  call_account_api(:get, 'sub_accounts', params, options.merge(content_type: :json))
@@ -84,9 +84,9 @@ class Cloudinary::AccountApi
84
84
  # @param [Object] options additional options
85
85
  def self.create_user(name, email, role, sub_account_ids = [], options = {})
86
86
  params = {
87
- name: name,
88
- email: email,
89
- role: role,
87
+ name: name,
88
+ email: email,
89
+ role: role,
90
90
  sub_account_ids: sub_account_ids
91
91
  }
92
92
 
@@ -111,9 +111,9 @@ class Cloudinary::AccountApi
111
111
  # @param [Object] options additional options
112
112
  def self.update_user(user_id, name = nil, email = nil, role = nil, sub_account_ids = nil, options = {})
113
113
  params = {
114
- name: name,
115
- email: email,
116
- role: role,
114
+ name: name,
115
+ email: email,
116
+ role: role,
117
117
  sub_account_ids: sub_account_ids
118
118
  }
119
119
 
@@ -127,18 +127,30 @@ class Cloudinary::AccountApi
127
127
  call_account_api(:get, ['users', user_id], {}, options.merge(content_type: :json))
128
128
  end
129
129
 
130
- # Lists users in the account.
131
- # @param [Boolean] pending Limit results to pending users (true), users that are not pending (false), or all users (nil, the default)
132
- # @param [Array<String>] user_ids A list of up to 100 user IDs. When provided, other parameters are ignored.
133
- # @param [String] prefix Returns users where the name or email address begins with the specified case-insensitive string.
134
- # @param [String] sub_account_id Only returns users who have access to the specified account.
135
- # @param [Object] options additional options
130
+ # Get a list of the users according to filters.
131
+ #
132
+ # @param [Boolean] pending Optional. Limit results to pending users (true), users that are not pending (false), or all users (null)
133
+ # @param [Array<String>] user_ids Optional. List of user IDs. Up to 100
134
+ # @param [String] prefix Optional. Search by prefix of the user's name or email. Case-insensitive
135
+ # @param [String] sub_account_id Optional. Return only users who have access to the given sub-account
136
+ # @param [Object] options Generic advanced options map, see online documentation.
137
+ # @option options [Boolean] :last_login Optional. Return only users that last logged in in the specified range of dates (true),
138
+ # users that didn't last logged in in that range (false), or all users (null).
139
+ # @option options [Date] :from Optional. Last login start date.
140
+ # @option options [Date] :to Optional. Last login end date.
141
+ #
142
+ # @return [Cloudinary::Api::Response] the users' details.
143
+ #
144
+ # @raise [Cloudinary::Api::Error] If the request fails.
136
145
  def self.users(pending = nil, user_ids = [], prefix = nil, sub_account_id = nil, options = {})
137
146
  params = {
138
- ids: user_ids,
139
- prefix: prefix,
147
+ ids: user_ids,
148
+ prefix: prefix,
140
149
  sub_account_id: sub_account_id,
141
- pending: pending
150
+ pending: pending,
151
+ last_login: options[:last_login].to_s,
152
+ from: Cloudinary::Utils.to_usage_api_date_format(options[:from]),
153
+ to: Cloudinary::Utils.to_usage_api_date_format(options[:to])
142
154
  }
143
155
 
144
156
  call_account_api(:get, 'users', params, options.merge(content_type: :json))
@@ -210,16 +222,73 @@ class Cloudinary::AccountApi
210
222
  call_account_api(:get, ['user_groups', group_id, 'users'], {}, options.merge(content_type: :json))
211
223
  end
212
224
 
225
+ # Lists access keys.
226
+ #
227
+ # @param [String] sub_account_id The ID of the sub-account.
228
+ # @param [Object] options Additional options.
229
+ def self.access_keys(sub_account_id, options = {})
230
+ params = Cloudinary::Api.only(options, :page_size, :page, :sort_by, :sort_order)
231
+ call_account_api(:get, ['sub_accounts', sub_account_id, 'access_keys'], params, options)
232
+ end
233
+
234
+ # Generates access key.
235
+ #
236
+ # @param [String] sub_account_id The ID of the sub-account.
237
+ # @param [String] name The display name as shown in the management console.
238
+ # @param [Boolean] enabled Whether to create the access key as enabled (default is enabled).
239
+ # @param [Object] options Additional options.
240
+ def self.generate_access_key(sub_account_id, name = nil, enabled = nil, options = {})
241
+ params = {
242
+ name: name,
243
+ enabled: enabled,
244
+ }
245
+ call_account_api(:post, ['sub_accounts', sub_account_id, 'access_keys'], params, options.merge(content_type: :json))
246
+ end
247
+
248
+ # Updates access key.
249
+ #
250
+ # @param [String] sub_account_id The ID of the sub-account.
251
+ # @param [String] api_key The API key.
252
+ # @param [String] name The display name as shown in the management console.
253
+ # @param [Boolean] enabled Enable or disable the access key.
254
+ # @param [Object] options Additional options.
255
+ def self.update_access_key(sub_account_id, api_key, name = nil, enabled = nil, options = {})
256
+ params = {
257
+ name: name,
258
+ enabled: enabled,
259
+ }
260
+ call_account_api(:put, ['sub_accounts', sub_account_id, 'access_keys', api_key], params, options.merge(content_type: :json))
261
+ end
262
+
263
+ # Deletes access key.
264
+ #
265
+ # @param [String] sub_account_id The ID of the sub-account.
266
+ # @param [String, nil] api_key The API key.
267
+ # @param [String, nil] name The display name as shown in the management console.
268
+ # @param [Object] options Additional options.
269
+ def self.delete_access_key(sub_account_id, api_key = nil, name = nil, options = {})
270
+ uri = ['sub_accounts', sub_account_id, 'access_keys']
271
+ unless api_key.blank?
272
+ uri.append(api_key)
273
+ end
274
+
275
+ params = {
276
+ name: name,
277
+ }
278
+ call_account_api(:delete, uri, params, options.merge(content_type: :json))
279
+ end
280
+
213
281
  def self.call_account_api(method, uri, params, options)
214
282
  account_id = options[:account_id] || Cloudinary.account_config.account_id || raise('Must supply account_id')
215
283
  api_key = options[:provisioning_api_key] || Cloudinary.account_config.provisioning_api_key || raise('Must supply provisioning api_key')
216
284
  api_secret = options[:provisioning_api_secret] || Cloudinary.account_config.provisioning_api_secret || raise('Must supply provisioning api_secret')
285
+ api_version = options[:api_version] || Cloudinary.config.api_version || 'v1_1'
217
286
 
218
287
  params.reject! { |_, v| v.nil? }
219
288
  auth = { :key => api_key, :secret => api_secret }
220
289
 
221
290
  call_cloudinary_api(method, uri, auth, params, options) do |cloudinary, inner_uri|
222
- [cloudinary, 'v1_1', 'provisioning', 'accounts', account_id, inner_uri]
291
+ [cloudinary, api_version, 'provisioning', 'accounts', account_id, inner_uri]
223
292
  end
224
293
  end
225
294