Class: AWS::CF::Signer

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

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.default_expiresObject

Public: Provides an accessor to the default_expires value

Returns an Integer value indicating the current setting



77
78
79
# File 'lib/cloudfront-signer.rb', line 77

def default_expires
  @default_expires ||= 3600
end

.key_pair_idObject

Public: Provides a configuration option to set the key_pair_id if it has not been inferred from the key_path

Examples

AWS::CF::Signer.configure do |config|
  config.key_pair_id = "XXYYZZ"
end

Returns a String value indicating the current setting



24
25
26
# File 'lib/cloudfront-signer.rb', line 24

def key_pair_id
  @key_pair_id
end

.key_pathObject

Public: Provides an accessor to the key_path

Returns a String value indicating the current setting



60
61
62
# File 'lib/cloudfront-signer.rb', line 60

def key_path
  @key_path
end

Class Method Details

.configure {|_self| ... } ⇒ Object

Public: Provides a simple way to configure the signing class.

Yields self.

Examples

AWS::CF::Signer.configure do |config|
  config.key_path = "/path/to/yourkeyfile.pem"
  config.key_pair_id  = "XXYYZZ"
  config.default_expires = 3600
end

Returns nothing.

Yields:

  • (_self)

Yield Parameters:



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/cloudfront-signer.rb', line 104

def self.configure
  yield self if block_given?

  unless key_path || private_key
    fail ArgumentError,
         'You must supply the path to a PEM format RSA key pair.'
  end

  unless @key_pair_id
    @key_pair_id = extract_key_pair_id(key_path)
    fail ArgumentError,
         'The Cloudfront signing key id could not be inferred from ' \
         "#{key_path}. Please supply the key pair id as a " \
         'configuration argument.' unless @key_pair_id
  end
end

.is_configured?Boolean

Public: Provides a configuration check method which tests to see that the key_path, key_pair_id and private key values have all been set.

Returns a Boolean value indicating that settings are present.

Returns:

  • (Boolean)


125
126
127
# File 'lib/cloudfront-signer.rb', line 125

def self.is_configured?
  (key_pair_id.nil? || private_key.nil?) ? false : true
end

.key=(key) ⇒ Object

Public: Provides a configuration option to set the key directly as a string e.g. as an ENV var

Examples

AWS::CF::Signer.configure do |config|
  config.key = ENV.fetch('KEY')
end

Returns nothing.



53
54
55
# File 'lib/cloudfront-signer.rb', line 53

def key=(key)
  @key = OpenSSL::PKey::RSA.new(key)
end

.sign(subject, configuration_options = {}, policy_options = {}) ⇒ Object

Public: Builds a signed url or stream resource name with optional configuration and policy options

Returns a String



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/cloudfront-signer.rb', line 166

def self.sign(subject, configuration_options = {}, policy_options = {})
  # If the url or stream path already has a query string parameter -
  # append to that.
  separator = subject =~ /\?/ ? '&' : '?'

  subject.gsub!(/\s/, '%20') if configuration_options[:remove_spaces]

  result = subject +
           separator +
           signed_params(subject, policy_options).collect do |key, value|
             "#{key}=#{value}"
           end.join('&')

  if configuration_options[:html_escape]
    return html_encode(result)
  else
    return result
  end
end

.sign_path(subject, policy_options = {}) ⇒ Object

Public: Sign a stream path part or filename (spaces are allowed in stream paths and so are not removed).

Returns a String



149
150
151
# File 'lib/cloudfront-signer.rb', line 149

def self.sign_path(subject, policy_options = {})
  sign subject, { remove_spaces: false }, policy_options
end

.sign_path_safe(subject, policy_options = {}) ⇒ Object

Public: Sign a stream path or filename and HTML encode the result.

Returns a String



156
157
158
159
160
# File 'lib/cloudfront-signer.rb', line 156

def self.sign_path_safe(subject, policy_options = {})
  sign subject,
       { remove_spaces: false, html_escape: true },
       policy_options
end

.sign_url(subject, policy_options = {}) ⇒ Object

Public: Sign a url - encoding any spaces in the url before signing. CloudFront stipulates that signed URLs must not contain spaces (as opposed to stream paths/filenames which CAN contain spaces).

Returns a String



134
135
136
# File 'lib/cloudfront-signer.rb', line 134

def self.sign_url(subject, policy_options = {})
  sign subject, { remove_spaces: true }, policy_options
end

.sign_url_safe(subject, policy_options = {}) ⇒ Object

Public: Sign a url (as above) and HTML encode the result.

Returns a String



141
142
143
# File 'lib/cloudfront-signer.rb', line 141

def self.sign_url_safe(subject, policy_options = {})
  sign subject, { remove_spaces: true, html_escape: true }, policy_options
end

.signed_params(subject, policy_options = {}) ⇒ Object

Public: Sign a subject url or stream resource name with optional policy options. It returns raw params to be used in urls or cookies

Returns a Hash



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/cloudfront-signer.rb', line 190

def self.signed_params(subject, policy_options = {})
  result = {}

  if policy_options[:policy_file]
    policy = IO.read(policy_options[:policy_file])
    result['Policy'] = encode_policy(policy)
  else
    policy_options[:expires] = epoch_time(policy_options[:expires] ||
                                          Time.now + default_expires)

    if policy_options.keys.size <= 1
      # Canned Policy - shorter URL
      expires_at = policy_options[:expires]
      policy = %{{"Statement":[{"Resource":"#{subject}","Condition":{"DateLessThan":{"AWS:EpochTime":#{expires_at}}}}]}}
      result['Expires'] = expires_at
    else
      # Custom Policy
      resource = policy_options[:resource] || subject
      policy = generate_custom_policy(resource, policy_options)
      result['Policy'] = encode_policy(policy)
    end
  end

  result.merge 'Signature' => create_signature(policy),
               'Key-Pair-Id' => @key_pair_id
end