Class: Authlogic::Session::Base

Inherits:
Object
  • Object
show all
Includes:
Authlogic::Session, ActiveRecordTrickery, Callbacks, Config, Cookies, Params, Scopes
Defined in:
lib/authlogic/session/base.rb,
lib/authlogic.rb

Overview

Base

This is the muscle behind Authlogic. For detailed information on how to use this please refer to the README. For detailed method explanations see below.

Constant Summary

Constants included from Callbacks

Callbacks::CALLBACKS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Config

included

Methods included from Scopes

included

Methods included from Params

#valid_params?

Methods included from Cookies

included, #valid_cookie?

Methods included from Callbacks

#destroy_with_callbacks, #find_record_with_callbacks, included, #save_with_callbacks, #validate_with_callbacks

Methods included from ActiveRecordTrickery

included

Constructor Details

#initialize(*args) ⇒ Base

You can initialize a session by doing any of the following:

UserSession.new
UserSession.new(:login => "login", :password => "password", :remember_me => true)
UserSession.new(:openid => "identity url", :remember_me => true)
UserSession.new(User.first, true)

If a user has more than one session you need to pass an id so that Authlogic knows how to differentiate the sessions. The id MUST be a Symbol.

UserSession.new(:my_id)
UserSession.new({:login => "login", :password => "password", :remember_me => true}, :my_id)
UserSession.new({:openid => "identity url", :remember_me => true}, :my_id)
UserSession.new(User.first, true, :my_id)

Ids are rarely used, but they can be useful. For example, what if users allow other users to login into their account via proxy? Now that user can “technically” be logged into 2 accounts at once. To solve this just pass a id called :proxy, or whatever you want. Authlogic will separate everything out.

The reason the id is separate from the first parameter hash is becuase this should be controlled by you, not by what the user passes. A usr could inject their own id and things would not work as expected.

Raises:



105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/authlogic/session/base.rb', line 105

def initialize(*args)
  raise NotActivated.new(self) unless self.class.activated?
  
  create_configurable_methods!
  
  self.id = args.pop if args.last.is_a?(Symbol)
  
  if args.first.is_a?(Hash)
    self.credentials = args.first
  elsif !args.first.blank? && args.first.class < ::ActiveRecord::Base
    self.unauthorized_record = args.first
    self.remember_me = args[1] if args.size > 1
  end
end

Instance Attribute Details

#authenticating_withObject

A flag for how the user is logging in. Possible values:

  • :password - username and password

  • :unauthorized_record - an actual ActiveRecord object

  • :openid - OpenID

By default this is :password



127
128
129
# File 'lib/authlogic/session/base.rb', line 127

def authenticating_with
  @authenticating_with ||= :password
end

#idObject

Allows you to set a unique identifier for your session, so that you can have more than 1 session at a time. A good example when this might be needed is when you want to have a normal user session and a “secure” user session. The secure user session would be created only when they want to modify their billing information, or other sensative information. Similar to me.com. This requires 2 user sessions. Just use an id for the “secure” session and you should be good.

You can set the id a number of ways:

session = Session.new(:secure)
session = Session.new("username", "password", :secure)
session = Session.new({:username => "username", :password => "password"}, :secure)
session.id = :secure

Just be sure and set your id before you validate / create / update your session.



216
217
218
# File 'lib/authlogic/session/base.rb', line 216

def id
  @id
end

#new_sessionObject

Returns the value of attribute new_session.



83
84
85
# File 'lib/authlogic/session/base.rb', line 83

def new_session
  @new_session
end

#recordObject

Returns the value of attribute record.



84
85
86
# File 'lib/authlogic/session/base.rb', line 84

def record
  @record
end

#unauthorized_recordObject

Returns the value of attribute unauthorized_record.



84
85
86
# File 'lib/authlogic/session/base.rb', line 84

def unauthorized_record
  @unauthorized_record
end

Class Method Details

.activated?Boolean

Returns true if a controller have been set and can be used properly. This MUST be set before anything can be done. Similar to how ActiveRecord won’t allow you to do anything without establishing a DB connection. By default this is done for you automatically, but if you are using Authlogic in a unique way outside of rails, you need to assign a controller object to Authlogic via Authlogic::Session::Base.controller = obj.

Returns:

  • (Boolean)


13
14
15
# File 'lib/authlogic/session/base.rb', line 13

def activated?
  !controller.blank?
end

.controllerObject

:nodoc:



21
22
23
# File 'lib/authlogic/session/base.rb', line 21

def controller # :nodoc:
  controllers[Thread.current]
end

.controller=(value) ⇒ Object

:nodoc:



17
18
19
# File 'lib/authlogic/session/base.rb', line 17

def controller=(value) # :nodoc:
  controllers[Thread.current] = value
end

.create(*args) ⇒ Object

A convenince method. The same as:

session = UserSession.new
session.create


33
34
35
36
# File 'lib/authlogic/session/base.rb', line 33

def create(*args)
  session = new(*args)
  session.save
end

.create!(*args) ⇒ Object

Same as create but calls create!, which raises an exception when authentication fails



39
40
41
42
# File 'lib/authlogic/session/base.rb', line 39

def create!(*args)
  session = new(*args)
  session.save!
end

.find(id = nil) ⇒ Object

A convenience method for session.find_record. Finds your session by session, then cookie, and finally basic http auth. Perfect for that global before_filter to find your logged in user:

before_filter :load_user

def load_user
  @user_session = UserSession.find
  @current_user = @user_session && @user_session.user
end

Accepts a single parameter as the id. See initialize for more information on ids. Lastly, how it finds the session can be modified via configuration.



54
55
56
57
58
59
# File 'lib/authlogic/session/base.rb', line 54

def find(id = nil)
  args = [id].compact
  session = new(*args)
  return session if session.find_record
  nil
end

.klassObject

:nodoc:



61
62
63
64
65
66
67
68
# File 'lib/authlogic/session/base.rb', line 61

def klass # :nodoc:
  @klass ||=
    if klass_name
      klass_name.constantize
    else
      nil
    end
end

.klass_nameObject

:nodoc:



70
71
72
73
74
75
# File 'lib/authlogic/session/base.rb', line 70

def klass_name # :nodoc:
  @klass_name ||= 
    if guessed_name = name.scan(/(.*)Session/)[0]
      @klass_name = guessed_name[0]
    end
end

.reset_controllers!Object



25
26
27
# File 'lib/authlogic/session/base.rb', line 25

def reset_controllers!
  @@controllers = {}
end

Instance Method Details

#authenticating_with_password?Boolean

Returns true if logging in with credentials. Credentials mean username and password.

Returns:

  • (Boolean)


132
133
134
# File 'lib/authlogic/session/base.rb', line 132

def authenticating_with_password?
  authenticating_with == :password
end

#authenticating_with_unauthorized_record?Boolean Also known as: authenticating_with_record?

Returns true if logging in with an unauthorized record

Returns:

  • (Boolean)


137
138
139
# File 'lib/authlogic/session/base.rb', line 137

def authenticating_with_unauthorized_record?
  authenticating_with == :unauthorized_record
end

#credentialsObject

Your login credentials in hash format. Usually => “my login”, :password => “<protected>” depending on your configuration. Password is protected as a security measure. The raw password should never be publicly accessible.



144
145
146
# File 'lib/authlogic/session/base.rb', line 144

def credentials
  { => send(), password_field => "<Protected>"}
end

#credentials=(values) ⇒ Object

Lets you set your loging and password via a hash format. This is “params” safe. It only allows for 3 keys: your login field name, password field name, and remember me.



149
150
151
152
153
154
155
156
# File 'lib/authlogic/session/base.rb', line 149

def credentials=(values)
  return if values.blank? || !values.is_a?(Hash)
  values.symbolize_keys!
  [.to_sym, password_field.to_sym, :remember_me].each do |field|
    next if values[field].blank?
    send("#{field}=", values[field])
  end
end

#destroyObject

Resets everything, your errors, record, cookies, and session. Basically “logs out” a user.



159
160
161
162
163
# File 'lib/authlogic/session/base.rb', line 159

def destroy
  errors.clear
  @record = nil
  true
end

#errorsObject

The errors in Authlogic work JUST LIKE ActiveRecord. In fact, it uses the exact same ActiveRecord errors class. Use it the same way:

Example

class UserSession
  before_validation :check_if_awesome

  private
    def check_if_awesome
      errors.add(:login, "must contain awesome") if  && !.include?("awesome")
      errors.add_to_base("You must be awesome to log in") unless record.awesome?
    end
end


178
179
180
# File 'lib/authlogic/session/base.rb', line 178

def errors
  @errors ||= Errors.new(self)
end

#find_recordObject

Attempts to find the record by session, then cookie, and finally basic http auth. See the class level find method if you are wanting to use this in a before_filter to persist your session.



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/authlogic/session/base.rb', line 183

def find_record
  if record
    self.new_session = false
    return record
  end
  
  find_with.each do |find_method|
    if send("valid_#{find_method}?")
      self.new_session = false
      
      if record.class.column_names.include?("last_request_at") && (record.last_request_at.blank? || last_request_at_threshold.ago >= record.last_request_at)
        record.last_request_at = Time.now
        record.save_without_session_maintenance(false)
      end
      
      return record
    end
  end
  nil
end

#inspectObject

:nodoc:



220
221
222
223
224
225
226
227
228
229
230
# File 'lib/authlogic/session/base.rb', line 220

def inspect # :nodoc:
  details = {}
  case authenticating_with
  when :unauthorized_record
    details[:unauthorized_record] = "<protected>"
  else
    details[.to_sym] = send()
    details[password_field.to_sym] = "<protected>"
  end
  "#<#{self.class.name} #{details.inspect}>"
end

#new_session?Boolean

Similar to ActiveRecord’s new_record? Returns true if the session has not been saved yet.

Returns:

  • (Boolean)


233
234
235
# File 'lib/authlogic/session/base.rb', line 233

def new_session?
  new_session != false
end

#remember_meObject

:nodoc:



237
238
239
240
# File 'lib/authlogic/session/base.rb', line 237

def remember_me # :nodoc:
  return @remember_me if @set_remember_me
  @remember_me ||= self.class.remember_me
end

#remember_me=(value) ⇒ Object

Accepts a boolean as a flag to remember the session or not. Basically to expire the cookie at the end of the session or keep it for “remember_me_until”.



243
244
245
246
# File 'lib/authlogic/session/base.rb', line 243

def remember_me=(value)
  @set_remember_me = true
  @remember_me = value
end

#remember_me?Boolean

Allows users to be remembered via a cookie.

Returns:

  • (Boolean)


249
250
251
# File 'lib/authlogic/session/base.rb', line 249

def remember_me?
  remember_me == true || remember_me == "true" || remember_me == "1"
end

#remember_me_untilObject

When to expire the cookie. See remember_me_for configuration option to change this.



254
255
256
257
# File 'lib/authlogic/session/base.rb', line 254

def remember_me_until
  return unless remember_me?
  remember_me_for.from_now
end

#saveObject

Creates / updates a new user session for you. It does all of the magic:

  1. validates

  2. sets session

  3. sets cookie

  4. updates magic fields



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/authlogic/session/base.rb', line 265

def save
  if valid?
    record. = (record..blank? ? 1 : record. + 1) if record.respond_to?(:login_count)
    
    if record.respond_to?(:current_login_at)
      record. = record. if record.respond_to?(:last_login_at)
      record. = Time.now
    end
    
    if record.respond_to?(:current_login_ip)
      record. = record. if record.respond_to?(:last_login_ip)
      record. = controller.request.remote_ip
    end
    
    record.save_without_session_maintenance(false)
    
    self.new_session = false
    self
  end
end

#save!Object

Same as save but raises an exception when authentication fails

Raises:



287
288
289
290
291
# File 'lib/authlogic/session/base.rb', line 287

def save!
  result = save
  raise SessionInvalid.new(self) unless result
  result
end

#valid?Boolean

Returns if the session is valid or not. Basically it means that a record could or could not be found. If the session is valid you will have a result when calling the “record” method. If it was unsuccessful you will not have a record.

Returns:

  • (Boolean)


302
303
304
305
306
307
308
309
310
311
312
# File 'lib/authlogic/session/base.rb', line 302

def valid?
  errors.clear
  if valid_credentials?
    validate
    valid_record?
    return true if errors.empty?
  end
  
  self.record = nil
  false
end

#valid_http_auth?Boolean

Tries to validate the session from information from a basic http auth, if it was provided.

Returns:

  • (Boolean)


315
316
317
318
319
320
321
322
323
324
325
# File 'lib/authlogic/session/base.rb', line 315

def valid_http_auth?
  controller.authenticate_with_http_basic do |, password|
    if !.blank? && !password.blank?
      send("#{}=", )
      send("#{password_field}=", password)
      return valid?
    end
  end
  
  false
end

#validateObject

Overwite this method to add your own validation, or use callbacks: before_validation, after_validation



328
329
# File 'lib/authlogic/session/base.rb', line 328

def validate
end