Changeset 293
- Timestamp:
- 10/26/08 21:24:52 (2 months ago)
- Files:
-
- trunk/app/controllers/account_controller.rb (deleted)
- trunk/app/controllers/author_controller.rb (modified) (1 diff)
- trunk/app/controllers/sessions_controller.rb (modified) (2 diffs)
- trunk/app/helpers/application_helper.rb (modified) (2 diffs)
- trunk/app/views/shared/_footer.rhtml (modified) (2 diffs)
- trunk/config/environment.rb (modified) (2 diffs)
- trunk/config/initializers/red_cloth.rb (deleted)
- trunk/lib/authenticated_system.rb (modified) (6 diffs)
- trunk/lib/authenticated_test_helper.rb (modified) (1 diff)
- trunk/script/spec (modified) (1 diff)
- trunk/spec/controllers/account_controller_spec.rb (deleted)
- trunk/spec/controllers/author_controller_spec.rb (modified) (1 diff)
- trunk/spec/controllers/meals_controller_spec.rb (modified) (1 diff)
- trunk/spec/controllers/recipes_controller_spec.rb (modified) (1 diff)
- trunk/spec/controllers/sessions_controller_spec.rb (modified) (7 diffs)
- trunk/spec/helpers/application_helper_spec.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/app/controllers/author_controller.rb
r157 r293 30 30 protected 31 31 def authorized? 32 current_user.author?32 logged_in? && current_user.author? 33 33 end 34 34 end trunk/app/controllers/sessions_controller.rb
r263 r293 1 1 # This controller handles the login/logout function of the site. 2 2 class SessionsController < ApplicationController 3 # Be sure to include AuthenticationSystem in Application Controller instead 4 include AuthenticatedSystem 3 layout 'home' 5 4 6 layout 'master' 5 def show 6 if logged_in? && current_user.author? 7 redirect_to(:controller => 'author', :action => 'index') 8 return 9 end 10 redirect_to(:controller => 'home', :action => 'index') 11 end 7 12 8 13 # render new.rhtml … … 40 45 self.current_user.forget_me if logged_in? 41 46 cookies.delete :auth_token 47 cookies.delete :unsafe_login 48 cookies.delete :unsafe_roles 42 49 reset_session 43 50 flash[:notice] = "You have been logged out." 44 redirect_back_or_default('/') 51 redirect_back_or_default(:action => 'interstitial') 52 end 53 54 def interstitial 55 @redirect_delay = 5 56 @redirect_url = url_for(:controller => 'home', :action => 'index') 57 58 if logged_in? && current_user.author? 59 @redirect_url = url_for(:controller => 'author', :action => 'index') 60 end 45 61 end 46 62 end trunk/app/helpers/application_helper.rb
r98 r293 1 #### #1 #### 2 2 # 3 3 # Copyright 2007 Chris Strom, Robin Strom … … 104 104 def wiki(text) 105 105 return nil if text.blank? 106 textilize(wikify(text))106 RedCloth.new(wikify(text)).to_html 107 107 end 108 108 109 109 def wiki_without_paragraph(text) 110 110 return nil if text.blank? 111 wikify( textilize_without_paragraph('xxx '+text)[4..-1])111 wikify(RedCloth.new('xxx '+text, [:lite_mode]).to_html[4..-1]) 112 112 end 113 113 end trunk/app/views/shared/_footer.rhtml
r263 r293 10 10 11 11 <p id="footnote-current-user-container" style="width: 100%; max-width: none; text-align: center; display: none"> 12 <b>Logged in as:</b> <a href="/ account" id="footnote-current-user"></a>13 (<%= link_to('logout', :controller => 'account', :action => 'logout') %>)12 <b>Logged in as:</b> <a href="/session" id="footnote-current-user"></a> 13 (<%= link_to('logout', session_path, :method => 'delete') %>) 14 14 </p> 15 15 <script type="text/javascript"> … … 32 32 33 33 <a href="http://creativecommons.org/licenses/by-nc/1.0/"> 34 < img id="eee-creativecommons-img" alt="Creative Commons License" src="http://creativecommons.org/images/public/somerights.gif" /></a>34 <!-- img id="eee-creativecommons-img" alt="Creative Commons License" src="http://creativecommons.org/images/public/somerights.gif" / --></a> 35 35 <!-- /Creative Commons License --> 36 36 trunk/config/environment.rb
r284 r293 6 6 7 7 # Specifies gem version of Rails to use when vendor/rails is not present 8 RAILS_GEM_VERSION = '2.1. 1' unless defined? RAILS_GEM_VERSION8 RAILS_GEM_VERSION = '2.1.2' unless defined? RAILS_GEM_VERSION 9 9 10 10 # Bootstrap the Rails environment, frameworks, and default configuration … … 26 26 # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net" 27 27 # config.gem "aws-s3", :lib => "aws/s3" 28 config.gem "RedCloth", :version => '>=4.0.4' 28 29 29 30 # Only load the plugins named here, in the order given. By default, all plugins trunk/lib/authenticated_system.rb
r147 r293 4 4 # Preloads @current_user with the user model if they're logged in. 5 5 def logged_in? 6 current_user != :false6 !!current_user 7 7 end 8 8 9 # Accesses the current user from the session. 9 # Accesses the current user from the session. 10 # Future calls avoid the database because nil is not equal to false. 10 11 def current_user 11 @current_user ||= ( session[:user] && User.find_by_id(session[:user])) || :false12 @current_user ||= (login_from_session || login_from_basic_auth || login_from_cookie) unless @current_user == false 12 13 end 13 14 14 # Store the given user i n the session.15 # Store the given user id in the session. 15 16 def current_user=(new_user) 16 session[:user ] = (new_user.nil? || new_user.is_a?(Symbol)) ? nil : new_user.id17 @current_user = new_user 17 session[:user_id] = new_user ? new_user.id : nil 18 @current_user = new_user || false 18 19 end 19 20 20 # Check if the user is authorized .21 # Check if the user is authorized 21 22 # 22 23 # Override this method in your controllers if you want to restrict access … … 27 28 # 28 29 # # only allow nonbobs 29 # def authorize ?30 # def authorized? 30 31 # current_user.login != "bob" 31 32 # end 32 33 def authorized? 33 true34 logged_in? 34 35 end 35 36 … … 49 50 # 50 51 def login_required 51 username, passwd = get_auth_data 52 self.current_user ||= User.authenticate(username, passwd) || :false if username && passwd 53 logged_in? && authorized? ? true : access_denied 52 authorized? || access_denied 54 53 end 55 54 … … 63 62 # simply close itself. 64 63 def access_denied 65 respond_to do | accepts|66 accepts.html do64 respond_to do |format| 65 format.html do 67 66 store_location 68 redirect_to :controller => '/account', :action => 'login'67 redirect_to new_session_path 69 68 end 70 accepts.xml do 71 headers["Status"] = "Unauthorized" 72 headers["WWW-Authenticate"] = %(Basic realm="Web Password") 73 render :text => "Could't authenticate you", :status => '401 Unauthorized' 69 format.any do 70 request_http_basic_authentication 'Web Password' 74 71 end 75 72 end 76 false77 73 end 78 74 … … 87 83 # to the passed default. 88 84 def redirect_back_or_default(default) 89 session[:return_to] ? redirect_to(session[:return_to]) : redirect_to(default)85 redirect_to(session[:return_to] || default) 90 86 session[:return_to] = nil 91 87 end … … 97 93 end 98 94 99 # When called with before_filter :login_from_cookie will check for an :auth_token 100 # cookie and log the user back in if apropriate 101 def login_from_cookie 102 return unless cookies[:auth_token] && !logged_in? 103 user = User.find_by_remember_token(cookies[:auth_token]) 104 if user && user.remember_token? 105 user.remember_me 106 self.current_user = user 107 cookies[:auth_token] = { :value => self.current_user.remember_token , :expires => self.current_user.remember_token_expires_at } 108 cookies[:login] = { :value => self.current_user.login, :expires => self.current_user.remember_token_expires_at } 109 cookies[:roles] = { :value => self.current_user.roles.join(" "), :expires => self.current_user.remember_token_expires_at } 110 flash[:notice] = "Logged in successfully" 95 # Called from #current_user. First attempt to login by the user id stored in the session. 96 def login_from_session 97 self.current_user = User.find_by_id(session[:user_id]) if session[:user_id] 98 end 99 100 # Called from #current_user. Now, attempt to login by basic authentication information. 101 def login_from_basic_auth 102 authenticate_with_http_basic do |username, password| 103 self.current_user = User.authenticate(username, password) 111 104 end 112 105 end 113 106 114 private115 @@http_auth_headers = %w(X-HTTP_AUTHORIZATION HTTP_AUTHORIZATION Authorization)116 # gets BASIC auth info117 def get_auth_data118 auth_key = @@http_auth_headers.detect { |h| request.env.has_key?(h)}119 auth_data = request.env[auth_key].to_s.split unless auth_key.blank?120 return auth_data && auth_data[0] == 'Basic' ? Base64.decode64(auth_data[1]).split(':')[0..1] : [nil, nil]107 # Called from #current_user. Finaly, attempt to login by an expiring token in the cookie. 108 def login_from_cookie 109 user = cookies[:auth_token] && User.find_by_remember_token(cookies[:auth_token]) 110 if user && user.remember_token? 111 cookies[:auth_token] = { :value => user.remember_token, :expires => user.remember_token_expires_at } 112 self.current_user = user 113 end 121 114 end 122 115 end trunk/lib/authenticated_test_helper.rb
r1 r293 2 2 # Sets the current user in the session from the user fixtures. 3 3 def login_as(user) 4 @request.session[:user] = user ? users(user).id : nil 5 end 6 7 def content_type(type) 8 @request.env['Content-Type'] = type 9 end 10 11 def accept(accept) 12 @request.env["HTTP_ACCEPT"] = accept 4 @request.session[:user_id] = user ? user.id : nil 13 5 end 14 6 15 7 def authorize_as(user) 16 if user 17 @request.env["HTTP_AUTHORIZATION"] = "Basic #{Base64.encode64("#{users(user).login}:test")}" 18 accept 'application/xml' 19 content_type 'application/xml' 20 else 21 @request.env["HTTP_AUTHORIZATION"] = nil 22 accept nil 23 content_type nil 24 end 25 end 26 27 # http://project.ioni.st/post/217#post-217 28 # 29 # def test_new_publication 30 # assert_difference(Publication, :count) do 31 # post :create, :publication => {...} 32 # # ... 33 # end 34 # end 35 # 36 def assert_difference(object, method = nil, difference = 1) 37 initial_value = object.send(method) 38 yield 39 assert_equal initial_value + difference, object.send(method), "#{object}##{method}" 40 end 41 42 def assert_no_difference(object, method, &block) 43 assert_difference object, method, 0, &block 44 end 45 46 # Assert the block redirects to the login 47 # 48 # assert_requires_login(:bob) { |c| c.get :edit, :id => 1 } 49 # 50 def assert_requires_login(login = nil) 51 yield HttpLoginProxy.new(self, login) 52 end 53 54 def assert_http_authentication_required(login = nil) 55 yield XmlLoginProxy.new(self, login) 56 end 57 58 def reset!(*instance_vars) 59 instance_vars = [:controller, :request, :response] unless instance_vars.any? 60 instance_vars.collect! { |v| "@#{v}".to_sym } 61 instance_vars.each do |var| 62 instance_variable_set(var, instance_variable_get(var).class.new) 63 end 8 @request.env["HTTP_AUTHORIZATION"] = user ? ActionController::HttpAuthentication::Basic.encode_credentials(user.login, 'test') : nil 64 9 end 65 10 end 66 67 class BaseLoginProxy68 attr_reader :controller69 attr_reader :options70 def initialize(controller, login)71 @controller = controller72 @login = login73 end74 75 private76 def authenticated77 raise NotImplementedError78 end79 80 def check81 raise NotImplementedError82 end83 84 def method_missing(method, *args)85 @controller.reset!86 authenticate87 @controller.send(method, *args)88 check89 end90 end91 92 class HttpLoginProxy < BaseLoginProxy93 protected94 def authenticate95 @controller.login_as @login if @login96 end97 98 def check99 @controller.assert_redirected_to :controller => 'account', :action => 'login'100 end101 end102 103 class XmlLoginProxy < BaseLoginProxy104 protected105 def authenticate106 @controller.accept 'application/xml'107 @controller.authorize_as @login if @login108 end109 110 def check111 @controller.assert_response 401112 end113 endtrunk/script/spec
r245 r293 1 1 #!/usr/bin/env ruby 2 $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../vendor/plugins/rspec/lib")) 2 require 'rubygems' 3 3 require 'spec' 4 4 exit ::Spec::Runner::CommandLine.run(::Spec::Runner::OptionParser.parse(ARGV, STDERR, STDOUT)) trunk/spec/controllers/author_controller_spec.rb
r159 r293 46 46 47 47 get 'index' 48 response.should redirect_to( :controller => '/account', :action => 'login')48 response.should redirect_to(new_session_url) 49 49 end 50 50 trunk/spec/controllers/meals_controller_spec.rb
r233 r293 293 293 it "should be authorized if the current user is an author" do 294 294 @user.should_receive(:author?).and_return(false) 295 @controller.should_receive(:logged_in?).and_return(true) 295 296 296 post 'update', :id => 7, :meal => { :foo => "bar" } 297 response.should redirect_to( :controller => '/account', :action => 'login')297 response.should redirect_to(new_session_url) 298 298 end 299 299 end trunk/spec/controllers/recipes_controller_spec.rb
r211 r293 315 315 it "should be authorized if the current user is an author" do 316 316 @user.should_receive(:author?).and_return(false) 317 @controller.should_receive(:logged_in?).and_return(true)318 317 319 318 post 'update', :id => 7, :recipe => { :foo => "bar" } 320 response.should redirect_to( :controller => '/account', :action => 'login')319 response.should redirect_to(new_session_url) 321 320 end 322 321 end trunk/spec/controllers/sessions_controller_spec.rb
r264 r293 6 6 7 7 describe SessionsController do 8 fixtures :users 8 before(:each) do 9 @user = User.create(:login => 'quentin', 10 :email => 'nospam@eeecooks.com', 11 :password => 'test', 12 :password_confirmation => 'test') 13 end 9 14 10 15 it 'logins and redirects' do … … 21 26 22 27 it 'logs out' do 23 login_as :quentin28 login_as @user 24 29 get :destroy 25 30 session[:user_id].should be_nil … … 38 43 39 44 it 'deletes token on logout' do 40 login_as :quentin45 login_as @user 41 46 get :destroy 42 47 response.cookies["auth_token"].should == [] … … 44 49 45 50 it 'logs in with cookie' do 46 users(:quentin).remember_me47 request.cookies["auth_token"] = cookie_for( :quentin)51 @user.remember_me 52 request.cookies["auth_token"] = cookie_for(@user) 48 53 get :new 49 54 controller.send(:logged_in?).should be_true … … 51 56 52 57 it 'fails expired cookie login' do 53 users(:quentin).remember_me54 users(:quentin).update_attribute :remember_token_expires_at, 5.minutes.ago55 request.cookies["auth_token"] = cookie_for( :quentin)58 @user.remember_me 59 @user.update_attribute :remember_token_expires_at, 5.minutes.ago 60 request.cookies["auth_token"] = cookie_for(@user) 56 61 get :new 57 62 controller.send(:logged_in?).should_not be_true … … 59 64 60 65 it 'fails cookie login' do 61 users(:quentin).remember_me66 @user.remember_me 62 67 request.cookies["auth_token"] = auth_token('invalid_auth_token') 63 68 get :new … … 70 75 71 76 def cookie_for(user) 72 auth_token user s(user).remember_token77 auth_token user.remember_token 73 78 end 74 79 end trunk/spec/helpers/application_helper_spec.rb
r288 r293 131 131 it "should do wiki by wikifying, then textilizing" do 132 132 helper.should_receive(:wikify).with('text').and_return('wikified text') 133 helper.should_receive(:textilize).with('wikified text').and_return('textilized, wikified text') 134 helper.wiki('text').should == 'textilized, wikified text' 133 helper.wiki('text').should == '<p>wikified text</p>' 135 134 end 136 135 137 136 it "should do wiki (without paragraph) by textilizing (without paragraph), then wikifying" do 138 helper.should_receive(:textilize_without_paragraph).with('xxx text').and_return('xxx textilized text') 139 helper.should_receive(:wikify).with('textilized text').and_return('wikified, textilized text') 137 helper.should_receive(:wikify).with('text').and_return('wikified, textilized text') 140 138 helper.wiki_without_paragraph('text').should == 'wikified, textilized text' 141 139 end
