cloudinary 1.17.0 → 1.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +61 -0
- data/cloudinary.gemspec +8 -3
- data/lib/active_storage/service/cloudinary_service.rb +32 -6
- data/lib/cloudinary.rb +45 -64
- data/lib/cloudinary/account_api.rb +231 -0
- data/lib/cloudinary/account_config.rb +30 -0
- data/lib/cloudinary/api.rb +182 -66
- data/lib/cloudinary/auth_token.rb +4 -0
- data/lib/cloudinary/base_api.rb +79 -0
- data/lib/cloudinary/base_config.rb +70 -0
- data/lib/cloudinary/config.rb +43 -0
- data/lib/cloudinary/helper.rb +1 -1
- data/lib/cloudinary/uploader.rb +33 -6
- data/lib/cloudinary/utils.rb +109 -27
- data/lib/cloudinary/version.rb +1 -1
- data/lib/cloudinary/video_helper.rb +96 -22
- data/vendor/assets/javascripts/cloudinary/jquery.cloudinary.js +6 -2
- metadata +17 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b641514503d45c3a6c4e8ba5ed87f0f5b8e521260eda789212543be5ccf77a1
|
4
|
+
data.tar.gz: 0f65e99aa08e446f01d783af5284a1265aaa4f28a1e95c284addd30beb36ec8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 191f627013b5f97fca44e748fd1c4631f9af58a69680b02fdc6b4604e2ddf31216542fcb88e2d1daa825c0ff22a138f2c7d0b41d4895a69cc1b7eaa42a1ab16a
|
7
|
+
data.tar.gz: 8a5abe09f562e188e1e6d43d05f462939c62c4070ac50e93c3acaf876998e651aa2fc50775a10c5fb324d388fac9d599c5fe0e60480cdbbebeb7eedf699057e8
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,64 @@
|
|
1
|
+
1.20.0 / 2021-03-26
|
2
|
+
==================
|
3
|
+
|
4
|
+
New functionality and features
|
5
|
+
------------------------------
|
6
|
+
|
7
|
+
* Add support for `download_backedup_asset` helper method
|
8
|
+
* Add support for `filename_override` upload parameter
|
9
|
+
* Add support for `SHA-256` algorithm in auth signatures
|
10
|
+
|
11
|
+
Other Changes
|
12
|
+
-------------
|
13
|
+
|
14
|
+
* Fix `type` parameter support in ActiveStorage service
|
15
|
+
* Fix expression normalization in advanced cases
|
16
|
+
* Add test for context metadata as user variables
|
17
|
+
* Improve validation of auth token generation
|
18
|
+
|
19
|
+
|
20
|
+
1.19.0 / 2021-03-05
|
21
|
+
==================
|
22
|
+
|
23
|
+
New functionality and features
|
24
|
+
------------------------------
|
25
|
+
|
26
|
+
* Add Account Provisioning API
|
27
|
+
* Add support for `api_proxy` parameter
|
28
|
+
* Add support for `date` parameter in `usage` Admin API
|
29
|
+
|
30
|
+
Other Changes
|
31
|
+
-------------
|
32
|
+
|
33
|
+
* Fix direct upload of raw files
|
34
|
+
* Improve unit testing of add-ons
|
35
|
+
* Change test for `eval` upload parameter
|
36
|
+
* Bump vulnerable version of rubyzip
|
37
|
+
* Fix `cloudinary.gemspec` glob issue
|
38
|
+
|
39
|
+
1.18.1 / 2020-09-30
|
40
|
+
===================
|
41
|
+
|
42
|
+
* Update embedded `jquery.cloudinary.js` to fix ES5 compatibility issue
|
43
|
+
|
44
|
+
1.18.0 / 2020-09-27
|
45
|
+
===================
|
46
|
+
|
47
|
+
New functionality and features
|
48
|
+
------------------------------
|
49
|
+
* Add `download_folder` helper
|
50
|
+
* Add support for `sources` in `video` tag
|
51
|
+
* Add structured metadata to Admin and Upload API
|
52
|
+
|
53
|
+
Other Changes
|
54
|
+
-------------
|
55
|
+
* Fix download of a raw file in ActiveStorage
|
56
|
+
* Update embedded `jquery.cloudinary.js` to fix ES5 compatibility issue
|
57
|
+
|
58
|
+
1.17.1 / 2020-08-25
|
59
|
+
===================
|
60
|
+
|
61
|
+
* Fix options handling issue in SassC
|
1
62
|
|
2
63
|
1.17.0 / 2020-08-21
|
3
64
|
===================
|
data/cloudinary.gemspec
CHANGED
@@ -15,12 +15,17 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.rubyforge_project = "cloudinary"
|
17
17
|
|
18
|
-
s.files =
|
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/*")
|
19
19
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
22
|
s.add_dependency "aws_cf_signer"
|
23
|
-
|
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
|
24
29
|
|
25
30
|
s.add_development_dependency "actionpack"
|
26
31
|
s.add_development_dependency "nokogiri"
|
@@ -39,7 +44,7 @@ Gem::Specification.new do |s|
|
|
39
44
|
s.add_development_dependency "railties", "<= 4.2.7" if RUBY_VERSION <= "1.9.3"
|
40
45
|
s.add_development_dependency "rspec-rails"
|
41
46
|
|
42
|
-
s.add_development_dependency "rubyzip"
|
47
|
+
s.add_development_dependency "rubyzip"
|
43
48
|
|
44
49
|
if RUBY_VERSION <= "2.4.0"
|
45
50
|
s.add_development_dependency "simplecov", "<= 0.17.1" # support testing Ruby 1.9
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'active_storage/blob_key'
|
2
2
|
require 'cloudinary/helper'
|
3
|
+
require 'net/http'
|
3
4
|
|
4
5
|
unless ActiveStorage::Blob.method_defined? :original_key
|
5
6
|
class ActiveStorage::Blob
|
@@ -57,7 +58,7 @@ module ActiveStorage
|
|
57
58
|
url = Cloudinary::Utils.cloudinary_url(
|
58
59
|
public_id(key),
|
59
60
|
resource_type: resource_type(nil, key),
|
60
|
-
format: ext_for_file(filename, content_type),
|
61
|
+
format: ext_for_file(key, filename, content_type),
|
61
62
|
**@options.merge(options.symbolize_keys)
|
62
63
|
)
|
63
64
|
|
@@ -71,6 +72,14 @@ module ActiveStorage
|
|
71
72
|
instrument :url, key: key do |payload|
|
72
73
|
options = {:resource_type => resource_type(nil, key)}.merge(@options.merge(options.symbolize_keys))
|
73
74
|
options[:public_id] = public_id_internal(key)
|
75
|
+
# Provide file format for raw files, since js client does not include original file name.
|
76
|
+
#
|
77
|
+
# When the file is uploaded from the server, the request includes original filename. That allows Cloudinary
|
78
|
+
# to identify file extension and append it to the public id of the file (raw files include file extension
|
79
|
+
# in their public id, opposed to transformable assets (images/video) that use only basename). When uploading
|
80
|
+
# through direct upload (client side js), filename is missing, and that leads to inconsistent/broken URLs.
|
81
|
+
# To avoid that, we explicitly pass file format in options.
|
82
|
+
options[:format] = ext_for_file(key) if options[:resource_type] == "raw"
|
74
83
|
options[:context] = {active_storage_key: key}
|
75
84
|
options.delete(:file)
|
76
85
|
payload[:url] = api_uri("upload", options)
|
@@ -86,7 +95,12 @@ module ActiveStorage
|
|
86
95
|
|
87
96
|
def delete(key)
|
88
97
|
instrument :delete, key: key do
|
89
|
-
|
98
|
+
options = {
|
99
|
+
resource_type: resource_type(nil, key),
|
100
|
+
type: @options[:type]
|
101
|
+
}.compact
|
102
|
+
|
103
|
+
Cloudinary::Uploader.destroy public_id(key), **options
|
90
104
|
end
|
91
105
|
end
|
92
106
|
|
@@ -98,7 +112,12 @@ module ActiveStorage
|
|
98
112
|
def exist?(key)
|
99
113
|
instrument :exist, key: key do |payload|
|
100
114
|
begin
|
101
|
-
|
115
|
+
options = {
|
116
|
+
resource_type: resource_type(nil, key),
|
117
|
+
type: @options[:type]
|
118
|
+
}.compact
|
119
|
+
|
120
|
+
Cloudinary::Api.resource public_id(key), **options
|
102
121
|
true
|
103
122
|
rescue Cloudinary::Api::NotFound => e
|
104
123
|
false
|
@@ -107,8 +126,7 @@ module ActiveStorage
|
|
107
126
|
end
|
108
127
|
|
109
128
|
def download(key, &block)
|
110
|
-
|
111
|
-
uri = URI(url)
|
129
|
+
uri = URI(url(key))
|
112
130
|
if block_given?
|
113
131
|
instrument :streaming_download, key: key do
|
114
132
|
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
@@ -169,12 +187,18 @@ module ActiveStorage
|
|
169
187
|
#
|
170
188
|
# It does the best effort when original filename does not include extension, but we know the mime-type.
|
171
189
|
#
|
190
|
+
# @param [ActiveStorage::BlobKey] key The blob key with attributes.
|
172
191
|
# @param [ActiveStorage::Filename] filename The original filename.
|
173
192
|
# @param [string] content_type The content type of the file.
|
174
193
|
#
|
175
194
|
# @return [string] The extension of the filename.
|
176
|
-
def ext_for_file(filename, content_type)
|
195
|
+
def ext_for_file(key, filename = nil, content_type = nil)
|
196
|
+
if filename.blank?
|
197
|
+
options = key.respond_to?(:attributes) ? key.attributes : {}
|
198
|
+
filename = ActiveStorage::Filename.new(options[:filename]) if options.has_key?(:filename)
|
199
|
+
end
|
177
200
|
ext = filename.respond_to?(:extension_without_delimiter) ? filename.extension_without_delimiter : nil
|
201
|
+
|
178
202
|
return ext unless ext.blank?
|
179
203
|
|
180
204
|
# Raw files are not convertible, no extension guessing for them
|
@@ -194,6 +218,8 @@ module ActiveStorage
|
|
194
218
|
end
|
195
219
|
|
196
220
|
def content_type_to_resource_type(content_type)
|
221
|
+
return 'image' if content_type.nil?
|
222
|
+
|
197
223
|
type, subtype = content_type.split('/')
|
198
224
|
case type
|
199
225
|
when 'video', 'audio'
|
data/lib/cloudinary.rb
CHANGED
@@ -16,7 +16,12 @@ require "cloudinary/missing"
|
|
16
16
|
module Cloudinary
|
17
17
|
autoload :Utils, 'cloudinary/utils'
|
18
18
|
autoload :Uploader, 'cloudinary/uploader'
|
19
|
+
autoload :BaseConfig, "cloudinary/base_config"
|
20
|
+
autoload :Config, "cloudinary/config"
|
21
|
+
autoload :AccountConfig, "cloudinary/account_config"
|
22
|
+
autoload :BaseApi, "cloudinary/base_api"
|
19
23
|
autoload :Api, "cloudinary/api"
|
24
|
+
autoload :AccountApi, "cloudinary/account_api"
|
20
25
|
autoload :Downloader, "cloudinary/downloader"
|
21
26
|
autoload :Blob, "cloudinary/blob"
|
22
27
|
autoload :PreloadedFile, "cloudinary/preloaded_file"
|
@@ -58,64 +63,42 @@ module Cloudinary
|
|
58
63
|
"ept" => "eps"
|
59
64
|
}
|
60
65
|
|
61
|
-
|
62
|
-
|
66
|
+
# Cloudinary config
|
67
|
+
#
|
68
|
+
# @param [Hash] new_config If +new_config+ is passed, Config will be updated with it
|
69
|
+
# @yieldparam [OpenStruct] Config can be updated in the block
|
70
|
+
#
|
71
|
+
# @return [OpenStruct]
|
63
72
|
def self.config(new_config=nil)
|
64
|
-
|
65
|
-
@@config ||= OpenStruct.new((YAML.load(ERB.new(IO.read(config_dir.join("cloudinary.yml"))).result)[config_env] rescue {}))
|
66
|
-
|
67
|
-
config_from_env if first_time
|
73
|
+
@@config ||= make_new_config(Config)
|
68
74
|
|
69
|
-
|
70
|
-
yield
|
75
|
+
@@config.update(new_config) if new_config
|
76
|
+
yield @@config if block_given?
|
71
77
|
|
72
78
|
@@config
|
73
79
|
end
|
74
80
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
set_config(
|
84
|
-
"cloud_name" => uri.host,
|
85
|
-
"api_key" => uri.user,
|
86
|
-
"api_secret" => uri.password,
|
87
|
-
"private_cdn" => !uri.path.blank?,
|
88
|
-
"secure_distribution" => uri.path[1..-1]
|
89
|
-
)
|
90
|
-
uri.query.to_s.split("&").each do
|
91
|
-
|param|
|
92
|
-
key, value = param.split("=")
|
93
|
-
if isNestedKey? key
|
94
|
-
putNestedKey key, value
|
95
|
-
else
|
96
|
-
set_config(key => Utils.smart_unescape(value))
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
81
|
+
# Cloudinary account config
|
82
|
+
#
|
83
|
+
# @param [Hash] new_config If +new_config+ is passed, Account Config will be updated with it
|
84
|
+
# @yieldparam [OpenStruct] Account config can be updated in the block
|
85
|
+
#
|
86
|
+
# @return [OpenStruct]
|
87
|
+
def self.account_config(new_config=nil)
|
88
|
+
@@account_config ||= make_new_config(AccountConfig)
|
100
89
|
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
chain.each do |innerKey|
|
106
|
-
inner = outer[innerKey]
|
107
|
-
if inner.nil?
|
108
|
-
inner = OpenStruct.new
|
109
|
-
outer[innerKey] = inner
|
110
|
-
end
|
111
|
-
outer = inner
|
112
|
-
end
|
113
|
-
outer[lastKey] = value
|
90
|
+
@@account_config.update(new_config) if new_config
|
91
|
+
yield @@account_config if block_given?
|
92
|
+
|
93
|
+
@@account_config
|
114
94
|
end
|
115
95
|
|
96
|
+
def self.config_from_url(url)
|
97
|
+
config.load_from_url(url)
|
98
|
+
end
|
116
99
|
|
117
|
-
def self.
|
118
|
-
|
100
|
+
def self.config_from_account_url(url)
|
101
|
+
account_config.load_from_url(url)
|
119
102
|
end
|
120
103
|
|
121
104
|
def self.app_root
|
@@ -129,22 +112,6 @@ module Cloudinary
|
|
129
112
|
|
130
113
|
private
|
131
114
|
|
132
|
-
def self.config_from_env
|
133
|
-
# Heroku support
|
134
|
-
if ENV["CLOUDINARY_CLOUD_NAME"]
|
135
|
-
config_keys = ENV.keys.select! { |key| key.start_with? "CLOUDINARY_" }
|
136
|
-
config_keys -= ["CLOUDINARY_URL"] # ignore it when explicit options are passed
|
137
|
-
config_keys.each do |full_key|
|
138
|
-
conf_key = full_key["CLOUDINARY_".length..-1].downcase # convert "CLOUDINARY_CONFIG_NAME" to "config_name"
|
139
|
-
conf_val = ENV[full_key]
|
140
|
-
conf_val = conf_val == 'true' if %w[true false].include?(conf_val) # cast relevant boolean values
|
141
|
-
set_config(conf_key => conf_val)
|
142
|
-
end
|
143
|
-
elsif ENV["CLOUDINARY_URL"]
|
144
|
-
config_from_url(ENV["CLOUDINARY_URL"])
|
145
|
-
end
|
146
|
-
end
|
147
|
-
|
148
115
|
def self.config_env
|
149
116
|
return ENV["CLOUDINARY_ENV"] if ENV["CLOUDINARY_ENV"]
|
150
117
|
return Rails.env if defined? Rails::env
|
@@ -159,6 +126,20 @@ module Cloudinary
|
|
159
126
|
def self.set_config(new_config)
|
160
127
|
new_config.each{|k,v| @@config.send(:"#{k}=", v) if !v.nil?}
|
161
128
|
end
|
129
|
+
|
130
|
+
# Builds config from yaml file, extends it with specific module and loads configuration from environment variable
|
131
|
+
#
|
132
|
+
# @param [Module] config_module Config is extended with this module after being built
|
133
|
+
#
|
134
|
+
# @return [OpenStruct]
|
135
|
+
def self.make_new_config(config_module)
|
136
|
+
OpenStruct.new((YAML.load(ERB.new(IO.read(config_dir.join("cloudinary.yml"))).result)[config_env] rescue {})).tap do |config|
|
137
|
+
config.extend(config_module)
|
138
|
+
config.load_config_from_env
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
private_class_method :make_new_config
|
162
143
|
end
|
163
144
|
# Prevent require loop if included after Rails is already initialized.
|
164
145
|
require "cloudinary/helper" if defined?(::ActionView::Base)
|
@@ -0,0 +1,231 @@
|
|
1
|
+
class Cloudinary::AccountApi
|
2
|
+
extend Cloudinary::BaseApi
|
3
|
+
|
4
|
+
# Creates a new sub-account. Any users that have access to all sub-accounts will also automatically have access to the
|
5
|
+
# new sub-account.
|
6
|
+
# @param [String] name The display name as shown in the management console
|
7
|
+
# @param [String] cloud_name A case-insensitive cloud name comprised of alphanumeric and underscore characters.
|
8
|
+
# Generates an error if the specified cloud name is not unique across all Cloudinary accounts.
|
9
|
+
# Note: Once created, the name can only be changed for accounts with fewer than 1000 assets.
|
10
|
+
# @param [Object] custom_attributes Any custom attributes you want to associate with the sub-account
|
11
|
+
# @param [Boolean] enabled Whether to create the account as enabled (default is enabled)
|
12
|
+
# @param [String] base_account ID of sub-account from which to copy settings
|
13
|
+
# @param [Object] options additional options
|
14
|
+
def self.create_sub_account(name, cloud_name = nil, custom_attributes = {}, enabled = nil, base_account = nil, options = {})
|
15
|
+
params = {
|
16
|
+
name: name,
|
17
|
+
cloud_name: cloud_name,
|
18
|
+
custom_attributes: custom_attributes,
|
19
|
+
enabled: enabled,
|
20
|
+
base_sub_account_id: base_account
|
21
|
+
}
|
22
|
+
|
23
|
+
call_account_api(:post, 'sub_accounts', params, options.merge(content_type: :json))
|
24
|
+
end
|
25
|
+
|
26
|
+
# Updates the specified details of the sub-account.
|
27
|
+
# @param [String] sub_account_id The ID of the sub-account.
|
28
|
+
# @param [String] name The display name as shown in the management console
|
29
|
+
# @param [String] cloud_name A case-insensitive cloud name comprised of alphanumeric and underscore characters.
|
30
|
+
# Generates an error if the specified cloud name is not unique across all Cloudinary accounts.
|
31
|
+
# Note: Once created, the name can only be changed for accounts with fewer than 1000 assets.
|
32
|
+
# @param [Object] custom_attributes Any custom attributes you want to associate with the sub-account, as a map/hash
|
33
|
+
# of key/value pairs.
|
34
|
+
# @param [Boolean] enabled Whether the sub-account is enabled.
|
35
|
+
# @param [Object] options additional options
|
36
|
+
def self.update_sub_account(sub_account_id, name = nil, cloud_name = nil, custom_attributes = nil, enabled = nil, options = {})
|
37
|
+
params = {
|
38
|
+
name: name,
|
39
|
+
cloud_name: cloud_name,
|
40
|
+
custom_attributes: custom_attributes,
|
41
|
+
enabled: enabled
|
42
|
+
}
|
43
|
+
|
44
|
+
call_account_api(:put, ['sub_accounts', sub_account_id], params, options.merge(content_type: :json))
|
45
|
+
end
|
46
|
+
|
47
|
+
# Lists sub-accounts.
|
48
|
+
# @param [Boolean] enabled Whether to only return enabled sub-accounts (true) or disabled accounts (false).
|
49
|
+
# Default: all accounts are returned (both enabled and disabled).
|
50
|
+
# @param [Array<String>] ids A list of up to 100 sub-account IDs. When provided, other parameters are ignored.
|
51
|
+
# @param [String] prefix Returns accounts where the name begins with the specified case-insensitive string.
|
52
|
+
# @param [Object] options additional options
|
53
|
+
def self.sub_accounts(enabled = nil, ids = [], prefix = nil, options = {})
|
54
|
+
params = {
|
55
|
+
enabled: enabled,
|
56
|
+
ids: ids,
|
57
|
+
prefix: prefix
|
58
|
+
}
|
59
|
+
|
60
|
+
call_account_api(:get, 'sub_accounts', params, options.merge(content_type: :json))
|
61
|
+
end
|
62
|
+
|
63
|
+
# Retrieves the details of the specified sub-account.
|
64
|
+
# @param [String] sub_account_id The ID of the sub-account.
|
65
|
+
# @param [Object] options additional options
|
66
|
+
def self.sub_account(sub_account_id, options = {})
|
67
|
+
call_account_api(:get, ['sub_accounts', sub_account_id], {}, options.merge(content_type: :json))
|
68
|
+
end
|
69
|
+
|
70
|
+
# Deletes the specified sub-account. Supported only for accounts with fewer than 1000 assets.
|
71
|
+
# @param [String] sub_account_id The ID of the sub-account.
|
72
|
+
# @param [Object] options additional options
|
73
|
+
def self.delete_sub_account(sub_account_id, options = {})
|
74
|
+
call_account_api(:delete, ['sub_accounts', sub_account_id], {}, options)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Creates a new user in the account.
|
78
|
+
# @param [String] name The name of the user.
|
79
|
+
# @param [String] email A unique email address, which serves as the login name and notification address.
|
80
|
+
# @param [String] role The role to assign. Possible values: master_admin, admin, billing, technical_admin, reports,
|
81
|
+
# media_library_admin, media_library_user
|
82
|
+
# @param [Array<String>] sub_account_ids The list of sub-account IDs that this user can access.
|
83
|
+
# Note: This parameter is ignored if the role is specified as master_admin.
|
84
|
+
# @param [Object] options additional options
|
85
|
+
def self.create_user(name, email, role, sub_account_ids = [], options = {})
|
86
|
+
params = {
|
87
|
+
name: name,
|
88
|
+
email: email,
|
89
|
+
role: role,
|
90
|
+
sub_account_ids: sub_account_ids
|
91
|
+
}
|
92
|
+
|
93
|
+
call_account_api(:post, 'users', params, options.merge(content_type: :json))
|
94
|
+
end
|
95
|
+
|
96
|
+
# Deletes an existing user.
|
97
|
+
# @param [String] user_id The ID of the user to delete.
|
98
|
+
# @param [Object] options additional options
|
99
|
+
def self.delete_user(user_id, options = {})
|
100
|
+
call_account_api(:delete, ['users', user_id], {}, options)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Updates the details of the specified user.
|
104
|
+
# @param [String] user_id The ID of the user to update.
|
105
|
+
# @param [String] name The name of the user.
|
106
|
+
# @param [String] email A unique email address, which serves as the login name and notification address.
|
107
|
+
# @param [String] role The role to assign. Possible values: master_admin, admin, billing, technical_admin, reports,
|
108
|
+
# media_library_admin, media_library_user
|
109
|
+
# @param [Array<String>] sub_account_ids The list of sub-account IDs that this user can access.
|
110
|
+
# Note: This parameter is ignored if the role is specified as master_admin.
|
111
|
+
# @param [Object] options additional options
|
112
|
+
def self.update_user(user_id, name = nil, email = nil, role = nil, sub_account_ids = nil, options = {})
|
113
|
+
params = {
|
114
|
+
name: name,
|
115
|
+
email: email,
|
116
|
+
role: role,
|
117
|
+
sub_account_ids: sub_account_ids
|
118
|
+
}
|
119
|
+
|
120
|
+
call_account_api(:put, ['users', user_id], params, options.merge(content_type: :json))
|
121
|
+
end
|
122
|
+
|
123
|
+
# Returns the user with the specified ID.
|
124
|
+
# @param [String] user_id The ID of the user.
|
125
|
+
# @param [Object] options additional options
|
126
|
+
def self.user(user_id, options = {})
|
127
|
+
call_account_api(:get, ['users', user_id], {}, options.merge(content_type: :json))
|
128
|
+
end
|
129
|
+
|
130
|
+
# Lists users in the account.
|
131
|
+
# @param [Boolean] pending Whether to only return pending users. Default: all users
|
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
|
136
|
+
def self.users(pending = nil, user_ids = [], prefix = nil, sub_account_id = nil, options = {})
|
137
|
+
params = if user_ids && user_ids.count > 0
|
138
|
+
{
|
139
|
+
ids: user_ids
|
140
|
+
}
|
141
|
+
else
|
142
|
+
{
|
143
|
+
prefix: prefix,
|
144
|
+
sub_account_id: sub_account_id,
|
145
|
+
pending: pending
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
call_account_api(:get, 'users', params, options.merge(content_type: :json))
|
150
|
+
end
|
151
|
+
|
152
|
+
# Creates a new user group.
|
153
|
+
# @param [String] name The name for the user group.
|
154
|
+
# @param [Object] options additional options
|
155
|
+
def self.create_user_group(name, options = {})
|
156
|
+
params = {
|
157
|
+
name: name
|
158
|
+
}
|
159
|
+
|
160
|
+
call_account_api(:post, 'user_groups', params, options.merge(content_type: :json))
|
161
|
+
end
|
162
|
+
|
163
|
+
# Updates the specified user group.
|
164
|
+
# @param [String] group_id The ID of the user group to update.
|
165
|
+
# @param [String] name The name for the user group.
|
166
|
+
# @param [Object] options additional options
|
167
|
+
def self.update_user_group(group_id, name, options = {})
|
168
|
+
params = {
|
169
|
+
name: name
|
170
|
+
}
|
171
|
+
|
172
|
+
call_account_api(:put, ['user_groups', group_id], params, options.merge(content_type: :json))
|
173
|
+
end
|
174
|
+
|
175
|
+
# Adds a user to a group with the specified ID.
|
176
|
+
# @param [String] group_id The ID of the user group.
|
177
|
+
# @param [String] user_id The ID of the user.
|
178
|
+
# @param [Object] options additional options
|
179
|
+
def self.add_user_to_group(group_id, user_id, options = {})
|
180
|
+
call_account_api(:post, ['user_groups', group_id, 'users', user_id], {}, options.merge(content_type: :json))
|
181
|
+
end
|
182
|
+
|
183
|
+
# Removes a user from a group with the specified ID.
|
184
|
+
# @param [String] group_id The ID of the user group.
|
185
|
+
# @param [String] user_id The ID of the user.
|
186
|
+
# @param [Object] options additional options
|
187
|
+
def self.remove_user_from_group(group_id, user_id, options = {})
|
188
|
+
call_account_api(:delete, ['user_groups', group_id, 'users', user_id], {}, options.merge(content_type: :json))
|
189
|
+
end
|
190
|
+
|
191
|
+
# Deletes the user group with the specified ID.
|
192
|
+
# @param [String] group_id The ID of the user group to delete.
|
193
|
+
# @param [Object] options additional options
|
194
|
+
def self.delete_user_group(group_id, options = {})
|
195
|
+
call_account_api(:delete, ['user_groups', group_id], {}, options)
|
196
|
+
end
|
197
|
+
|
198
|
+
# Lists user groups in the account.
|
199
|
+
# @param [Object] options additional options
|
200
|
+
def self.user_groups(options = {})
|
201
|
+
call_account_api(:get, 'user_groups', {}, options.merge(content_type: :json))
|
202
|
+
end
|
203
|
+
|
204
|
+
# Retrieves the details of the specified user group.
|
205
|
+
# @param [String] group_id The ID of the user group to retrieve.
|
206
|
+
# @param [Object] options additional options
|
207
|
+
def self.user_group(group_id, options = {})
|
208
|
+
call_account_api(:get, ['user_groups', group_id], {}, options.merge(content_type: :json))
|
209
|
+
end
|
210
|
+
|
211
|
+
# Lists users in the specified user group.
|
212
|
+
# @param [String] group_id The ID of the user group.
|
213
|
+
# @param [Object] options additional options
|
214
|
+
def self.user_group_users(group_id, options = {})
|
215
|
+
call_account_api(:get, ['user_groups', group_id, 'users'], {}, options.merge(content_type: :json))
|
216
|
+
end
|
217
|
+
|
218
|
+
def self.call_account_api(method, uri, params, options)
|
219
|
+
account_id = options[:account_id] || Cloudinary.account_config.account_id || raise('Must supply account_id')
|
220
|
+
api_key = options[:provisioning_api_key] || Cloudinary.account_config.provisioning_api_key || raise('Must supply provisioning api_key')
|
221
|
+
api_secret = options[:provisioning_api_secret] || Cloudinary.account_config.provisioning_api_secret || raise('Must supply provisioning api_secret')
|
222
|
+
|
223
|
+
params.reject! { |_, v| v.nil? }
|
224
|
+
|
225
|
+
call_cloudinary_api(method, uri, api_key, api_secret, params, options) do |cloudinary, inner_uri|
|
226
|
+
[cloudinary, 'v1_1', 'provisioning', 'accounts', account_id, inner_uri]
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
private_class_method :call_account_api
|
231
|
+
end
|