Skip to content

Commit

Permalink
Save now accepts a block
Browse files Browse the repository at this point in the history
  • Loading branch information
binarylogic committed Nov 20, 2008
1 parent e162fc1 commit e42c8f3
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 43 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.rdoc
Expand Up @@ -4,6 +4,8 @@
* In the session Authlogic now also stores the record id. We use this id to find the record and then check the token against the record, thus allowing for quicker database lookups, while getting the same security.
* Skip validation for reset_perishable_token!
* Added checks for uniqueness validations to only perform if the values have changed, this cuts down on DB queries
* Abstract controller adapter now uses ruby's simple delegator class
* Allow to save with a block: user_session.save { |result| }, result will either be false or self, this is useful when implementing OpenID and other methods

== 1.2.1 released 2008-11-19

Expand Down
26 changes: 2 additions & 24 deletions lib/authlogic/controller_adapters/abstract_adapter.rb
Expand Up @@ -2,41 +2,19 @@ module Authlogic
module ControllerAdapters # :nodoc:
# = Abstract Adapter
# Allows you to use Authlogic in any framework you want, not just rails. See tha RailsAdapter for an example of how to adapter Authlogic to work with your framework.
class AbstractAdapter
attr_accessor :controller

def initialize(controller)
self.controller = controller
end

class AbstractAdapter < SimpleDelegator
def authenticate_with_http_basic(&block)
@auth = Rack::Auth::Basic::Request.new(controller.request.env)
@auth = Rack::Auth::Basic::Request.new(__getobj__.request.env)
if @auth.provided? and @auth.basic?
block.call(*@auth.credentials)
else
false
end
end

def cookies
controller.cookies
end

def params
controller.params
end

def request
controller.request
end

def request_content_type
request.content_type
end

def session
controller.session
end
end
end
end
4 changes: 2 additions & 2 deletions lib/authlogic/controller_adapters/rails_adapter.rb
Expand Up @@ -5,11 +5,11 @@ module ControllerAdapters
# provides. Similar to how ActiveRecord has an adapter for MySQL, PostgreSQL, SQLite, etc.
class RailsAdapter < AbstractAdapter
def authenticate_with_http_basic(&block)
controller.authenticate_with_http_basic(&block)
__getobj__.authenticate_with_http_basic(&block)
end

def cookies
controller.send(:cookies)
__getobj__.send(:cookies)
end

def request_content_type
Expand Down
Expand Up @@ -27,7 +27,7 @@ def acts_as_authentic_with_credentials(options = {})
validates_length_of options[:login_field], :within => 6..100, :allow_blank => options[:allow_blank_login_and_password_fields]
validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message], :allow_blank => options[:allow_blank_login_and_password_fields]
else
validates_length_of options[:login_field], :within => 2..100, :allow_blank => options[:allow_blank_login_and_password_field]
validates_length_of options[:login_field], :within => 2..100, :allow_blank => options[:allow_blank_login_and_password_fields]
validates_format_of options[:login_field], :with => options[:login_field_regex], :message => options[:login_field_regex_failed_message], :allow_blank => options[:allow_blank_login_and_password_fields]
end

Expand Down
25 changes: 17 additions & 8 deletions lib/authlogic/session/base.rb
Expand Up @@ -26,9 +26,9 @@ def controller # :nodoc:
#
# session = UserSession.new
# session.create
def create(*args)
def create(*args, &block)
session = new(*args)
session.save
session.save(&block)
end

# Same as create but calls create!, which raises an exception when authentication fails
Expand Down Expand Up @@ -150,9 +150,9 @@ def credentials
def credentials=(values)
return if values.blank? || !values.is_a?(Hash)
values.symbolize_keys!
[login_field.to_sym, password_field.to_sym, :remember_me].each do |field|
next if values[field].blank?
send("#{field}=", values[field])
values.each do |field, value|
next if value.blank?
send("#{field}=", value)
end
end

Expand Down Expand Up @@ -272,7 +272,8 @@ def remember_me_until
# 2. sets session
# 3. sets cookie
# 4. updates magic fields
def save
def save(&block)
result = nil
if valid?
record.login_count = (record.login_count.blank? ? 1 : record.login_count + 1) if record.respond_to?(:login_count)

Expand All @@ -289,8 +290,13 @@ def save
record.save_without_session_maintenance(false)

self.new_session = false
self
result = self
else
result = false
end

yield result if block_given?
result
end

# Same as save but raises an exception when authentication fails
Expand Down Expand Up @@ -411,6 +417,8 @@ def valid_credentials?
errors.add(password_field, password_invalid_message)
return false
end

self.record = unchecked_record
when :unauthorized_record
unchecked_record = unauthorized_record

Expand All @@ -423,9 +431,10 @@ def valid_credentials?
errors.add_to_base("You can not login with a new record.")
return false
end

self.record = unchecked_record
end

self.record = unchecked_record
true
end

Expand Down
4 changes: 2 additions & 2 deletions lib/authlogic/session/callbacks.rb
Expand Up @@ -49,14 +49,14 @@ def find_record_with_callbacks
# after_save
# before_update # only if new_session? == false
# before_create # only if new_session? == true
def save_with_callbacks
def save_with_callbacks(&block)
run_callbacks(:before_save)
if new_session?
run_callbacks(:before_create)
else
run_callbacks(:before_update)
end
result = save_without_callbacks
result = save_without_callbacks(&block)
if result
run_callbacks(:after_save)

Expand Down
13 changes: 13 additions & 0 deletions lib/authlogic/session/config.rb
Expand Up @@ -45,6 +45,19 @@ def configure
yield self
end

# This works just like ActiveRecord's attr_accessible, except by default this ONLY allows the login, password, and remember me option.
#
# * <tt>Default:</tt> {:login_field}, {:password_field}, :remember_me, set to nil to disable
# * <tt>Accepts:</tt> String
def attr_accessible(*values)
if values.blank?
read_inheritable_attribute(:attr_accessible) || attr_accessible(login_field, password_field, :remember_me)
else
write_inheritable_attribute(:attr_accessible, value)
end
end
alias_method :attr_accessible=, :attr_accessible

# The name of the cookie or the key in the cookies hash. Be sure and use a unique name. If you have multiple sessions and they use the same cookie it will cause problems.
# Also, if a id is set it will be inserted into the beginning of the string. Exmaple:
#
Expand Down
17 changes: 17 additions & 0 deletions lib/authlogic/session/openid.rb
@@ -0,0 +1,17 @@
module Authlogic
module Session
# = Session
#
# Handles all parts of authentication that deal with sessions. Such as persisting a session and saving / destroy a session.
module OpenID
def self.included(klass)
klass.class_eval do
attr_accessor :
alias_method_chain :credentials=, :openid
end
end

# Tries to validate the session from information in the session
def credentials_with_openid=(value)
self.credentials_without_openid
end
23 changes: 17 additions & 6 deletions test/session_tests/base_test.rb
Expand Up @@ -55,10 +55,10 @@ def test_find

assert UserSession.find
last_request_at = ben.reload.last_request_at
sleep(1.5)
sleep(0.5)
assert UserSession.find
assert_equal last_request_at, ben.reload.last_request_at
sleep(1)
sleep(2)
assert UserSession.find
assert_not_equal last_request_at, ben.reload.last_request_at

Expand Down Expand Up @@ -212,19 +212,17 @@ def test_save_with_nothing
assert session.new_session?
end

def test_save_with_record
def test_save_with_credentials
ben = users(:ben)
session = UserSession.new(:login => ben.login, :password => "benrocks")
assert session.save
assert !session.new_session?
assert_equal 1, session.record.login_count
assert Time.now >= session.record.current_login_at
assert_equal "1.1.1.1", session.record.current_login_ip
unset_cookie
unset_session
end

def test_save_with_credentials
def test_save_with_record
ben = users(:ben)
session = UserSession.new(ben)
assert session.save
Expand All @@ -234,6 +232,19 @@ def test_save_with_credentials
assert_equal "1.1.1.1", session.record.current_login_ip
end

def test_save_with_block
ben = users(:ben)
session = UserSession.new(:login => ben.login, :password => "benrocks")
block_result = session.save do |result|
assert result
end
assert_equal session, block_result
assert !session.new_session?
assert_equal 1, session.record.login_count
assert Time.now >= session.record.current_login_at
assert_equal "1.1.1.1", session.record.current_login_ip
end

def test_save_with_bang
session = UserSession.new
assert_raise(Authlogic::Session::SessionInvalid) { session.save! }
Expand Down

1 comment on commit e42c8f3

@sbfaulkner
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

openid.rb looks like a bad commit, or git corruption or something… (I only see the first 17 lines or so)

Please sign in to comment.