diff options
-rw-r--r-- | app/controllers/application.rb | 43 | ||||
-rw-r--r-- | app/controllers/frontpage_controller.rb | 10 | ||||
-rw-r--r-- | app/models/user.rb | 58 | ||||
-rw-r--r-- | app/views/frontpage/signin.rhtml | 11 | ||||
-rw-r--r-- | app/views/layouts/default.rhtml | 5 | ||||
-rw-r--r-- | config/routes.rb | 2 | ||||
-rw-r--r-- | db/migrate/001_create_users.rb | 15 | ||||
-rw-r--r-- | db/schema.rb | 14 | ||||
-rw-r--r-- | test/fixtures/users.yml | 5 | ||||
-rw-r--r-- | test/unit/user_test.rb | 10 |
10 files changed, 168 insertions, 5 deletions
diff --git a/app/controllers/application.rb b/app/controllers/application.rb index dcae8385b..e5c6a455b 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -1,7 +1,42 @@ -# Filters added to this controller apply to all controllers in the application. -# Likewise, all the methods added will be available for all controllers. +# controllers/application.rb: +# Parent class of all controllers in FOI site. Filters added to this controller +# apply to all controllers in the application. Likewise, all the methods added +# will be available for all controllers. +# +# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. +# Email: francis@mysociety.org; WWW: http://www.mysociety.org/ +# +# $Id: application.rb,v 1.2 2007-08-01 16:41:32 francis Exp $ + class ApplicationController < ActionController::Base - # Pick a unique cookie name to distinguish our session data from others' - session :session_key => '_foi_session_id' + # Pick a unique cookie name to distinguish our session data from others' + session :session_key => '_foi_session_id' + + def check_authentication + unless session[:user] + session[:intended_action] = action_name + session[:intended_controller] = controller_name + redirect_to :action => "signin" + end + end + + def signin + if request.post? + user = User.authenticate(params[:email], params[:password]) + if user + session[:user] = user.id + redirect_to :action => session[:intended_action], :controller => session[:intended_controller] + else + flash[:notice] = "Email or password not correct" + end + + end + end + + def signout + sessions[:user] = nil + redirect_to frontpage + end + end diff --git a/app/controllers/frontpage_controller.rb b/app/controllers/frontpage_controller.rb index 3eaaf70b6..e52f6c2fe 100644 --- a/app/controllers/frontpage_controller.rb +++ b/app/controllers/frontpage_controller.rb @@ -1,3 +1,11 @@ +# controllers/frontpage_controller.rb: +# Main page of site. +# +# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. +# Email: francis@mysociety.org; WWW: http://www.mysociety.org/ +# +# $Id: frontpage_controller.rb,v 1.2 2007-08-01 16:41:32 francis Exp $ + class FrontpageController < ApplicationController layout "default" @@ -6,5 +14,7 @@ class FrontpageController < ApplicationController format.html end end + + before_filter :check_authentication, :except => [:signin] end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 000000000..2a6b7a31d --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,58 @@ +# models/user.rb: +# Model of people who use the site to file requests, make comments etc. +# +# Copyright (c) 2007 UK Citizens Online Democracy. All rights reserved. +# Email: francis@mysociety.org; WWW: http://www.mysociety.org/ +# +# $Id: user.rb,v 1.1 2007-08-01 16:41:33 francis Exp $ + +require 'digest/sha1' + +class User < ActiveRecord::Base + validates_presence_of :name + + validates_presence_of :email + validates_uniqueness_of :email, :case_sensitive => false + + attr_accessor :password_confirmation + validates_confirmation_of :password + + def validate + errors.add_to_base("Missing password") if hashed_password.blank? + end + + # Return user given login email and password + def self.authenticate(email, password) + user = self.find(:first, :conditions => [ 'email ilike ?', email ] ) + if user + expected_password = encrypted_password(password, user.salt) + if user.hashed_password != expected_password + user = nil + end + end + user + end + + # Virtual password attribute, which stores the hashed password, rather than plain text. + def password + @password + end + def password=(pwd) + @password = pwd + return if pwd.blank? + create_new_salt + self.hashed_password = User.encrypted_password(self.password, self.salt) + end + + private + + def self.encrypted_password(password, salt) + string_to_hash = password + salt # XXX need to add a secret here too? + Digest::SHA1.hexdigest(string_to_hash) + end + + def create_new_salt + self.salt = self.object_id.to_s + rand.to_s + end +end + diff --git a/app/views/frontpage/signin.rhtml b/app/views/frontpage/signin.rhtml new file mode 100644 index 000000000..f66ec4eb0 --- /dev/null +++ b/app/views/frontpage/signin.rhtml @@ -0,0 +1,11 @@ + +<%= start_form_tag :action => "signin" %> + <label for="email">Email:</label> + <%= text_field_tag "email" %> + <br> + <label for="password">Password:</label> + <%= password_field_tag "password" %> + <br> + <%= submit_tag "Sign in" %> +<%= end_form_tag %> + diff --git a/app/views/layouts/default.rhtml b/app/views/layouts/default.rhtml index fd37dfa9e..3181598ba 100644 --- a/app/views/layouts/default.rhtml +++ b/app/views/layouts/default.rhtml @@ -11,6 +11,11 @@ <ul id="navigation"> <li>Home</li> </ul> + + <% if flash[:notice] %> + <div id="notice"><%= flash[:notice] %></div> + <% end %> + <%= yield :layout %> </body> </html> diff --git a/config/routes.rb b/config/routes.rb index 94613f14f..bd1f9cf5d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -22,7 +22,7 @@ ActionController::Routing::Routes.draw do |map| #map.connect ':controller/:action/:id.:format' #map.connect ':controller/:action/:id' - map.connect "/", :controller => 'frontpage' + map.connect "/:action/:id", :controller => 'frontpage' end diff --git a/db/migrate/001_create_users.rb b/db/migrate/001_create_users.rb new file mode 100644 index 000000000..ba528c038 --- /dev/null +++ b/db/migrate/001_create_users.rb @@ -0,0 +1,15 @@ +class CreateUsers < ActiveRecord::Migration + def self.up + create_table :users do |t| + t.column :email, :string + t.column :name, :string + + t.column :hashed_password, :string + t.column :salt, :string + end + end + + def self.down + drop_table :users + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 000000000..32e957c51 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,14 @@ +# This file is autogenerated. Instead of editing this file, please use the +# migrations feature of ActiveRecord to incrementally modify your database, and +# then regenerate this schema definition. + +ActiveRecord::Schema.define(:version => 1) do + + create_table "users", :force => true do |t| + t.column "email", :string + t.column "name", :string + t.column "hashed_password", :string + t.column "salt", :string + end + +end diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 000000000..b49c4eb4e --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,5 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html +one: + id: 1 +two: + id: 2 diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb new file mode 100644 index 000000000..5468f7a2d --- /dev/null +++ b/test/unit/user_test.rb @@ -0,0 +1,10 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class UserTest < Test::Unit::TestCase + fixtures :users + + # Replace this with your real tests. + def test_truth + assert true + end +end |