From 065859b90cc5ef403b8f47bd5394b343e556cc4d Mon Sep 17 00:00:00 2001 From: Azul Date: Wed, 23 Mar 2016 21:48:52 +0100 Subject: upgrade: remove references to RestClient CouchRest > 1.2 does not use RestClient anymore. So we should not try to catch its errors. --- .../lib/couchrest/session/document.rb | 119 +++++++++++++++++++++ .../lib/couchrest/session/store.rb | 94 ++++++++++++++++ 2 files changed, 213 insertions(+) create mode 100644 vendor/gems/couchrest_session_store/lib/couchrest/session/document.rb create mode 100644 vendor/gems/couchrest_session_store/lib/couchrest/session/store.rb (limited to 'vendor/gems/couchrest_session_store/lib/couchrest/session') diff --git a/vendor/gems/couchrest_session_store/lib/couchrest/session/document.rb b/vendor/gems/couchrest_session_store/lib/couchrest/session/document.rb new file mode 100644 index 0000000..b1e73cc --- /dev/null +++ b/vendor/gems/couchrest_session_store/lib/couchrest/session/document.rb @@ -0,0 +1,119 @@ +require 'couchrest/session/utility' +require 'time' + +class CouchRest::Session::Document < CouchRest::Document + include CouchRest::Model::Configuration + include CouchRest::Model::Connection + include CouchRest::Session::Utility + include CouchRest::Model::Rotation + + rotate_database 'sessions', + :every => 1.month, :expiration_field => :expires + + def self.fetch(sid) + self.allocate.tap do |session_doc| + session_doc.fetch(sid) + end + end + + def self.build(sid, session, options = {}) + self.new(CouchRest::Document.new({"_id" => sid})).tap do |session_doc| + session_doc.update session, options + end + end + + def self.build_or_update(sid, session, options = {}) + options[:marshal_data] = true if options[:marshal_data].nil? + doc = self.fetch(sid) + doc.update(session, options) + return doc + rescue CouchRest::NotFound + self.build(sid, session, options) + end + + def self.find_by_expires(options = {}) + options[:reduce] ||= false + design = database.get '_design/Session' + response = design.view :by_expires, options + response['rows'] + end + + def self.create_database!(name=nil) + db = super(name) + begin + db.get('_design/Session') + rescue CouchRest::NotFound + design = File.read(File.expand_path('../../../../design/Session.json', __FILE__)) + design = JSON.parse(design) + db.save_doc(design.merge({"_id" => "_design/Session"})) + end + db + end + + def initialize(doc) + @doc = doc + end + + def fetch(sid = nil) + @doc = database.get(sid || doc['_id']) + end + + def to_session + if doc["marshalled"] + session = unmarshal(doc["data"]) + else + session = doc["data"] + end + return session + end + + def delete + database.delete_doc(doc) + end + + def update(session, options) + # clean up old data but leave id and revision intact + doc.reject! do |k,v| + k[0] != '_' + end + doc.merge! data_for_doc(session, options) + end + + def save + database.save_doc(doc) + rescue CouchRest::Conflict + fetch + retry + rescue CouchRest::NotFound => exc + if exc.http_body =~ /no_db_file/ + exc = CouchRest::StorageMissing.new(exc.response, database) + end + raise exc + end + + def expired? + expires && expires < Time.now + end + + protected + + def data_for_doc(session, options) + { "data" => options[:marshal_data] ? marshal(session) : session, + "marshalled" => options[:marshal_data], + "expires" => expiry_from_options(options) } + end + + def expiry_from_options(options) + expire_after = options[:expire_after] + expire_after && (Time.now + expire_after).utc + end + + def expires + doc["expires"] && Time.iso8601(doc["expires"]) + end + + def doc + @doc + end + +end diff --git a/vendor/gems/couchrest_session_store/lib/couchrest/session/store.rb b/vendor/gems/couchrest_session_store/lib/couchrest/session/store.rb new file mode 100644 index 0000000..f209f54 --- /dev/null +++ b/vendor/gems/couchrest_session_store/lib/couchrest/session/store.rb @@ -0,0 +1,94 @@ +class CouchRest::Session::Store < ActionDispatch::Session::AbstractStore + + # delegate configure to document + def self.configure(*args, &block) + CouchRest::Session::Document.configure *args, &block + end + + def self.set_options(options) + @options = options + if @options[:database] + CouchRest::Session::Document.use_database @options[:database] + end + end + + def initialize(app, options = {}) + super + self.class.set_options(options) + end + + def cleanup(rows) + rows.each do |row| + doc = CouchRest::Session::Document.fetch(row['id']) + doc.delete + end + end + + def expired + CouchRest::Session::Document.find_by_expires startkey: 1, + endkey: Time.now.utc.iso8601 + end + + def never_expiring + CouchRest::Session::Document.find_by_expires endkey: 1 + end + + private + + def get_session(env, sid) + if session = fetch_session(sid) + [sid, session] + else + [generate_sid, {}] + end + rescue CouchRest::NotFound + # session data does not exist anymore + return [sid, {}] + rescue CouchRest::Unauthorized, + Errno::EHOSTUNREACH, + Errno::ECONNREFUSED => e + # can't connect to couch. We add some status to the session + # so the app can react. (Display error for example) + return [sid, {"_status" => {"couch" => "unreachable"}}] + end + + def set_session(env, sid, session, options) + raise CouchRest::NotFound if /^_design\/(.*)/ =~ sid + doc = build_or_update_doc(sid, session, options) + doc.save + return sid + # if we can't store the session we just return false. + rescue CouchRest::Unauthorized, + Errno::EHOSTUNREACH, + Errno::ECONNREFUSED => e + return false + end + + def destroy_session(env, sid, options) + doc = secure_get(sid) + doc.delete + generate_sid unless options[:drop] + rescue CouchRest::NotFound + # already destroyed - we're done. + generate_sid unless options[:drop] + end + + def fetch_session(sid) + return nil unless sid + doc = secure_get(sid) + doc.to_session unless doc.expired? + end + + def build_or_update_doc(sid, session, options) + CouchRest::Session::Document.build_or_update(sid, session, options) + end + + # prevent access to design docs + # this should be prevented on a couch permission level as well. + # but better be save than sorry. + def secure_get(sid) + raise CouchRest::NotFound if /^_design\/(.*)/ =~ sid + CouchRest::Session::Document.fetch(sid) + end + +end -- cgit v1.2.3