module AliyunVod::Sign # https://help.aliyun.com/document_detail/44434.html?spm=a2c4g.11186623.2.16.354c7853oqlhMb&/#SignatureNonce def self.generate(params, **opts) method = opts[:method] || 'POST' key = opts[:key] || AliyunVod.access_key_secret + '&' digest = OpenSSL::Digest.new('sha1') str = params_to_string(params) str = percent_encode(str) str = "#{method}&%2F&#{str}" Base64.encode64(OpenSSL::HMAC.digest(digest, key, str)).gsub(/\n/, '') end def self.verify?(signature, timestamp) content = "#{AliyunVod.callback_url}|#{timestamp}|#{AliyunVod.signature_key}" our_signature = Digest::MD5.hexdigest(content) ActiveSupport::SecurityUtils.secure_compare(signature, our_signature) end def self.params_to_string(params) params.sort.map { |k, v| "#{percent_encode(k)}=#{percent_encode(v)}" }.join('&') end def self.percent_encode(str) return '' if str.blank? CGI::escape(str.to_s).gsub(/\+/,'%20').gsub(/\*/,'%2A').gsub(/%7E/,'~') end def self.format_params(params) params.each_with_object({}) do |arr, obj| obj[arr[0]] = arr[1].is_a?(Hash) ? parse_hash_to_str(arr[1]) : arr[1] end end def self.parse_hash_to_str(hash) hash.each_with_object({}) do |h, obj| obj[h[0]] = h[1].is_a?(Hash) ? parse_hash_to_str(h[1].clone) : h[1].to_s end.to_json end end