lib/distack/urlsign/signer.rb in distack-urlsign-0.3.1 vs lib/distack/urlsign/signer.rb in distack-urlsign-0.3.2
- old
+ new
@@ -1,8 +1,10 @@
module Distack::URLSign
InvalidSignatureError = Class.new(StandardError)
+ MissingSignatureError = Class.new(StandardError)
+
class Signer
KEY_REGEX = /^[0-9A-f]+$/
def initialize(hex_key)
if hex_key !~ KEY_REGEX
@@ -41,28 +43,36 @@
if url.opaque
raise "can't verify opaque URL"
end
q = Rack::Utils.parse_nested_query(url.query)
+ raise MissingSignatureError unless q["_signature"]
original_q = q.dup
original_q.delete("_signature")
original_qs = Rack::Utils.build_nested_query(original_q)
- chunks = [url.scheme, "#{url.host}:#{url.port}", url.path, original_qs, url.userinfo].compact
+ host_with_port = url.port == url.default_port ? url.host : "#{url.host}:#{url.port}"
+ chunks = [url.scheme, host_with_port, url.path, original_qs, url.userinfo].compact
digest = OpenSSL::Digest.new("sha512")
rawsig = OpenSSL::HMAC.digest(digest, @key, chunks.join)
signature = Base64.urlsafe_encode64(rawsig)
- if secure_compare(signature, q["_signature"])
+ if secure_compare(signature, URI.decode(q["_signature"]).to_s)
new_url = url.dup
new_url.query = original_qs
new_url
else
raise InvalidSignatureError, "signature is invalid for #{url}"
end
+ end
+
+ def valid?(url)
+ !!verify(url)
+ rescue InvalidSignatureError, MissingSignatureError
+ false
end
private
# Constant time string comparison.