cloudinary 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 675877dafeb654d86f21a603814835b907b0b560
4
- data.tar.gz: 0afd3a11251a44cbc84293ded02975cd1473b01b
3
+ metadata.gz: 7a96fb520a45441c0cc40d980dc03836c6b7ffc4
4
+ data.tar.gz: 29924a2fa48916d03132b9bf6a080749471b558d
5
5
  SHA512:
6
- metadata.gz: d33e51978a4d8e65e5c7bb1463d8fe1c17ffbf8e4c099fb5b9cf4160877e69c6bd60698507e6718d1457ee713b4168d5782058a9399c3f5b67522e3c0bb16e02
7
- data.tar.gz: 1833b23e9d849a38ddc2d88844d89b33bb903c0e4acfcc6ede358995338df7fbb8922887fd924e96ae6be9f46964db69f3bdfe9f2b45036444d511647eedef0f
6
+ metadata.gz: 86b21f0e18c8759c79162d2b8f2cde2f1fd8807eae924c4fa6906f698f4a92e518763328a91dc36022c62edbf8772bad6b5f3885b41e4457831d1f11dcdd0d56
7
+ data.tar.gz: 94b7b4a747cb5bab25112cf0ac2041df8fa48009efbbc7f5719fe2df809ea3ae0d0f823928a3b0c6862839f4f3124db8ab3f0e6b2f2de52500d168570d118cb4
@@ -1,4 +1,11 @@
1
1
 
2
+ 1.4.0 / 2017-01-30
3
+ ==================
4
+
5
+ * Add Akamai token generator
6
+ * Merge pull request #201 from nashby/fix-image-formats
7
+ * Remove video formats from the image formats array.
8
+
2
9
  1.3.0 / 2016-12-22
3
10
  ==================
4
11
 
@@ -0,0 +1,50 @@
1
+ require 'openssl'
2
+
3
+ module Cloudinary
4
+ module Akamai
5
+ SEPARATOR = '~'
6
+
7
+ def self.included(base)
8
+ base.extend(ClassMethods)
9
+ end
10
+
11
+ module ClassMethods
12
+ def generate_token(options)
13
+ key = options[:key] || Cloudinary.config.akamai_key
14
+ throw "Missing akamai_key configuration" unless key
15
+ name = options[:token_name] || "__cld_token__"
16
+ start = options[:start_time]
17
+ expiration = options[:end_time]
18
+ ip = options[:ip]
19
+ acl = options[:acl]
20
+ window = options[:window]
21
+
22
+ start = Time.new.getgm.to_i if start == 'now'
23
+ unless expiration
24
+ if window
25
+ expiration = (start || Time.new.getgm.to_i) + window
26
+ else
27
+ throw 'Must provide either end_time or window'
28
+ end
29
+ end
30
+
31
+ token = []
32
+ token << "ip=#{ip}" if ip
33
+ token << "st=#{start}" if start
34
+ token << "exp=#{expiration}"
35
+ token << "acl=#{acl}"
36
+ auth = digest(token.join(SEPARATOR), key)
37
+ token << "hmac=#{auth}"
38
+ "#{name}=#{token.join(SEPARATOR)}"
39
+ end
40
+
41
+ private
42
+
43
+ def digest(message, key = Cloudinary.config.akamai_key)
44
+ bin_key = Array(key).pack("H*")
45
+ digest = OpenSSL::Digest::SHA256.new
46
+ OpenSSL::HMAC.hexdigest(digest, bin_key, message)
47
+ end
48
+ end
49
+ end
50
+ end
@@ -5,8 +5,10 @@ require 'uri'
5
5
  require 'aws_cf_signer'
6
6
  require 'json'
7
7
  require 'cgi'
8
+ require 'cloudinary/akamai'
8
9
 
9
10
  class Cloudinary::Utils
11
+ include Cloudinary::Akamai
10
12
  # @deprecated Use Cloudinary::SHARED_CDN
11
13
  SHARED_CDN = Cloudinary::SHARED_CDN
12
14
  DEFAULT_RESPONSIVE_WIDTH_TRANSFORMATION = {:width => :auto, :crop => :limit}
@@ -626,7 +628,7 @@ class Cloudinary::Utils
626
628
  end
627
629
  end
628
630
 
629
- IMAGE_FORMATS = %w(ai bmp bpg djvu eps eps3 flif gif h264 hdp hpx ico j2k jp2 jpc jpe jpg miff mka mp4 pdf png psd svg tif tiff wdp webm webp zip )
631
+ IMAGE_FORMATS = %w(ai bmp bpg djvu eps eps3 flif gif hdp hpx ico j2k jp2 jpc jpe jpg miff pdf png psd svg tif tiff wdp webp zip )
630
632
 
631
633
  AUDIO_FORMATS = %w(aac aifc aiff flac m4a mp3 ogg wav)
632
634
 
@@ -1,4 +1,4 @@
1
1
  # Copyright Cloudinary
2
2
  module Cloudinary
3
- VERSION = "1.3.0"
3
+ VERSION = "1.4.0"
4
4
  end
@@ -373,6 +373,10 @@ describe Cloudinary::Api do
373
373
  Cloudinary::Api.subfolders("test_folder1")
374
374
  end
375
375
 
376
+ it "should throw if folder is missing" do
377
+ Cloudinary::Api.subfolders("I_do_not_exist")
378
+ end
379
+
376
380
  describe '.restore' do
377
381
  it 'should restore a deleted resource' do
378
382
  expect(RestClient::Request).to receive(:execute).with(deep_hash_value( [:payload, :public_ids] => "api_test_restore", [:url] => /.*\/restore$/))
@@ -7,12 +7,46 @@ include Cloudinary
7
7
  describe Utils do
8
8
 
9
9
  it 'should parse integer range values' do
10
- expect(Utils.instance_eval {norm_range_value("200")}).to eq( "200")
10
+ expect(Utils.instance_eval { norm_range_value("200") }).to eq("200")
11
11
  end
12
12
  it "should parse float range values" do
13
- expect(Utils.instance_eval {norm_range_value("200.0")}).to eq("200.0"), "parse a float"
13
+ expect(Utils.instance_eval { norm_range_value("200.0") }).to eq("200.0"), "parse a float"
14
14
  end
15
15
  it "should parse a percent range value" do
16
- expect(Utils.instance_eval {norm_range_value("20p")}).to eq("20p")
16
+ expect(Utils.instance_eval { norm_range_value("20p") }).to eq("20p")
17
+ end
18
+ describe 'Utils.generate_token' do
19
+ config_backup = Cloudinary.config.clone
20
+ before do
21
+ Cloudinary.config.akamai_key = '00112233FF99'
22
+ end
23
+ after do
24
+ Cloudinary.config.each_pair { |k, _| Cloudinary.config.delete_field(k) }
25
+ Cloudinary.config(config_backup.to_h)
26
+ end
27
+ it "should generate an Akamai token with start_time and window" do
28
+ token = Utils.generate_token start_time: 1111111111, acl: '/image/*', window: 300
29
+ expect(token).to eq('__cld_token__=st=1111111111~exp=1111111411~acl=/image/*~hmac=0854e8b6b6a46471a80b2dc28c69bd352d977a67d031755cc6f3486c121b43af')
30
+ end
31
+ it "should generate an Akamai token with window" do
32
+ first_exp = Time.new.getgm.to_i + 300
33
+ # expiration is calculated automatically as now + window
34
+ token = Utils.generate_token acl: '*', window: 300
35
+ second_exp = Time.new.getgm.to_i + 300
36
+ match = /exp=(\d+)/.match(token)
37
+ expect(match[1]).to be_truthy
38
+ expiration = match[1].to_i
39
+ expect(expiration).to be_between(first_exp, second_exp)
40
+ expect(Utils.generate_token acl: '*', end_time: expiration).to eq(token)
41
+ end
42
+
43
+ it "should accept a key" do
44
+ expect(Utils.generate_token acl: '*', end_time: 10000000, key: '00aabbff')
45
+ .to eq('__cld_token__=exp=10000000~acl=*~hmac=030eafb6b19e499659d699b3d43e7595e35e3c0060e8a71904b3b8c8759f4890')
46
+ end
47
+ it "should throw if no end_time or window is provided" do
48
+ expect { Utils.generate_token acl: '*' }.to raise_error
49
+
50
+ end
17
51
  end
18
52
  end
@@ -1,6 +1,6 @@
1
1
 
2
2
  /**
3
- * Cloudinary's JavaScript library - Version 2.1.8
3
+ * Cloudinary's JavaScript library - Version 2.1.9
4
4
  * Copyright Cloudinary
5
5
  * see https://github.com/cloudinary/cloudinary_js
6
6
  *
@@ -1370,7 +1370,7 @@ var slice = [].slice,
1370
1370
  secure: (typeof window !== "undefined" && window !== null ? (ref = window.location) != null ? ref.protocol : void 0 : void 0) === 'https:'
1371
1371
  };
1372
1372
 
1373
- Configuration.CONFIG_PARAMS = ["api_key", "api_secret", "cdn_subdomain", "cloud_name", "cname", "private_cdn", "protocol", "resource_type", "responsive_class", "responsive_use_breakpoints", "responsive_width", "round_dpr", "secure", "secure_cdn_subdomain", "secure_distribution", "shorten", "type", "url_suffix", "use_root_path", "version"];
1373
+ Configuration.CONFIG_PARAMS = ["api_key", "api_secret", "cdn_subdomain", "cloud_name", "cname", "private_cdn", "protocol", "resource_type", "responsive", "responsive_class", "responsive_use_breakpoints", "responsive_width", "round_dpr", "secure", "secure_cdn_subdomain", "secure_distribution", "shorten", "type", "url_suffix", "use_root_path", "version"];
1374
1374
 
1375
1375
 
1376
1376
  /**
@@ -2715,10 +2715,12 @@ var slice = [].slice,
2715
2715
  /** @override */
2716
2716
 
2717
2717
  ImageTag.prototype.attributes = function() {
2718
- var attr;
2718
+ var attr, options, srcAttribute;
2719
2719
  attr = ImageTag.__super__.attributes.call(this) || [];
2720
- if (attr['src'] == null) {
2721
- attr['src'] = new Cloudinary(this.getOptions()).url(this.publicId);
2720
+ options = this.getOptions();
2721
+ srcAttribute = options.responsive && !options.client_hints ? 'data-src' : 'src';
2722
+ if (attr[srcAttribute] == null) {
2723
+ attr[srcAttribute] = new Cloudinary(this.getOptions()).url(this.publicId);
2722
2724
  }
2723
2725
  return attr;
2724
2726
  };
@@ -2913,7 +2915,7 @@ var slice = [].slice,
2913
2915
  Cloudinary = (function() {
2914
2916
  var AKAMAI_SHARED_CDN, CF_SHARED_CDN, DEFAULT_POSTER_OPTIONS, DEFAULT_VIDEO_SOURCE_TYPES, OLD_AKAMAI_SHARED_CDN, SHARED_CDN, VERSION, absolutize, applyBreakpoints, cdnSubdomainNumber, closestAbove, cloudinaryUrlPrefix, defaultBreakpoints, finalizeResourceType, findContainerWidth, maxWidth, updateDpr;
2915
2917
 
2916
- VERSION = "2.1.8";
2918
+ VERSION = "2.1.9";
2917
2919
 
2918
2920
  CF_SHARED_CDN = "d3jpl91pxevbkh.cloudfront.net";
2919
2921
 
@@ -4148,7 +4150,7 @@ var slice = [].slice,
4148
4150
  TextLayer: TextLayer,
4149
4151
  SubtitlesLayer: SubtitlesLayer,
4150
4152
  Cloudinary: Cloudinary,
4151
- VERSION: "2.1.8",
4153
+ VERSION: "2.1.9",
4152
4154
  CloudinaryJQuery: CloudinaryJQuery
4153
4155
  };
4154
4156
  return cloudinary;
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cloudinary
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nadav Soferman
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-12-22 00:00:00.000000000 Z
13
+ date: 2017-01-30 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: aws_cf_signer
@@ -129,6 +129,7 @@ files:
129
129
  - Rakefile
130
130
  - cloudinary.gemspec
131
131
  - lib/cloudinary.rb
132
+ - lib/cloudinary/akamai.rb
132
133
  - lib/cloudinary/api.rb
133
134
  - lib/cloudinary/blob.rb
134
135
  - lib/cloudinary/carrier_wave.rb