Class: VagrantPlugins::S3Auth::Action::AuthenticateBoxUrl

Inherits:
Object
  • Object
show all
Defined in:
lib/vagrant-s3auth/action/authenticate_box_url.rb

Instance Method Summary collapse

Constructor Details

#initialize(app, env) ⇒ AuthenticateBoxUrl

Returns a new instance of AuthenticateBoxUrl.



11
12
13
14
15
16
# File 'lib/vagrant-s3auth/action/authenticate_box_url.rb', line 11

def initialize(app, env)
  @app    = app
  @logger = Log4r::Logger.new('vagrant_s3auth::action::authenticate_box_url')
  @access_key = ENV['AWS_ACCESS_KEY_ID']
  @secret_key = ENV['AWS_SECRET_ACCESS_KEY']
end

Instance Method Details

#box_url?(url) ⇒ Boolean

Returns:

  • (Boolean)


80
81
82
# File 'lib/vagrant-s3auth/action/authenticate_box_url.rb', line 80

def box_url?(url)
  url.path.end_with?('.box')
end

#call(env) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/vagrant-s3auth/action/authenticate_box_url.rb', line 18

def call(env)
  env[:box_urls].map! do |url_string|
    begin
      url = URI.parse(url_string)
    rescue URI::InvalidURIError
      next url_string
    end

    unless s3_url?(url)
      @logger.debug("Skipping non-S3 host: #{url}")
      next url_string
    end

    # Vagrant makes a HEAD request for metadata. S3 doesn't support
    # query-string authentication on HEAD requests, so skip signing. We
    # need to provide a different "authenticated" URL, though, or
    # Vagrant will think the box doesn't require authentication,
    # and won't request an authenticated URL for the box itself.
    unless box_url?(url)
      @logger.debug("Munging S3 metadata URL: #{url}")
      next url_string + '?'
    end

    @logger.info("Signing URL for S3 box: #{url}")
    sign(url)
  end

  @app.call(env)
end

#ensure_credentialsObject



65
66
67
68
69
70
71
72
73
74
# File 'lib/vagrant-s3auth/action/authenticate_box_url.rb', line 65

def ensure_credentials
  missing_variables = []
  missing_variables << 'AWS_ACCESS_KEY_ID' unless @access_key
  missing_variables << 'AWS_SECRET_ACCESS_KEY' unless @secret_key

  unless missing_variables.empty?
    raise Errors::MissingCredentialsError,
      missing_variables: missing_variables.join(', ')
  end
end

#s3_url?(url) ⇒ Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/vagrant-s3auth/action/authenticate_box_url.rb', line 76

def s3_url?(url)
  url.host == S3_HOST
end

#sign(url) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/vagrant-s3auth/action/authenticate_box_url.rb', line 48

def sign(url)
  ensure_credentials

  expires = (Time.now + 20).to_i
  message = "GET\n\n\n#{expires}\n#{url.path}"
  signature = CGI.escape(Base64.strict_encode64(
    OpenSSL::HMAC.digest('sha1', @secret_key, message)))

  url.query = {
    'AWSAccessKeyId' => @access_key,
    'Expires'        => expires,
    'Signature'      => signature
  }.map { |k, v| "#{k}=#{v}" }.join('&')

  url.to_s
end