From a60a9d56f9808cf30a8489060f5b3d7b2ff241d9 Mon Sep 17 00:00:00 2001 From: Espen Antonsen Date: Fri, 22 May 2009 16:14:07 +0200 Subject: [PATCH] authlogic FTW! --- .../admin/application_controller.rb | 8 - app/controllers/application_controller.rb | 48 ++- app/controllers/user_sessions_controller.rb | 24 ++ app/controllers/users_controller.rb | 36 +++ app/helpers/user_sessions_helper.rb | 2 + app/helpers/users_helper.rb | 2 + app/models/user.rb | 3 + app/models/user_session.rb | 3 + app/views/user_sessions/new.html.erb | 14 + app/views/users/_form.html.erb | 8 + app/views/users/edit.html.erb | 9 + app/views/users/new.html.erb | 7 + app/views/users/show.html.erb | 32 ++ config/environment.rb | 6 +- config/routes.rb | 8 + db/migrate/20090522131931_create_users.rb | 26 ++ db/schema.rb | 20 +- public/index.html | 275 ------------------ test/fixtures/users.yml | 7 + test/functional/sessions_controller_test.rb | 82 ++++++ .../user_sessions_controller_test.rb | 8 + test/functional/users_controller_test.rb | 8 + .../unit/helpers/user_sessions_helper_test.rb | 4 + test/unit/helpers/users_helper_test.rb | 4 + test/unit/user_test.rb | 8 + vendor/plugins/restful_authentication | 1 - 26 files changed, 356 insertions(+), 297 deletions(-) delete mode 100644 app/controllers/admin/application_controller.rb create mode 100644 app/controllers/user_sessions_controller.rb create mode 100644 app/controllers/users_controller.rb create mode 100644 app/helpers/user_sessions_helper.rb create mode 100644 app/helpers/users_helper.rb create mode 100644 app/models/user.rb create mode 100644 app/models/user_session.rb create mode 100644 app/views/user_sessions/new.html.erb create mode 100644 app/views/users/_form.html.erb create mode 100644 app/views/users/edit.html.erb create mode 100644 app/views/users/new.html.erb create mode 100644 app/views/users/show.html.erb create mode 100644 db/migrate/20090522131931_create_users.rb delete mode 100644 public/index.html create mode 100644 test/fixtures/users.yml create mode 100644 test/functional/sessions_controller_test.rb create mode 100644 test/functional/user_sessions_controller_test.rb create mode 100644 test/functional/users_controller_test.rb create mode 100644 test/unit/helpers/user_sessions_helper_test.rb create mode 100644 test/unit/helpers/users_helper_test.rb create mode 100644 test/unit/user_test.rb delete mode 160000 vendor/plugins/restful_authentication diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb deleted file mode 100644 index 86e53dd..0000000 --- a/app/controllers/admin/application_controller.rb +++ /dev/null @@ -1,8 +0,0 @@ -class Admin::ApplicationController < ApplicationController - - - protected - - before_filter :login_required - -end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 438939a..99ba92a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -5,16 +5,44 @@ class ApplicationController < ActionController::Base helper :all # include all helpers, all the time protect_from_forgery # See ActionController::RequestForgeryProtection for details - # Scrub sensitive parameters from your log - # filter_parameter_logging :password - - protected + filter_parameter_logging :password, :password_confirmation + helper_method :current_user, :current_user_session - def set_current_person - @current_user = session[:user] - end + private + def current_user_session + return @current_user_session if defined?(@current_user_session) + @current_user_session = UserSession.find + end - def login_required - redirect_to(login_path) unless @current_user - end + def current_user + return @current_user if defined?(@current_user) + @current_user = current_user_session && current_user_session.user + end + + def require_user + unless current_user + store_location + flash[:notice] = "You must be logged in to access this page" + redirect_to new_user_session_url + return false + end + end + + def require_no_user + if current_user + store_location + flash[:notice] = "You must be logged out to access this page" + redirect_to account_url + return false + end + end + + def store_location + session[:return_to] = request.request_uri + end + + def redirect_back_or_default(default) + redirect_to(session[:return_to] || default) + session[:return_to] = nil + end end diff --git a/app/controllers/user_sessions_controller.rb b/app/controllers/user_sessions_controller.rb new file mode 100644 index 0000000..18ea2c7 --- /dev/null +++ b/app/controllers/user_sessions_controller.rb @@ -0,0 +1,24 @@ +class UserSessionsController < ApplicationController + before_filter :require_no_user, :only => [:new, :create] + before_filter :require_user, :only => :destroy + + def new + @user_session = UserSession.new + end + + def create + @user_session = UserSession.new(params[:user_session]) + if @user_session.save + flash[:notice] = "Login successful!" + redirect_back_or_default account_url + else + render :action => :new + end + end + + def destroy + current_user_session.destroy + flash[:notice] = "Logout successful!" + redirect_back_or_default new_user_session_url + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..ab9dafd --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,36 @@ +class UsersController < ApplicationController + before_filter :require_no_user, :only => [:new, :create] + before_filter :require_user, :only => [:show, :edit, :update] + + def new + @user = User.new + end + + def create + @user = User.new(params[:user]) + if @user.save + flash[:notice] = "Account registered!" + redirect_back_or_default account_url + else + render :action => :new + end + end + + def show + @user = @current_user + end + + def edit + @user = @current_user + end + + def update + @user = @current_user # makes our views "cleaner" and more consistent + if @user.update_attributes(params[:user]) + flash[:notice] = "Account updated!" + redirect_to account_url + else + render :action => :edit + end + end +end diff --git a/app/helpers/user_sessions_helper.rb b/app/helpers/user_sessions_helper.rb new file mode 100644 index 0000000..2018402 --- /dev/null +++ b/app/helpers/user_sessions_helper.rb @@ -0,0 +1,2 @@ +module UserSessionsHelper +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 0000000..2310a24 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..04c7d17 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,3 @@ +class User < ActiveRecord::Base + acts_as_authentic +end diff --git a/app/models/user_session.rb b/app/models/user_session.rb new file mode 100644 index 0000000..e7556cb --- /dev/null +++ b/app/models/user_session.rb @@ -0,0 +1,3 @@ +class UserSession < Authlogic::Session::Base + # configuration here, see documentation for sub modules of Authlogic::Session +end \ No newline at end of file diff --git a/app/views/user_sessions/new.html.erb b/app/views/user_sessions/new.html.erb new file mode 100644 index 0000000..55e66b6 --- /dev/null +++ b/app/views/user_sessions/new.html.erb @@ -0,0 +1,14 @@ +

Login

+ +<% form_for @user_session, :url => user_session_path do |f| %> + <%= f.error_messages %> + <%= f.label :email %>
+ <%= f.text_field :email %>
+
+ <%= f.label :password %>
+ <%= f.password_field :password %>
+
+ <%= f.check_box :remember_me %><%= f.label :remember_me %>
+
+ <%= f.submit "Login" %> +<% end %> \ No newline at end of file diff --git a/app/views/users/_form.html.erb b/app/views/users/_form.html.erb new file mode 100644 index 0000000..77e8551 --- /dev/null +++ b/app/views/users/_form.html.erb @@ -0,0 +1,8 @@ +<%= form.label :email %>
+<%= form.text_field :email %>
+
+<%= form.label :password, form.object.new_record? ? nil : "Change password" %>
+<%= form.password_field :password %>
+
+<%= form.label :password_confirmation %>
+<%= form.password_field :password_confirmation %>
\ No newline at end of file diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb new file mode 100644 index 0000000..40a466f --- /dev/null +++ b/app/views/users/edit.html.erb @@ -0,0 +1,9 @@ +

Edit My Account

+ +<% form_for @user, :url => account_path do |f| %> + <%= f.error_messages %> + <%= render :partial => "form", :object => f %> + <%= f.submit "Update" %> +<% end %> + +
<%= link_to "My Profile", account_path %> \ No newline at end of file diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb new file mode 100644 index 0000000..baf4146 --- /dev/null +++ b/app/views/users/new.html.erb @@ -0,0 +1,7 @@ +

Register

+ +<% form_for @user, :url => account_path do |f| %> + <%= f.error_messages %> + <%= render :partial => "form", :object => f %> + <%= f.submit "Register" %> +<% end %> \ No newline at end of file diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb new file mode 100644 index 0000000..694b3ed --- /dev/null +++ b/app/views/users/show.html.erb @@ -0,0 +1,32 @@ +

+ Login count: + <%=h @user.login_count %> +

+ +

+ Last request at: + <%=h @user.last_request_at %> +

+ +

+ Last login at: + <%=h @user.last_login_at %> +

+ +

+ Current login at: + <%=h @user.current_login_at %> +

+ +

+ Last login ip: + <%=h @user.last_login_ip %> +

+ +

+ Current login ip: + <%=h @user.current_login_ip %> +

+ + +<%= link_to 'Edit', edit_account_path %> \ No newline at end of file diff --git a/config/environment.rb b/config/environment.rb index ccad8b1..ba6ae65 100644 --- a/config/environment.rb +++ b/config/environment.rb @@ -6,8 +6,12 @@ RAILS_GEM_VERSION = '2.3.2' unless defined? RAILS_GEM_VERSION # Bootstrap the Rails environment, frameworks, and default configuration require File.join(File.dirname(__FILE__), 'boot') + Rails::Initializer.run do |config| + config.gem "authlogic" + #config.gem "image_science" + config.time_zone = 'Copenhagen' config.i18n.default_locale = 'no-NB' @@ -25,6 +29,4 @@ Rails::Initializer.run do |config| :user_name => "espen@inspired.no", :password => "tkg5megmeg" } - - #config.gem "image_science" end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 6f92161..6fef8fd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,14 @@ ActionController::Routing::Routes.draw do |map| + map.resources :users + map.resource :user_session + map.resource :account, :controller => "users" + map.login "login", :controller => "user_sessions", :action => "new" + map.logout "logout", :controller => "user_sessions", :action => "destroy" map.resources :photos map.resources :albums #map.connect ':controller/:action/:id' #map.connect ':controller/:action/:id.:format' + + map.root :controller => "user_sessions", :action => "new" # optional, this just sets the root route + end diff --git a/db/migrate/20090522131931_create_users.rb b/db/migrate/20090522131931_create_users.rb new file mode 100644 index 0000000..d18f33b --- /dev/null +++ b/db/migrate/20090522131931_create_users.rb @@ -0,0 +1,26 @@ +class CreateUsers < ActiveRecord::Migration + def self.up + create_table :users do |t| + t.string :email, :null => false # optional, you can use login instead, or both + t.string :crypted_password, :null => false # optional, see below + t.string :password_salt, :null => false # optional, but highly recommended + t.string :persistence_token, :null => false # required + t.string :single_access_token, :null => false # optional, see Authlogic::Session::Params + t.string :perishable_token, :null => false # optional, see Authlogic::Session::Perishability + + # Magic columns, just like ActiveRecord's created_at and updated_at. These are automatically maintained by Authlogic if they are present. + t.integer :login_count, :null => false, :default => 0 # optional, see Authlogic::Session::MagicColumns + t.integer :failed_login_count, :null => false, :default => 0 # optional, see Authlogic::Session::MagicColumns + t.datetime :last_request_at # optional, see Authlogic::Session::MagicColumns + t.datetime :current_login_at # optional, see Authlogic::Session::MagicColumns + t.datetime :last_login_at # optional, see Authlogic::Session::MagicColumns + t.string :current_login_ip # optional, see Authlogic::Session::MagicColumns + t.string :last_login_ip # optional, see Authlogic::Session::MagicColumns + t.timestamps + end + end + + def self.down + drop_table :users + end +end diff --git a/db/schema.rb b/db/schema.rb index ee15190..25613bd 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 => 20090520230047) do +ActiveRecord::Schema.define(:version => 20090522131931) do create_table "albums", :force => true do |t| t.string "title", :null => false @@ -28,4 +28,22 @@ ActiveRecord::Schema.define(:version => 20090520230047) do t.text "path" end + create_table "users", :force => true do |t| + t.string "email", :null => false + t.string "crypted_password", :null => false + t.string "password_salt", :null => false + t.string "persistence_token", :null => false + t.string "single_access_token", :null => false + t.string "perishable_token", :null => false + t.integer "login_count", :default => 0, :null => false + t.integer "failed_login_count", :default => 0, :null => false + t.datetime "last_request_at" + t.datetime "current_login_at" + t.datetime "last_login_at" + t.string "current_login_ip" + t.string "last_login_ip" + t.datetime "created_at" + t.datetime "updated_at" + end + end diff --git a/public/index.html b/public/index.html deleted file mode 100644 index 0dd5189..0000000 --- a/public/index.html +++ /dev/null @@ -1,275 +0,0 @@ - - - - - Ruby on Rails: Welcome aboard - - - - - - -
- - -
- - - - -
-

Getting started

-

Here’s how to get rolling:

- -
    -
  1. -

    Use script/generate to create your models and controllers

    -

    To see all available options, run it without parameters.

    -
  2. - -
  3. -

    Set up a default route and remove or rename this file

    -

    Routes are set up in config/routes.rb.

    -
  4. - -
  5. -

    Create your database

    -

    Run rake db:migrate to create your database. If you're not using SQLite (the default), edit config/database.yml with your username and password.

    -
  6. -
-
-
- - -
- - \ No newline at end of file diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..5bf0293 --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,7 @@ +# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html + +# one: +# column: value +# +# two: +# column: value diff --git a/test/functional/sessions_controller_test.rb b/test/functional/sessions_controller_test.rb new file mode 100644 index 0000000..e53bcd8 --- /dev/null +++ b/test/functional/sessions_controller_test.rb @@ -0,0 +1,82 @@ +require File.dirname(__FILE__) + '/../test_helper' +require 'sessions_controller' + +# Re-raise errors caught by the controller. +class SessionsController; def rescue_action(e) raise e end; end + +class SessionsControllerTest < ActionController::TestCase + # Be sure to include AuthenticatedTestHelper in test/test_helper.rb instead + # Then, you can remove it from this and the units test. + include AuthenticatedTestHelper + + fixtures :users + + def test_should_login_and_redirect + post :create, :login => 'quentin', :password => 'monkey' + assert session[:user_id] + assert_response :redirect + end + + def test_should_fail_login_and_not_redirect + post :create, :login => 'quentin', :password => 'bad password' + assert_nil session[:user_id] + assert_response :success + end + + def test_should_logout + login_as :quentin + get :destroy + assert_nil session[:user_id] + assert_response :redirect + end + + def test_should_remember_me + @request.cookies["auth_token"] = nil + post :create, :login => 'quentin', :password => 'monkey', :remember_me => "1" + assert_not_nil @response.cookies["auth_token"] + end + + def test_should_not_remember_me + @request.cookies["auth_token"] = nil + post :create, :login => 'quentin', :password => 'monkey', :remember_me => "0" + puts @response.cookies["auth_token"] + assert @response.cookies["auth_token"].blank? + end + + def test_should_delete_token_on_logout + login_as :quentin + get :destroy + assert @response.cookies["auth_token"].blank? + end + + def test_should_login_with_cookie + users(:quentin).remember_me + @request.cookies["auth_token"] = cookie_for(:quentin) + get :new + assert @controller.send(:logged_in?) + end + + def test_should_fail_expired_cookie_login + users(:quentin).remember_me + users(:quentin).update_attribute :remember_token_expires_at, 5.minutes.ago + @request.cookies["auth_token"] = cookie_for(:quentin) + get :new + assert !@controller.send(:logged_in?) + end + + def test_should_fail_cookie_login + users(:quentin).remember_me + @request.cookies["auth_token"] = auth_token('invalid_auth_token') + get :new + assert !@controller.send(:logged_in?) + end + + protected + def auth_token(token) + CGI::Cookie.new('name' => 'auth_token', 'value' => token) + end + + def cookie_for(user) + auth_token users(user).remember_token + end +end diff --git a/test/functional/user_sessions_controller_test.rb b/test/functional/user_sessions_controller_test.rb new file mode 100644 index 0000000..5024b23 --- /dev/null +++ b/test/functional/user_sessions_controller_test.rb @@ -0,0 +1,8 @@ +require 'test_helper' + +class UserSessionsControllerTest < ActionController::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb new file mode 100644 index 0000000..c3db123 --- /dev/null +++ b/test/functional/users_controller_test.rb @@ -0,0 +1,8 @@ +require 'test_helper' + +class UsersControllerTest < ActionController::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end diff --git a/test/unit/helpers/user_sessions_helper_test.rb b/test/unit/helpers/user_sessions_helper_test.rb new file mode 100644 index 0000000..20dabdf --- /dev/null +++ b/test/unit/helpers/user_sessions_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class UserSessionsHelperTest < ActionView::TestCase +end diff --git a/test/unit/helpers/users_helper_test.rb b/test/unit/helpers/users_helper_test.rb new file mode 100644 index 0000000..96af37a --- /dev/null +++ b/test/unit/helpers/users_helper_test.rb @@ -0,0 +1,4 @@ +require 'test_helper' + +class UsersHelperTest < ActionView::TestCase +end diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb new file mode 100644 index 0000000..a64d2d3 --- /dev/null +++ b/test/unit/user_test.rb @@ -0,0 +1,8 @@ +require 'test_helper' + +class UserTest < ActiveSupport::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end diff --git a/vendor/plugins/restful_authentication b/vendor/plugins/restful_authentication deleted file mode 160000 index 7235d91..0000000 --- a/vendor/plugins/restful_authentication +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 7235d9150e8beb80a819923a4c871ef4069c6759