11require 'openssl'
2+ if RUBY_VERSION > "2"
3+ require "ostruct"
4+ else
5+ require "cloudinary/ostruct2"
6+ end
7+
28
39module Cloudinary
4- module Akamai
10+ module AuthToken
511 SEPARATOR = '~'
612
7- def self . included ( base )
8- base . extend ( ClassMethods )
9- end
10-
11- module ClassMethods
12- def generate_auth_token ( options = { } )
13- options = ( Cloudinary . config . auth_token || { } ) . to_h . merge options
14- key = options [ :key ]
15- throw "Missing auth token key configuration" unless key
13+ def self . generate ( options = { } )
14+ key = options [ :key ]
15+ throw "Missing auth token key configuration" unless key
1616 name = options [ :token_name ] || "__cld_token__"
1717 start = options [ :start_time ]
1818 expiration = options [ :expiration ]
1919 ip = options [ :ip ]
2020 acl = options [ :acl ]
2121 duration = options [ :duration ]
2222 url = options [ :url ]
23- start = Time . new . getgm . to_i if start == 'now'
24- if expiration . nil? || expiration == 0
25- if !( duration . nil? || duration == 0 )
26- expiration = ( start || Time . new . getgm . to_i ) + duration
27- else
28- throw 'Must provide either expiration or duration'
29- end
23+ start = Time . new . getgm . to_i if start == 'now'
24+ if expiration . nil? || expiration == 0
25+ if !( duration . nil? || duration == 0 )
26+ expiration = ( start || Time . new . getgm . to_i ) + duration
27+ else
28+ throw 'Must provide either expiration or duration'
3029 end
31-
32- token = [ ]
33- token << "ip=#{ ip } " if ip
34- token << "st=#{ start } " if start
35- token << "exp=#{ expiration } "
36- token << "acl=#{ escape_to_lower ( acl ) } " if acl
37- to_sign = token . clone
38- to_sign << "url=#{ escape_to_lower ( url ) } " if url
39- auth = digest ( to_sign . join ( SEPARATOR ) , key )
40- token << "hmac=#{ auth } "
41- "#{ name } =#{ token . join ( SEPARATOR ) } "
4230 end
4331
44- # escape URI pattern using lowercase hex. For example "/" -> "%2f".
45- def escape_to_lower ( url )
46- CGI ::escape ( url ) . gsub ( /%../ ) { |h | h . downcase }
47- end
32+ token = [ ]
33+ token << "ip=#{ ip } " if ip
34+ token << "st=#{ start } " if start
35+ token << "exp=#{ expiration } "
36+ token << "acl=#{ escape_to_lower ( acl ) } " if acl
37+ to_sign = token . clone
38+ to_sign << "url=#{ escape_to_lower ( url ) } " if url
39+ auth = digest ( to_sign . join ( SEPARATOR ) , key )
40+ token << "hmac=#{ auth } "
41+ "#{ name } =#{ token . join ( SEPARATOR ) } "
42+ end
4843
49- private
5044
51- def digest ( message , key )
52- bin_key = Array ( key ) . pack ( "H*" )
53- digest = OpenSSL ::Digest ::SHA256 . new
54- OpenSSL ::HMAC . hexdigest ( digest , bin_key , message )
55- end
45+ # Merge token2 to token1 returning a new
46+ # Requires to support Ruby 1.9
47+ def self . merge_auth_token ( token1 , token2 )
48+ token1 = token1 || { }
49+ token2 = token2 || { }
50+ token1 = token1 . respond_to? ( :to_h ) ? token1 . to_h : token1
51+ token2 = token2 . respond_to? ( :to_h ) ? token2 . to_h : token2
52+ token1 . merge ( token2 )
53+ end
54+
55+ private
56+
57+ # escape URI pattern using lowercase hex. For example "/" -> "%2f".
58+ def self . escape_to_lower ( url )
59+ CGI ::escape ( url ) . gsub ( /%../ ) { |h | h . downcase }
60+ end
61+
62+ def self . digest ( message , key )
63+ bin_key = Array ( key ) . pack ( "H*" )
64+ digest = OpenSSL ::Digest ::SHA256 . new
65+ OpenSSL ::HMAC . hexdigest ( digest , bin_key , message )
5666 end
5767 end
5868end
0 commit comments