Class: BosClient::Authable

Inherits:
Object
  • Object
show all
Defined in:
lib/bos_client/auth.rb

Class Method Summary collapse

Class Method Details

.authorize_request(request) ⇒ Object



8
9
10
11
12
13
14
# File 'lib/bos_client/auth.rb', line 8

def self.authorize_request request
  default_headers = get_default_headers request
  request.options[:headers].merge! default_headers
  authorization = sign(request)
  request.options[:headers].merge!({"Authorization" => authorization})
  request
end

.encode(string) ⇒ Object



61
62
63
# File 'lib/bos_client/auth.rb', line 61

def encode string
  URI.encode(string, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
end

.encode_slash(str) ⇒ Object



65
66
67
# File 'lib/bos_client/auth.rb', line 65

def encode_slash str
  str.gsub(/\//,'%2F')
end

.get_canonical_headers(request) ⇒ Object



46
47
48
49
50
51
52
53
54
55
# File 'lib/bos_client/auth.rb', line 46

def get_canonical_headers request
  headers_to_sign_keys = ["host", "content-md5", "content-length", "content-type"]
  headers_to_sign = []
  canonical_headers_downcase = request.options[:headers].each do |k, v|
    if headers_to_sign_keys.include?(k) || k.start_with?('x-bce')
      headers_to_sign << "#{encode(k.to_s.downcase)}:#{encode(v.to_s)}"
    end
  end
  headers_to_sign.compact.sort.join("\n")
end

.get_canonical_query_string(request) ⇒ Object



38
39
40
41
42
43
44
# File 'lib/bos_client/auth.rb', line 38

def get_canonical_query_string request
  params = request.options[:params]
  params = params.map do |k, v|
    "#{URI.encode(k.to_s)}=#{encode_slash(URI.encode(v.to_s))}"
  end.compact.sort.join('&')
  params
end

.get_canonical_time(t = Time.now.to_i) ⇒ Object



18
19
20
# File 'lib/bos_client/auth.rb', line 18

def get_canonical_time t = Time.now.to_i
  Time.at(t).utc.strftime("%FT%TZ")
end

.get_canonical_uri(request) ⇒ Object



32
33
34
35
36
# File 'lib/bos_client/auth.rb', line 32

def get_canonical_uri request
  uri  = URI(request.base_url)
  url_path = URI.encode(uri.path)
  url_path == '' ? '/' : url_path
end

.get_default_headers(request) ⇒ Object



22
23
24
25
26
27
28
29
30
# File 'lib/bos_client/auth.rb', line 22

def get_default_headers request
  {
    "content-type" =>"text/plain",
    "x-bce-date" => get_canonical_time,
    "content-length" => (request.options[:body] || "").length
  }
    # todo PUT 方法计算的签名错误,content-length 的问题,暂时处理。
  # headers.merge!({"content-length" => 0}) if request.options[:method] == :put
end

.get_http_method(request) ⇒ Object



57
58
59
# File 'lib/bos_client/auth.rb', line 57

def get_http_method request
  (request.options[:method] || 'get').upcase
end

.sign(request) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/bos_client/auth.rb', line 69

def sign request
  digest = OpenSSL::Digest.new('sha256')
  sign_key_prefix = "bce-auth-v1/#{BosClient.access_key_id}/#{get_canonical_time()}/#{BosClient.expiration_in_seconds}"
  sign_key = OpenSSL::HMAC.hexdigest digest, BosClient.secret_access_key, sign_key_prefix

  http_method = get_http_method request

  canonical_uri = get_canonical_uri request
  canonical_query_string = get_canonical_query_string request
  canonical_headers = get_canonical_headers request
  string_to_sign = [http_method, canonical_uri, canonical_query_string, canonical_headers].join("\n")
  sign_result = OpenSSL::HMAC.hexdigest digest, sign_key, string_to_sign
  "#{sign_key_prefix}//#{sign_result}"
end