Class: TOS::Signer

Inherits:
Object
  • Object
show all
Defined in:
lib/tos/signer.rb

Overview

Signs HTTP requests for the TOS object service using TOS4-HMAC-SHA256 (AWS SigV4 with the “tos” service name)

Constant Summary collapse

ALGORITHM =
"TOS4-HMAC-SHA256"
SERVICE =
"tos"
REQUEST =
"request"
EMPTY_SHA256 =
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
UNSIGNED_PAYLOAD =
"UNSIGNED-PAYLOAD"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(credentials:, region:) ⇒ Signer

Returns a new instance of Signer.

Raises:



18
19
20
21
22
23
24
# File 'lib/tos/signer.rb', line 18

def initialize(credentials:, region:)
  @credentials = Credentials.from(credentials)
  raise ConfigError, "TOS credentials are missing access_key_id/secret_access_key" unless @credentials.valid?
  raise ConfigError, "TOS region is required" if region.to_s.empty?

  @region = region.to_s
end

Instance Attribute Details

#credentialsObject (readonly)

Returns the value of attribute credentials.



16
17
18
# File 'lib/tos/signer.rb', line 16

def credentials
  @credentials
end

#regionObject (readonly)

Returns the value of attribute region.



16
17
18
# File 'lib/tos/signer.rb', line 16

def region
  @region
end

Instance Method Details

#presign(method:, host:, path:, query: {}, expires_in: 3600, now: Time.now.utc) ⇒ Object

Build a presigned URL with all signing material in the query string.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/tos/signer.rb', line 44

def presign(method:, host:, path:, query: {}, expires_in: 3600, now: Time.now.utc)
  datetime = now.strftime("%Y%m%dT%H%M%SZ")
  params = query.merge(
    "X-Tos-Algorithm" => ALGORITHM,
    "X-Tos-Credential" => "#{@credentials.access_key_id}/#{credential_scope(datetime[0, 8])}",
    "X-Tos-Date" => datetime,
    "X-Tos-Expires" => expires_in.to_s,
    "X-Tos-SignedHeaders" => "",
  )
  params["X-Tos-Security-Token"] = @credentials.security_token if @credentials.security_token

  params["X-Tos-Signature"] = sign(method, path, params, [], UNSIGNED_PAYLOAD, datetime)
  "https://#{host}#{path}?#{encode_query(params)}"
end

#sign_headers(method:, path:, query: {}, headers: {}, body: nil, now: Time.now.utc) ⇒ Object

Sign a request and return a Hash of headers to add (Authorization, X-Tos-Date, X-Tos-Content-Sha256, plus X-Tos-Security-Token when STS credentials are used).



29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/tos/signer.rb', line 29

def sign_headers(method:, path:, query: {}, headers: {}, body: nil, now: Time.now.utc)
  datetime = now.strftime("%Y%m%dT%H%M%SZ")
  content_sha = body ? sha256_hex(body) : EMPTY_SHA256

  out = headers.dup
  out["X-Tos-Date"] = datetime
  out["X-Tos-Content-Sha256"] = content_sha
  out["X-Tos-Security-Token"] = @credentials.security_token if @credentials.security_token

  signed = signed_headers(out)
  out["Authorization"] = authorization(method, path, query, signed, content_sha, datetime)
  out
end