Interface
Create a Filesystem store instance, putting all data in directory.
# File lib/openid/store/filesystem.rb, line 15 def initialize(directory) @nonce_dir = File.join(directory, 'nonces') @association_dir = File.join(directory, 'associations') @temp_dir = File.join(directory, 'temp') self.ensure_dir(@nonce_dir) self.ensure_dir(@association_dir) self.ensure_dir(@temp_dir) end
# File lib/openid/store/filesystem.rb, line 99 def _get_association(filename) begin assoc_file = File.open(filename, "r") rescue Errno::ENOENT return nil else begin assoc_s = assoc_file.read ensure assoc_file.close end begin association = Association.deserialize(assoc_s) rescue self.remove_if_present(filename) return nil end # clean up expired associations if association.expires_in == 0 self.remove_if_present(filename) return nil else return association end end end
Remove expired entries from the database. This is potentially expensive, so only run when it is acceptable to take time.
# File lib/openid/store/filesystem.rb, line 170 def cleanup cleanup_associations cleanup_nonces end
# File lib/openid/store/filesystem.rb, line 175 def cleanup_associations association_filenames = Dir[File.join(@association_dir, "*")] count = 0 association_filenames.each do |af| begin f = File.open(af, 'r') rescue Errno::ENOENT next else begin assoc_s = f.read ensure f.close end begin association = OpenID::Association.deserialize(assoc_s) rescue StandardError self.remove_if_present(af) next else if association.expires_in == 0 self.remove_if_present(af) count += 1 end end end end return count end
# File lib/openid/store/filesystem.rb, line 205 def cleanup_nonces nonces = Dir[File.join(@nonce_dir, "*")] now = Time.now.to_i count = 0 nonces.each do |filename| nonce = filename.split('/')[-1] timestamp = nonce.split('-', 2)[0].to_i(16) nonce_age = (timestamp - now).abs if nonce_age > Nonce.skew self.remove_if_present(filename) count += 1 end end return count end
Retrieve an association
# File lib/openid/store/filesystem.rb, line 79 def get_association(server_url, handle=nil) # the filename with empty handle is the prefix for the associations # for a given server url filename = get_association_filename(server_url, handle) if handle return _get_association(filename) end assoc_filenames = Dir.glob(filename.to_s + '*') assocs = assoc_filenames.collect do |f| _get_association(f) end assocs = assocs.find_all { |a| not a.nil? } assocs = assocs.sort_by { |a| a.issued } return nil if assocs.empty? return assocs[-1] end
Create a unique filename for a given server url and handle. The filename that is returned will contain the domain name from the server URL for ease of human inspection of the data dir.
# File lib/openid/store/filesystem.rb, line 28 def get_association_filename(server_url, handle) unless server_url.index('://') raise ArgumentError, "Bad server URL: #{server_url}" end proto, rest = server_url.split('://', 2) domain = filename_escape(rest.split('/',2)[0]) url_hash = safe64(server_url) if handle handle_hash = safe64(handle) else handle_hash = '' end filename = [proto,domain,url_hash,handle_hash].join('-') File.join(@association_dir, filename) end
Remove an association if it exists, otherwise do nothing.
# File lib/openid/store/filesystem.rb, line 129 def remove_association(server_url, handle) assoc = get_association(server_url, handle) if assoc.nil? return false else filename = get_association_filename(server_url, handle) return self.remove_if_present(filename) end end
Store an association in the assoc directory
# File lib/openid/store/filesystem.rb, line 46 def store_association(server_url, association) assoc_s = association.serialize filename = get_association_filename(server_url, association.handle) f, tmp = mktemp begin begin f.write(assoc_s) f.fsync ensure f.close end begin File.rename(tmp, filename) rescue Errno::EEXIST begin File.unlink(filename) rescue Errno::ENOENT # do nothing end File.rename(tmp, filename) end rescue self.remove_if_present(tmp) raise end end
Return whether the nonce is valid
# File lib/openid/store/filesystem.rb, line 141 def use_nonce(server_url, timestamp, salt) return false if (timestamp - Time.now.to_i).abs > Nonce.skew if server_url and !server_url.empty? proto, rest = server_url.split('://',2) else proto, rest = '','' end raise "Bad server URL" unless proto && rest domain = filename_escape(rest.split('/',2)[0]) url_hash = safe64(server_url) salt_hash = safe64(salt) nonce_fn = '%08x-%s-%s-%s-%s'%[timestamp, proto, domain, url_hash, salt_hash] filename = File.join(@nonce_dir, nonce_fn) begin fd = File.new(filename, File::CREAT | File::EXCL | File::WRONLY, 0200) fd.close return true rescue Errno::EEXIST return false end end
ensure that a path exists
# File lib/openid/store/filesystem.rb, line 264 def ensure_dir(dir_name) FileUtils::mkdir_p(dir_name) end
create a safe filename from a url
# File lib/openid/store/filesystem.rb, line 231 def filename_escape(s) s = '' if s.nil? filename_chunks = [] s.split('').each do |c| if @@FILENAME_ALLOWED.index(c) filename_chunks << c else filename_chunks << sprintf("_%02X", c.bytes.first) end end filename_chunks.join("") end
Create a temporary file and return the File object and filename.
# File lib/openid/store/filesystem.rb, line 225 def mktemp f = Tempfile.new('tmp', @temp_dir) [f, f.path] end
Generated with the Darkfish Rdoc Generator 2.