aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib/active_support/message_verifier.rb
diff options
context:
space:
mode:
authorHongli Lai (Phusion) <hongli@phusion.nl>2008-12-03 19:30:35 +0100
committerHongli Lai (Phusion) <hongli@phusion.nl>2008-12-03 19:30:35 +0100
commitccb96f2297e8783165cba764e9b5d51e1a15ff87 (patch)
tree3229e6fdddc42054615514d843c555e341003033 /activesupport/lib/active_support/message_verifier.rb
parentfb2325e35855d62abd2c76ce03feaa3ca7992e4f (diff)
parent761a633a9c0a45d76ef3ed10da97e3696c3ded79 (diff)
downloadrails-ccb96f2297e8783165cba764e9b5d51e1a15ff87.tar.gz
rails-ccb96f2297e8783165cba764e9b5d51e1a15ff87.tar.bz2
rails-ccb96f2297e8783165cba764e9b5d51e1a15ff87.zip
Merge commit 'origin/master' into savepoints
Conflicts: activerecord/lib/active_record/fixtures.rb activerecord/test/cases/defaults_test.rb
Diffstat (limited to 'activesupport/lib/active_support/message_verifier.rb')
-rw-r--r--activesupport/lib/active_support/message_verifier.rb46
1 files changed, 46 insertions, 0 deletions
diff --git a/activesupport/lib/active_support/message_verifier.rb b/activesupport/lib/active_support/message_verifier.rb
new file mode 100644
index 0000000000..b24acb9f47
--- /dev/null
+++ b/activesupport/lib/active_support/message_verifier.rb
@@ -0,0 +1,46 @@
+module ActiveSupport
+ # MessageVerifier makes it easy to generate and verify messages which are signed
+ # to prevent tampering.
+ #
+ # This is useful for cases like remember-me tokens and auto-unsubscribe links where the
+ # session store isn't suitable or available.
+ #
+ # Remember Me:
+ # cookies[:remember_me] = @verifier.generate([@user.id, 2.weeks.from_now])
+ #
+ # In the authentication filter:
+ #
+ # id, time = @verifier.verify(cookies[:remember_me])
+ # if time < Time.now
+ # self.current_user = User.find(id)
+ # end
+ #
+ class MessageVerifier
+ class InvalidSignature < StandardError; end
+
+ def initialize(secret, digest = 'SHA1')
+ @secret = secret
+ @digest = digest
+ end
+
+ def verify(signed_message)
+ data, digest = signed_message.split("--")
+ if digest != generate_digest(data)
+ raise InvalidSignature
+ else
+ Marshal.load(ActiveSupport::Base64.decode64(data))
+ end
+ end
+
+ def generate(value)
+ data = ActiveSupport::Base64.encode64s(Marshal.dump(value))
+ "#{data}--#{generate_digest(data)}"
+ end
+
+ private
+ def generate_digest(data)
+ require 'openssl' unless defined?(OpenSSL)
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(@digest), @secret, data)
+ end
+ end
+end