Skip to content

Commit f19ff3a

Browse files
committed
fix conflicts from merge
2 parents c2eae1c + b8dcc12 commit f19ff3a

File tree

9 files changed

+113
-53
lines changed

9 files changed

+113
-53
lines changed

lib/authlogic/acts_as_authentic/email.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def merge_validates_length_of_email_field_options(options = {})
6262
# merge options into it. Checkout the convenience function merge_validates_format_of_email_field_options to merge
6363
# options.</b>
6464
#
65-
# * <tt>Default:</tt> {:with => Authlogic::Regex.email, :message => lambda {I18n.t('error_messages.email_invalid', :default => "should look like an email address.")}}
65+
# * <tt>Default:</tt> {:with => Authlogic::Regex.email, :message => Proc.new {I18n.t('error_messages.email_invalid', :default => "should look like an email address.")}}
6666
# * <tt>Accepts:</tt> Hash of options accepted by validates_format_of
6767
def validates_format_of_email_field_options(value = nil)
6868
rw_config(:validates_format_of_email_field_options, value, {:with => Authlogic::Regex.email, :message => Proc.new{I18n.t('error_messages.email_invalid', :default => "should look like an email address.")}})

lib/authlogic/acts_as_authentic/login.rb

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,21 +90,19 @@ def merge_validates_uniqueness_of_login_field_options(options = {})
9090
end
9191

9292
# This method allows you to find a record with the given login. If you notice, with Active Record you have the
93-
# validates_uniqueness_of validation function. They give you a :case_sensitive option. I handle this in the same
94-
# manner that they handle that. If you are using the login field and set false for the :case_sensitive option in
95-
# validates_uniqueness_of_login_field_options this method will modify the query to look something like:
93+
# UniquenessValidator class. They give you a :case_sensitive option. I handle this in the same
94+
# manner that they handle that. If you are using the login field, set false for the :case_sensitive option in
95+
# validates_uniqueness_of_login_field_options and the column doesn't have a case-insensitive collation,
96+
# this method will modify the query to look something like:
9697
#
97-
# where("LOWER(#{quoted_table_name}.#{login_field}) = ?", login.downcase).first
98+
# "LOWER(#{quoted_table_name}.#{login_field}) = LOWER(#{login})"
9899
#
99-
# If you don't specify this it calls the good old find_by_* method:
100+
# If you don't specify this it just uses a regular case-sensitive search (with the binary modifier if necessary):
100101
#
101-
# find_by_login(login)
102+
# "BINARY #{login_field} = #{login}"
102103
#
103104
# The above also applies for using email as your login, except that you need to set the :case_sensitive in
104105
# validates_uniqueness_of_email_field_options to false.
105-
#
106-
# The only reason I need to do the above is for Postgres and SQLite since they perform case sensitive searches with the
107-
# find_by_* methods.
108106
def find_by_smart_case_login_field(login)
109107
if login_field
110108
find_with_case(login_field, login, validates_uniqueness_of_login_field_options[:case_sensitive] != false)
@@ -115,11 +113,14 @@ def find_by_smart_case_login_field(login)
115113

116114
private
117115
def find_with_case(field, value, sensitivity = true)
118-
if sensitivity
119-
send("find_by_#{field}", value)
116+
relation = if not sensitivity
117+
connection.case_insensitive_comparison(arel_table, field.to_s, columns_hash[field.to_s], value)
120118
else
121-
where("LOWER(#{quoted_table_name}.#{field}) = ?", value.mb_chars.downcase).first
119+
value = connection.case_sensitive_modifier(value) if value
120+
relation = arel_table[field.to_s].eq(value)
122121
end
122+
123+
where(relation).first
123124
end
124125
end
125126

lib/authlogic/acts_as_authentic/perishable_token.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def self.included(klass)
5252

5353
# Class level methods for the perishable token
5454
module ClassMethods
55-
# Use this methdo to find a record with a perishable token. This method does 2 things for you:
55+
# Use this method to find a record with a perishable token. This method does 2 things for you:
5656
#
5757
# 1. It ignores blank tokens
5858
# 2. It enforces the perishable_token_valid_for configuration option.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
module Authlogic
2+
module ControllerAdapters
3+
# Adapter for authlogic to make it function as a Rack middleware.
4+
# First you'll have write your own Rack adapter where you have to set your cookie domain.
5+
#
6+
# class YourRackAdapter < Authlogic::ControllerAdapters::RackAdapter
7+
# def cookie_domain
8+
# 'your_cookie_domain_here.com'
9+
# end
10+
# end
11+
#
12+
# Next you need to set up a rack middleware like this:
13+
#
14+
# class AuthlogicMiddleware
15+
# def initialize(app)
16+
# @app = app
17+
# end
18+
#
19+
# def call(env)
20+
# YourRackAdapter.new(env)
21+
# @app.call(env)
22+
# end
23+
# end
24+
#
25+
# And that is all! Now just load this middleware into rack:
26+
#
27+
# use AuthlogicMiddleware
28+
#
29+
# Authlogic will expect a User and a UserSession object to be present:
30+
#
31+
# class UserSession < Authlogic::Session::Base
32+
# # Authlogic options go here
33+
# end
34+
#
35+
# class User < ActiveRecord::Base
36+
# acts_as_authentic
37+
# end
38+
#
39+
class RackAdapter < AbstractAdapter
40+
41+
def initialize(env)
42+
# We use the Rack::Request object as the controller object.
43+
# For this to work, we have to add some glue.
44+
request = Rack::Request.new(env)
45+
46+
request.instance_eval do
47+
def request; self; end
48+
def remote_ip; self.ip; end
49+
end
50+
51+
super(request)
52+
Authlogic::Session::Base.controller = self
53+
end
54+
55+
# Rack Requests stores cookies with not just the value, but also with flags and expire information in the hash.
56+
# Authlogic does not like this, so we drop everything except the cookie value
57+
def cookies
58+
controller.cookies.map{|key, value_hash| {key => value_hash[:value]} }.inject(:merge) || {}
59+
end
60+
end
61+
end
62+
63+
end

lib/authlogic/crypto_providers/bcrypt.rb

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ module CryptoProviders
1717
#
1818
# Benchmark.bm(18) do |x|
1919
# x.report("BCrypt (cost = 10:") { 100.times { BCrypt::Password.create("mypass", :cost => 10) } }
20-
# x.report("BCrypt (cost = 2:") { 100.times { BCrypt::Password.create("mypass", :cost => 2) } }
20+
# x.report("BCrypt (cost = 4:") { 100.times { BCrypt::Password.create("mypass", :cost => 4) } }
2121
# x.report("Sha512:") { 100.times { Digest::SHA512.hexdigest("mypass") } }
2222
# x.report("Sha1:") { 100.times { Digest::SHA1.hexdigest("mypass") } }
2323
# end
2424
#
25-
# user system total real
26-
# BCrypt (cost = 10): 10.780000 0.060000 10.840000 ( 11.100289)
27-
# BCrypt (cost = 2): 0.180000 0.000000 0.180000 ( 0.181914)
28-
# Sha512: 0.000000 0.000000 0.000000 ( 0.000829)
29-
# Sha1: 0.000000 0.000000 0.000000 ( 0.000395)
25+
# user system total real
26+
# BCrypt (cost = 10): 37.360000 0.020000 37.380000 ( 37.558943)
27+
# BCrypt (cost = 4): 0.680000 0.000000 0.680000 ( 0.677460)
28+
# Sha512: 0.000000 0.000000 0.000000 ( 0.000672)
29+
# Sha1: 0.000000 0.000000 0.000000 ( 0.000454)
3030
#
3131
# You can play around with the cost to get that perfect balance
3232
# between performance and security. A default cost of 10 is the
@@ -46,11 +46,17 @@ module CryptoProviders
4646
class BCrypt
4747
class << self
4848
# This is the :cost option for the BCrpyt library. The higher the cost the more secure it is and the longer is take the generate a hash. By default this is 10.
49-
# Set this to whatever you want, play around with it to get that perfect balance between security and performance.
49+
# Set this to any value >= the engine's minimum (currently 4), play around with it to get that perfect balance between security and performance.
5050
def cost
5151
@cost ||= 10
5252
end
53-
attr_writer :cost
53+
54+
def cost=(val)
55+
if val < ::BCrypt::Engine::MIN_COST
56+
raise ArgumentError.new("Authlogic's bcrypt cost cannot be set below the engine's min cost (#{::BCrypt::Engine::MIN_COST})")
57+
end
58+
@cost = val
59+
end
5460

5561
# Creates a BCrypt hash for the password passed.
5662
def encrypt(*tokens)

lib/authlogic/session/active_record_trickery.rb

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ def self.included(klass)
99
klass.extend ClassMethods
1010
klass.send(:include, InstanceMethods)
1111
end
12-
12+
1313
module ClassMethods
1414
# How to name the attributes of Authlogic, works JUST LIKE ActiveRecord, but instead it uses the following
1515
# namespace:
@@ -20,24 +20,14 @@ def human_attribute_name(attribute_key_name, options = {})
2020
options[:default] ||= attribute_key_name.to_s.humanize
2121
I18n.t("attributes.#{name.underscore}.#{attribute_key_name}", options)
2222
end
23-
23+
2424
# How to name the class, works JUST LIKE ActiveRecord, except it uses the following namespace:
2525
#
2626
# authlogic.models.user_session
2727
def human_name(*args)
2828
I18n.t("models.#{name.underscore}", {:count => 1, :default => name.humanize})
2929
end
30-
31-
# For rails < 2.3, mispelled
32-
def self_and_descendents_from_active_record
33-
[self]
34-
end
35-
36-
# For rails >= 2.3, mispelling fixed
37-
def self_and_descendants_from_active_record
38-
[self]
39-
end
40-
30+
4131
# For rails >= 3.0
4232
def model_name
4333
if defined?(::ActiveModel)
@@ -55,7 +45,7 @@ def lookup_ancestors
5545
ancestors.select { |x| x.respond_to?(:model_name) }
5646
end
5747
end
58-
48+
5949
module InstanceMethods
6050
# Don't use this yourself, this is to just trick some of the helpers since this is the method it calls.
6151
def new_record?
@@ -69,7 +59,7 @@ def persisted?
6959
def destroyed?
7060
record.nil?
7161
end
72-
62+
7363
def to_key
7464
new_record? ? nil : record.to_key
7565
end

lib/authlogic/session/magic_columns.rb

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ module Session
88
# last_request_at Updates every time the user logs in, either by explicitly logging in, or logging in by cookie, session, or http auth
99
# current_login_at Updates with the current time when an explicit login is made.
1010
# last_login_at Updates with the value of current_login_at before it is reset.
11-
# current_login_ip Updates with the request remote_ip when an explicit login is made.
11+
# current_login_ip Updates with the request ip when an explicit login is made.
1212
# last_login_ip Updates with the value of current_login_ip before it is reset.
1313
module MagicColumns
1414
def self.included(klass)
@@ -21,7 +21,7 @@ def self.included(klass)
2121
before_save :set_last_request_at, :if => :set_last_request_at?
2222
end
2323
end
24-
24+
2525
# Configuration for the magic columns feature.
2626
module Config
2727
# Every time a session is found the last_request_at field for that record is updatd with the current time, if that field exists.
@@ -36,7 +36,7 @@ def last_request_at_threshold(value = nil)
3636
end
3737
alias_method :last_request_at_threshold=, :last_request_at_threshold
3838
end
39-
39+
4040
# The methods available for an Authlogic::Session::Base object that make up the magic columns feature.
4141
module InstanceMethods
4242
private
@@ -46,22 +46,22 @@ def increase_failed_login_count
4646
attempted_record.failed_login_count += 1
4747
end
4848
end
49-
49+
5050
def update_info
5151
record.login_count = (record.login_count.blank? ? 1 : record.login_count + 1) if record.respond_to?(:login_count)
5252
record.failed_login_count = 0 if record.respond_to?(:failed_login_count)
53-
53+
5454
if record.respond_to?(:current_login_at)
5555
record.last_login_at = record.current_login_at if record.respond_to?(:last_login_at)
5656
record.current_login_at = klass.default_timezone == :utc ? Time.now.utc : Time.now
5757
end
58-
58+
5959
if record.respond_to?(:current_login_ip)
6060
record.last_login_ip = record.current_login_ip if record.respond_to?(:last_login_ip)
61-
record.current_login_ip = controller.request.remote_ip
61+
record.current_login_ip = controller.request.ip
6262
end
6363
end
64-
64+
6565
# This method lets authlogic know whether it should allow the last_request_at field to be updated
6666
# with the current time (Time.now). One thing to note here is that it also checks for the existence of a
6767
# last_request_update_allowed? method in your controller. This allows you to control this method pragmatically
@@ -81,11 +81,11 @@ def set_last_request_at? # :doc:
8181
return controller.last_request_update_allowed? if controller.responds_to_last_request_update_allowed?
8282
record.last_request_at.blank? || last_request_at_threshold.to_i.seconds.ago >= record.last_request_at
8383
end
84-
84+
8585
def set_last_request_at
8686
record.last_request_at = klass.default_timezone == :utc ? Time.now.utc : Time.now
8787
end
88-
88+
8989
def last_request_at_threshold
9090
self.class.last_request_at_threshold
9191
end

lib/authlogic/session/session.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ def persist_by_session
3535
# Allow finding by persistence token, because when records are created the session is maintained in a before_save, when there is no id.
3636
# This is done for performance reasons and to save on queries.
3737
record = record_id.nil? ?
38-
search_for_record("find_by_persistence_token", persistence_token) :
39-
search_for_record("find_by_#{klass.primary_key}", record_id)
38+
search_for_record("find_by_persistence_token", persistence_token.to_s) :
39+
search_for_record("find_by_#{klass.primary_key}", record_id.to_s)
4040
self.unauthorized_record = record if record && record.persistence_token == persistence_token
4141
valid?
4242
else

lib/authlogic/test_case/mock_request.rb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ module Authlogic
22
module TestCase
33
class MockRequest # :nodoc:
44
attr_accessor :controller
5-
5+
66
def initialize(controller)
77
self.controller = controller
88
end
9-
10-
def remote_ip
9+
10+
def ip
1111
(controller && controller.respond_to?(:env) && controller.env.is_a?(Hash) && controller.env['REMOTE_ADDR']) || "1.1.1.1"
1212
end
13-
13+
1414
private
1515
def method_missing(*args, &block)
1616
end

0 commit comments

Comments
 (0)