Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Released v0.10.3

  • Loading branch information...
commit fcdc644cfd9bcfa0b9231970628423a8dc819cfd 1 parent a03f931
@binarylogic binarylogic authored
View
3  CHANGELOG.rdoc
@@ -1,9 +1,10 @@
-== 0.10.3 released 2008-10-29
+== 0.10.3 released 2008-10-31
* Instead of raising an error when extra fields are passed in credentials=, just ignore them.
* Added remember_me config option to set the default value.
* Only call credential methods if an argument was passed.
* More unit tests
+* Hardened automatic session updating. Also automatically log the user in if they change their password when logged out.
== 0.10.2 released 2008-10-24
View
73 lib/authgasm/acts_as_authentic.rb
@@ -31,7 +31,7 @@ module ClassMethods
# user.password= Method name based on the :password_field option. This is used to set the password. Pass the *raw* password to this.
# user.confirm_password= Confirms the password, needed to change the password.
# user.valid_password?(pass) Determines if the password passed is valid. The password could be encrypted or raw.
- # user.randomize_password! Basically resets the password to a random password using only letters and numbers.
+ # user.reset_password! Basically resets the password to a random password using only letters and numbers.
# user.logged_in? Based on the :logged_in_timeout option. Tells you if the user is logged in or not.
# user.forget! Changes their remember token, making their cookie and session invalid. A way to log the user out withouth changing their password.
#
@@ -94,9 +94,8 @@ def acts_as_authentic(options = {})
named_scope :logged_out, lambda { {:conditions => ["last_request_at <= ?", options[:logged_in_timeout].ago]} }
end
- after_create :create_sessions!
- before_update :find_my_sessions
- after_update :update_sessions!
+ before_save :get_session_information, :if => :update_sessions?
+ after_save :maintain_sessions!, :if => :update_sessions?
# Attributes
attr_writer "confirm_#{options[:password_field]}"
@@ -176,63 +175,75 @@ def crypto_provider
end
def forget!
- update_attribute(:#{options[:remember_token_field]}, self.class.unique_token)
+ self.#{options[:remember_token_field]} = self.class.unique_token
+ save_without_session_maintenance(false)
end
- def randomize_#{options[:password_field]}!
+ def reset_#{options[:password_field]}!
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
newpass = ""
1.upto(10) { |i| newpass << chars[rand(chars.size-1)] }
self.#{options[:password_field]} = newpass
self.confirm_#{options[:password_field]} = newpass
- save(false)
+ save_without_session_maintenance(false)
end
+ alias_method :randomize_password!, :reset_password!
- def save_from_session(*args)
- @saving_from_session = true
+ def save_without_session_maintenance(*args)
+ @skip_session_maintenance = true
result = save(*args)
- @saving_from_session = false
+ @skip_session_maintenance = false
result
end
protected
- def create_sessions!
- return if !#{options[:session_class]}.activated? || #{options[:session_ids].inspect}.blank?
+ def update_sessions?
+ !@skip_session_maintenance && #{options[:session_class]}.activated? && !#{options[:session_ids].inspect}.blank? && #{options[:remember_token_field]}_changed?
+ end
+
+ def get_session_information
+ # Need to determine if we are completely logged out, or logged in as another user
+ @_sessions = []
+ @_logged_out = true
+ #{options[:session_ids].inspect}.each do |session_id|
+ session = #{options[:session_class]}.find(*[session_id].compact)
+ if session
+ if !session.record.blank?
+ @_logged_out = false
+ @_sessions << session if session.record == self
+ end
+ end
+ end
+ end
+
+ def maintain_sessions!
+ if @_logged_out
+ create_session!
+ elsif !@_sessions.blank?
+ update_sessions!
+ end
+ end
+
+ def create_session!
# We only want to automatically login into the first session, since this is the main session. The other sessions are sessions
# that need to be created after logging into the main session.
session_id = #{options[:session_ids].inspect}.first
# If we are already logged in, ignore this completely. All that we care about is updating ourself.
next if #{options[:session_class]}.find(*[session_id].compact)
-
+
# Log me in
args = [self, session_id].compact
#{options[:session_class]}.create(*args)
end
- def find_my_sessions
- return if @saving_from_session || !#{options[:session_class]}.activated? || #{options[:session_ids].inspect}.blank?
-
- @my_sessions = []
- #{options[:session_ids].inspect}.each do |session_id|
- session = #{options[:session_class]}.find(*[session_id].compact)
-
- # Ignore if we can't find the session or the session isn't this record
- next if !session || session.record != self
-
- @my_sessions << session
- end
- end
-
def update_sessions!
- return if @saving_from_session || @my_sessions.blank?
-
- @my_sessions.each do |stale_session|
+ # We found sessions above, let's update them with the new info
+ @_sessions.each do |stale_session|
stale_session.unauthorized_record = self
stale_session.save
end
- @my_sessions = nil
end
def tried_to_set_password?
View
4 lib/authgasm/session/base.rb
@@ -54,7 +54,7 @@ def find(id = nil)
if session.send("valid_#{find_method}?")
if session.record.class.column_names.include?("last_request_at")
session.record.last_request_at = Time.now
- session.record.save_from_session(false)
+ session.record.save_without_session_maintenance(false)
end
return session
end
@@ -250,7 +250,7 @@ def save
record.current_login_ip = controller.request.remote_ip
end
- record.save_from_session(false)
+ record.save_without_session_maintenance(false)
self.new_session = false
self
View
2  lib/authgasm/version.rb
@@ -44,7 +44,7 @@ def to_a
MAJOR = 0
MINOR = 10
- TINY = 2
+ TINY = 3
# The current version as a Version instance
CURRENT = new(MAJOR, MINOR, TINY)
View
32 test_app/app/controllers/users_controller.rb
@@ -1,6 +1,7 @@
class UsersController < ApplicationController
before_filter :require_no_user, :only => [:new, :create]
- before_filter :require_user, :only => [:show, :edit, :update]
+ before_filter :require_user, :only => [:edit, :update]
+ before_filter :load_user, :except => [:new, :create]
def new
@user = User.new
@@ -17,11 +18,24 @@ def create
end
def show
- @user = @current_user
+ if @user
+ @user.update_attribute(:profile_views, @user.profile_views + 1) if @user && params[:id]
+ else
+ flash[:notice] = "We're sorry, but no user was found"
+ redirect_to new_user_session_url
+ end
end
- def edit
- @user = @current_user
+ # This is a method created for tests only, to make sure users logged out get logged in when changing passwords
+ def reset_password
+ if @user
+ @user.password = "saweet"
+ @user.confirm_password = "saweet"
+ @user.save
+ else
+ flash[:notice] = "We're sorry, but no user was found"
+ redirect_to new_user_session_url
+ end
end
def update
@@ -34,4 +48,14 @@ def update
render :action => :edit
end
end
+
+ private
+ def load_user
+ if params[:id]
+ @user = User.find_by_id(params[:id])
+ @user.update_attribute(:profile_views, @user.profile_views + 1) if @user
+ else
+ @user = @current_user
+ end
+ end
end
View
18 test_app/app/views/users/show.html.erb
@@ -1,23 +1,29 @@
-<h1><%= @current_user.login %></h1>
+<h1><%= @user.login %></h1>
<table>
<tr>
<td>Login:</td>
- <td><%= @current_user.login %></td>
+ <td><%= @user.login %></td>
</tr>
<tr>
<td>Login count:</td>
- <td><%= @current_user.login_count %></td>
+ <td><%= @user.login_count %></td>
+ </tr>
+ <tr>
+ <td>Profile views:</td>
+ <td><%= @user.profile_views %></td>
</tr>
<tr>
<td>First name:</td>
- <td><%= @current_user.first_name %></td>
+ <td><%= @user.first_name %></td>
</tr>
<tr>
<td>Last name:</td>
- <td><%= @current_user.last_name %></td>
+ <td><%= @user.last_name %></td>
</tr>
</table>
<br />
-<%= link_to "Edit", edit_account_path %><br />
+<% if @user == @current_user %>
+ <%= link_to "Edit", edit_account_path %><br />
+<% end %>
View
1  test_app/config/routes.rb
@@ -1,5 +1,6 @@
ActionController::Routing::Routes.draw do |map|
map.resource :user_session
map.resource :account, :controller => "users"
+ map.resources :users, :member => {:reset_password => :get}
map.default "/", :controller => "user_sessions", :action => "new"
end
View
1  test_app/db/migrate/20081023040052_create_users.rb
@@ -10,6 +10,7 @@ def self.up
t.string :last_name
t.integer :login_count, :null => false, :default => 0
t.datetime :last_request_at
+ t.integer :profile_views, :null => false, :default => 0
end
end
View
44 test_app/test/integration/user_sesion_stories_test.rb
@@ -17,8 +17,8 @@ def test_registration
post account_url, {:user => {:login => "binarylogic", :password => "pass", :confirm_password => "pass", :first_name => "Ben", :last_name => "Johnson"}}
assert_redirected_to account_url
assert flash.key?(:notice)
-
- access_account(User.last)
+
+ assert_account_access(User.last)
end
def test_login_process
@@ -29,9 +29,9 @@ def test_login_process
assert flash.key?(:notice)
assert_template "user_sessions/new"
- login_unsuccessfully
- login_unsuccessfully("bjohnson", "badpassword")
- login_successfully("bjohnson", "benrocks")
+ assert_unsuccessful_login
+ assert_unsuccessful_login("bjohnson", "badpassword")
+ assert_successful_login("bjohnson", "benrocks")
# Try to log in again after a successful login
get new_user_session_url
@@ -47,8 +47,8 @@ def test_login_process
assert flash.key?(:notice)
assert_template "users/show"
- access_account
- logout(new_account_url) # before I tried to register, it stored my location
+ assert_account_access
+ assert_successful_logout(new_account_url) # before I tried to register, it stored my location
# Try to access my account again
get account_url
@@ -58,7 +58,7 @@ def test_login_process
def test_changing_password
# Try logging in with correct credentials
- login_successfully("bjohnson", "benrocks")
+ assert_successful_login("bjohnson", "benrocks")
# Go to edit form
get edit_account_path
@@ -71,15 +71,35 @@ def test_changing_password
assert flash.key?(:notice)
assert_template "users/show"
- access_account
- logout
+ assert_account_access
+ assert_successful_logout
# Try to access my account again
get account_url
assert_redirected_to new_user_session_url
assert flash.key?(:notice)
- login_successfully("bjohnson", "sillywilly")
- access_account
+ assert_successful_login("bjohnson", "sillywilly")
+ assert_account_access
+ end
+
+ def test_updating_user_with_no_password_change
+ ben = users(:ben)
+ profile_views = ben.profile_views
+ assert_no_account_access
+ get user_url(ben)
+ ben.reload
+ assert ben.profile_views > profile_views
+ assert_no_account_access
+ end
+
+ def test_updating_user_with_password_change
+ ben = users(:ben)
+ crypted_password = ben.crypted_password
+ assert_no_account_access
+ get reset_password_user_url(ben)
+ ben.reload
+ assert_not_equal crypted_password, ben.crypted_password
+ assert_account_access
end
end
View
4 test_app/test/integration/user_session_test.rb
@@ -26,7 +26,7 @@ def test_klass_name
def test_find
assert_equal nil, UserSession.find
- login_successfully("bjohnson", "benrocks")
+ assert_successful_login("bjohnson", "benrocks")
assert UserSession.find
end
@@ -139,7 +139,7 @@ def test_new_session
session.save
assert !session.new_session?
- login_successfully("bjohnson", "benrocks")
+ assert_successful_login("bjohnson", "benrocks")
session = UserSession.find
assert !session.new_session?
end
View
33 test_app/test/test_helper.rb
@@ -45,21 +45,32 @@ def teardown
end
private
- def login_successfully(login, password)
+ def assert_successful_login(login, password)
post user_session_url, :user_session => {:login => login, :password => password}
assert_redirected_to account_url
follow_redirect!
assert_template "users/show"
end
- def login_unsuccessfully(login = nil, password = nil)
+ def assert_unsuccessful_login(login = nil, password = nil)
params = (login || password) ? {:user_session => {:login => login, :password => password}} : nil
post user_session_url, params
assert_template "user_sessions/new"
end
+
+ def assert_successful_logout(alt_redirect = nil)
+ redirecting_to = alt_redirect || new_user_session_url
+ delete user_session_url
+ assert_redirected_to redirecting_to # because I tried to access registration above, and it stored it
+ follow_redirect!
+ assert flash.key?(:notice)
+ assert_equal nil, session["user_credentials"]
+ assert_equal "", cookies["user_credentials"]
+ assert_template redirecting_to.gsub("http://www.example.com/", "").gsub("user_session", "user_sessions").gsub("account", "users")
+ end
- def access_account(user = nil)
- user ||= users(:ben)
+ def assert_account_access(user = nil)
+ user ||= users(:ben).reload
# Perform multiple requests to make sure the session is persisting properly, just being anal here
3.times do
get account_url
@@ -69,15 +80,9 @@ def access_account(user = nil)
assert_template "users/show"
end
end
-
- def logout(alt_redirect = nil)
- redirecting_to = alt_redirect || new_user_session_url
- delete user_session_url
- assert_redirected_to redirecting_to # because I tried to access registration above, and it stored it
- follow_redirect!
- assert flash.key?(:notice)
- assert_equal nil, session["user_credentials"]
- assert_equal "", cookies["user_credentials"]
- assert_template redirecting_to.gsub("http://www.example.com/", "").gsub("user_session", "user_sessions").gsub("account", "users")
+
+ def assert_no_account_access(alt_redirect = nil)
+ get account_url
+ assert_redirected_to alt_redirect || new_user_session_url
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.