aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/application.rb60
-rw-r--r--app/controllers/user_controller.rb9
-rw-r--r--app/views/user/_signin.rhtml5
-rw-r--r--config/environment.rb20
-rw-r--r--config/general-example5
-rw-r--r--db/migrate/058_remove_sessions.rb16
-rw-r--r--db/schema.rb12
-rwxr-xr-xscript/delete-old-sessions1
-rw-r--r--todo.txt5
9 files changed, 99 insertions, 34 deletions
diff --git a/app/controllers/application.rb b/app/controllers/application.rb
index dd762480c..4c3f6e114 100644
--- a/app/controllers/application.rb
+++ b/app/controllers/application.rb
@@ -6,23 +6,59 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
-# $Id: application.rb,v 1.48 2008-06-10 15:12:02 francis Exp $
+# $Id: application.rb,v 1.49 2008-06-12 13:43:29 francis Exp $
class ApplicationController < ActionController::Base
- # Standard hearders, footers and navigation for whole site
+ # Standard headers, footers and navigation for whole site
layout "default"
- # Pick a unique cookie name to distinguish our session data from others'
- session :session_key => '_foi_session_id'
+ # Set cookie expiry according to "remember me" checkbox, as per "An easier
+ # and more flexible hack" on this page:
+ # http://wiki.rubyonrails.org/rails/pages/HowtoChangeSessionOptions
+ before_filter :session_remember_me
+ def session_remember_me
+ # Reset the "sliding window" session expiry time.
+ if session[:remember_me]
+ expire_time = 1.month.from_now
+ # "Why is session[:force_new_cookie] set to Time.now? In order for the “sliding window”
+ # concept to work, a fresh cookie must be sent with every response. Rails only
+ # sends a cookie when the session data has changed so using a value like Time.now
+ # ensures that it changes every time. What I have actually found is that some
+ # internal voodoo causes the session data to change slightly anyway but it’s best
+ # to be sure!"
+ session[:force_new_cookie] = Time.now
+ else
+ expire_time = nil
+ end
+ # if statement here is so test code runs
+ if session.instance_variable_get(:@dbman)
+ session.instance_variable_get(:@dbman).instance_variable_get(:@cookie_options)['expires'] = expire_time
+ end
+ end
- # Override default error handler
+ # Override default error handler, for production sites.
def rescue_action_in_public(exception)
- # do something based on exception
+ # Make sure expiry time for session is set (before_filters are
+ # otherwise missed by this override)
+ session_remember_me
+
+ # Display user appropriate error message
@exception_backtrace = exception.backtrace.join("\n")
@exception_class = exception.class.to_s
render :template => "general/exception_caught.rhtml", :status => 404
end
+
+ # For development sites.
+ alias original_rescue_action_locally rescue_action_locally
+ def rescue_action_locally(exception)
+ # Make sure expiry time for session is set (before_filters are
+ # otherwise missed by this override)
+ session_remember_me
+
+ # Display default, detailed error for developers
+ original_rescue_action_locally(exception)
+ end
def local_request?
false
@@ -87,8 +123,11 @@ class ApplicationController < ActionController::Base
# Do a POST redirect. This is a nasty hack - we store the posted values in
# the session, and when the GET redirect with "?post_redirect=1" happens,
# load them in.
- def do_post_redirect(uri, params)
- session[:post_redirect_params] = params
+ def do_post_redirect(post_redirect)
+ uri = post_redirect.uri
+
+ session[:post_redirect_token] = post_redirect.token
+
# XXX what is the built in Ruby URI munging function that can do this
# choice of & vs. ? more elegantly than this dumb if statement?
if uri.include?("?")
@@ -110,8 +149,9 @@ class ApplicationController < ActionController::Base
# If we are in a faked redirect to POST request, then set post params.
before_filter :check_in_post_redirect
def check_in_post_redirect
- if params[:post_redirect] and session[:post_redirect_params]
- params.update(session[:post_redirect_params])
+ if params[:post_redirect] and session[:post_redirect_token]
+ post_redirect = PostRedirect.find_by_token(session[:post_redirect_token])
+ params.update(post_redirect.post_params)
end
end
diff --git a/app/controllers/user_controller.rb b/app/controllers/user_controller.rb
index 73fbce9d6..af2f572ba 100644
--- a/app/controllers/user_controller.rb
+++ b/app/controllers/user_controller.rb
@@ -4,7 +4,7 @@
# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
# Email: francis@mysociety.org; WWW: http://www.mysociety.org/
#
-# $Id: user_controller.rb,v 1.46 2008-05-12 10:57:43 francis Exp $
+# $Id: user_controller.rb,v 1.47 2008-06-12 13:43:29 francis Exp $
class UserController < ApplicationController
# Show page about a set of users with same url name
@@ -45,7 +45,8 @@ class UserController < ApplicationController
if @user_signin.email_confirmed
session[:user_id] = @user_signin.id
session[:user_circumstance] = nil
- do_post_redirect @post_redirect.uri, @post_redirect.post_params
+ session[:remember_me] = params[:remember_me] ? true : false
+ do_post_redirect @post_redirect
else
send_confirmation_mail @user_signin
end
@@ -96,7 +97,7 @@ class UserController < ApplicationController
session[:user_id] = @user.id
session[:user_circumstance] = post_redirect.circumstance
- do_post_redirect post_redirect.uri, post_redirect.post_params
+ do_post_redirect post_redirect
end
# Logout form
@@ -166,7 +167,7 @@ class UserController < ApplicationController
flash[:notice] = "Your password has been changed."
if params[:pretoken] and not params[:pretoken].empty?
post_redirect = PostRedirect.find_by_token(params[:pretoken])
- do_post_redirect post_redirect.uri, post_redirect.post_params
+ do_post_redirect post_redirect
else
redirect_to user_url(@user)
end
diff --git a/app/views/user/_signin.rhtml b/app/views/user/_signin.rhtml
index aefcde17e..787773d5a 100644
--- a/app/views/user/_signin.rhtml
+++ b/app/views/user/_signin.rhtml
@@ -19,6 +19,11 @@
<%= link_to "Forgotten your password?", signchange_url + "?pretoken=" + h(params[:token]) %>
</p>
+ <p class="form_note">
+ <%= check_box_tag 'remember_me', "1" %>
+ <label for="remember_me">Remember me</label>
+ </p>
+
<div class="form_button">
<%= hidden_field_tag 'token', params[:token], { :id => 'signin_token' } %>
<%= submit_tag "Sign in" %>
diff --git a/config/environment.rb b/config/environment.rb
index d05981b0d..6418de705 100644
--- a/config/environment.rb
+++ b/config/environment.rb
@@ -19,6 +19,10 @@ load "config.rb"
load "format.rb"
Rails::Initializer.run do |config|
+ # Load intial mySociety config
+ MySociety::Config.set_file(File.join(config.root_path, 'config', 'general'), true)
+ MySociety::Config.load_default
+
# Settings in config/environments/* take precedence over those specified here
# Skip frameworks you're not going to use (only works if using vendor/rails)
@@ -34,9 +38,15 @@ Rails::Initializer.run do |config|
# (by default production uses :info, the others :debug)
# config.log_level = :debug
- # Use the database for sessions instead of the file system
- # (create the session table with 'rake db:sessions:create')
- config.action_controller.session_store = :active_record_store
+ # Your secret key for verifying cookie session data integrity.
+ # If you change this key, all old sessions will become invalid!
+ # Make sure the secret is at least 30 characters and all random,
+ # no regular words or you'll be exposed to dictionary attacks.
+ config.action_controller.session = {
+ :session_key => '_foi_cookie_session',
+ :secret => MySociety::Config.get("COOKIE_STORE_SESSION_SECRET", 'this default is insecure as code is open source, please override for live sites in config/general; this will do for local development'),
+ }
+ config.action_controller.session_store = :cookie_store
# Use SQL instead of Active Record's schema dumper when creating the test database.
# This is necessary if your schema can't be completely dumped by the schema dumper,
@@ -50,10 +60,6 @@ Rails::Initializer.run do |config|
config.active_record.default_timezone = :utc
# See Rails::Configuration for more options
-
- # Load intial mySociety config
- MySociety::Config.set_file(File.join(config.root_path, 'config', 'general'), true)
- MySociety::Config.load_default
end
# Add new inflection rules using the following format
diff --git a/config/general-example b/config/general-example
index d7cd0be5d..2a7a0b140 100644
--- a/config/general-example
+++ b/config/general-example
@@ -19,7 +19,7 @@
* Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved.
* Email: francis@mysociety.org; WWW: http://www.mysociety.org
*
- * $Id: general-example,v 1.14 2008-05-18 23:50:05 francis Exp $
+ * $Id: general-example,v 1.15 2008-06-12 13:43:30 francis Exp $
*
*/
@@ -39,4 +39,7 @@ define('OPTION_CONTACT_EMAIL', 'admin@localhost');
define('OPTION_ADMIN_BASE_URL', '/admin/');
define('OPTION_ADMIN_PUBLIC_URL', '/'); // where /stylesheets sits under for admin pages
+// Secret key for signing cookie_store sessions
+define('OPTION_COOKIE_STORE_SESSION_SECRET', 'your secret key here, make it long and random');
+
?>
diff --git a/db/migrate/058_remove_sessions.rb b/db/migrate/058_remove_sessions.rb
new file mode 100644
index 000000000..316fcfdda
--- /dev/null
+++ b/db/migrate/058_remove_sessions.rb
@@ -0,0 +1,16 @@
+class RemoveSessions < ActiveRecord::Migration
+ def self.up
+ drop_table :sessions
+ end
+
+ def self.down
+ create_table :sessions do |t|
+ t.column :session_id, :string
+ t.column :data, :text
+ t.column :updated_at, :datetime
+ end
+
+ add_index :sessions, :session_id
+ add_index :sessions, :updated_at
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 66758a69c..6c71d1ef0 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -9,7 +9,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 57) do
+ActiveRecord::Schema.define(:version => 58) do
create_table "acts_as_xapian_jobs", :force => true do |t|
t.string "model", :null => false
@@ -118,16 +118,6 @@ ActiveRecord::Schema.define(:version => 57) do
t.text "url_name"
end
- create_table "sessions", :force => true do |t|
- t.string "session_id"
- t.text "data"
- t.datetime "updated_at"
- t.datetime "created_at"
- end
-
- add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
- add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
-
create_table "track_things", :force => true do |t|
t.integer "tracking_user_id", :null => false
t.string "track_query", :null => false
diff --git a/script/delete-old-sessions b/script/delete-old-sessions
index 0e4c91122..c1354e4f4 100755
--- a/script/delete-old-sessions
+++ b/script/delete-old-sessions
@@ -3,6 +3,5 @@
LOC=`dirname $0`
$LOC/runner 'PostRedirect.delete_old_post_redirects()'
-$LOC/runner "ActiveRecord::Base.connection.execute(\"delete from sessions where now() - updated_at > '1 month'\")"
diff --git a/todo.txt b/todo.txt
index 901e56166..a003d6b51 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,3 +1,6 @@
+Cookie:
+ Delete cronjob
+
Site move:
Install PostgresSQL 8.3
Move database
@@ -66,6 +69,8 @@ Needs tagline that v. quickly explains what site is on each page
This one is a word doc by itself:
http://www.whatdotheyknow.com/request/cost_benefit_analysis_for_real_n
+rename delete_old_sessions
+
Later
=====