Module: Roda::RodaPlugins::HmacPaths::InstanceMethods

Defined in:
lib/roda/plugins/hmac_paths.rb

Instance Method Summary collapse

Instance Method Details

#hmac_path(path, opts = OPTS) ⇒ Object

Return a path with an HMAC. Designed to be used with r.hmac_path, to make sure users can only request paths that they have been provided by the application (directly or indirectly). This can prevent users of a site from enumerating valid paths. The given path should be a string starting with /. Options:

:method

Limits the returned path to only be valid for the given request method.

:params

Includes parameters in the query string of the returned path, and limits the returned path to only be valid for that exact query string.

:root

Should be an empty string or string starting with /. This will be the already matched path of the routing tree using r.hmac_path. Defaults to the empty string, which will returns paths valid for r.hmac_path at the top level of the routing tree.



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/roda/plugins/hmac_paths.rb', line 161

def hmac_path(path, opts=OPTS)
  unless path.is_a?(String) && path.getbyte(0) == 47
    raise RodaError, "path must be a string starting with /"
  end

  root = opts[:root] || ''
  unless root.is_a?(String) && ((root_byte = root.getbyte(0)) == 47 || root_byte == nil)
    raise RodaError, "root must be empty string or string starting with /"
  end

  flags = String.new
  path = path.dup

  if method = opts[:method]
    flags << 'm'
  end

  if params = opts[:params]
    flags << 'p'
    path << '?' << Rack::Utils.build_query(params)
  end

  flags << '0' if flags.empty?
  
  hmac_path = if method
    "#{method.to_s.upcase}:/#{flags}#{path}"
  else
    "/#{flags}#{path}"
  end

  "#{root}/#{hmac_path_hmac(root, hmac_path)}/#{flags}#{path}"
end

#hmac_path_hmac(root, path, opts = OPTS) ⇒ Object

The HMAC to use in hmac_path, for the given root, path, and options.



195
196
197
# File 'lib/roda/plugins/hmac_paths.rb', line 195

def hmac_path_hmac(root, path, opts=OPTS)
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, hmac_path_hmac_secret(root, opts), path)
end