Chris@909: require 'digest/sha1' Chris@909: require 'openid/store/interface' Chris@909: Chris@909: module OpenIdAuthentication Chris@909: class MemCacheStore < OpenID::Store::Interface Chris@909: def initialize(*addresses) Chris@909: @connection = ActiveSupport::Cache::MemCacheStore.new(addresses) Chris@909: end Chris@909: Chris@909: def store_association(server_url, assoc) Chris@909: server_key = association_server_key(server_url) Chris@909: assoc_key = association_key(server_url, assoc.handle) Chris@909: Chris@909: assocs = @connection.read(server_key) || {} Chris@909: assocs[assoc.issued] = assoc_key Chris@909: Chris@909: @connection.write(server_key, assocs) Chris@909: @connection.write(assoc_key, assoc, :expires_in => assoc.lifetime) Chris@909: end Chris@909: Chris@909: def get_association(server_url, handle = nil) Chris@909: if handle Chris@909: @connection.read(association_key(server_url, handle)) Chris@909: else Chris@909: server_key = association_server_key(server_url) Chris@909: assocs = @connection.read(server_key) Chris@909: return if assocs.nil? Chris@909: Chris@909: last_key = assocs[assocs.keys.sort.last] Chris@909: @connection.read(last_key) Chris@909: end Chris@909: end Chris@909: Chris@909: def remove_association(server_url, handle) Chris@909: server_key = association_server_key(server_url) Chris@909: assoc_key = association_key(server_url, handle) Chris@909: assocs = @connection.read(server_key) Chris@909: Chris@909: return false unless assocs && assocs.has_value?(assoc_key) Chris@909: Chris@909: assocs = assocs.delete_if { |key, value| value == assoc_key } Chris@909: Chris@909: @connection.write(server_key, assocs) Chris@909: @connection.delete(assoc_key) Chris@909: Chris@909: return true Chris@909: end Chris@909: Chris@909: def use_nonce(server_url, timestamp, salt) Chris@909: return false if @connection.read(nonce_key(server_url, salt)) Chris@909: return false if (timestamp - Time.now.to_i).abs > OpenID::Nonce.skew Chris@909: @connection.write(nonce_key(server_url, salt), timestamp, :expires_in => OpenID::Nonce.skew) Chris@909: return true Chris@909: end Chris@909: Chris@909: private Chris@909: def association_key(server_url, handle = nil) Chris@909: "openid_association_#{digest(server_url)}_#{digest(handle)}" Chris@909: end Chris@909: Chris@909: def association_server_key(server_url) Chris@909: "openid_association_server_#{digest(server_url)}" Chris@909: end Chris@909: Chris@909: def nonce_key(server_url, salt) Chris@909: "openid_nonce_#{digest(server_url)}_#{digest(salt)}" Chris@909: end Chris@909: Chris@909: def digest(text) Chris@909: Digest::SHA1.hexdigest(text) Chris@909: end Chris@909: end Chris@909: end