Class: Authgasm::Session::Base

Inherits:
Object
  • Object
show all
Includes:
ActiveRecordTrickery, Callbacks, Config
Defined in:
lib/authgasm/session/base.rb,
lib/authgasm.rb

Overview

Base

This is the muscle behind Authgasm. 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 Callbacks

#destroy_with_callbacks, included, #save_with_callbacks, #valid_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(, password)
UserSession.new(:login => , :password => password)

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

UserSession.new(:my_id)
UserSession.new(, password, :my_id)
UserSession.new({:login => loing, :password => password}, :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. Authgasm will separate everything out.

Raises:



105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/authgasm/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)
  
  case args.size
  when 1
    credentials_or_record = args.first
    case credentials_or_record
    when Hash
      self.credentials = credentials_or_record
    else
      self.unauthorized_record = credentials_or_record
    end
  else
    send("#{}=", args[0])
    send("#{password_field}=", args[1])
    self.remember_me = args[2]
  end
end

Instance Attribute Details

#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.



179
180
181
# File 'lib/authgasm/session/base.rb', line 179

def id
  @id
end

#login_withObject

Returns the value of attribute login_with.



87
88
89
# File 'lib/authgasm/session/base.rb', line 87

def 
  @login_with
end

#new_sessionObject

Returns the value of attribute new_session.



87
88
89
# File 'lib/authgasm/session/base.rb', line 87

def new_session
  @new_session
end

#recordObject (readonly)

Returns the value of attribute record.



88
89
90
# File 'lib/authgasm/session/base.rb', line 88

def record
  @record
end

#remember_meObject

Returns the value of attribute remember_me.



87
88
89
# File 'lib/authgasm/session/base.rb', line 87

def remember_me
  @remember_me
end

#unauthorized_recordObject

Returns the value of attribute unauthorized_record.



88
89
90
# File 'lib/authgasm/session/base.rb', line 88

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 Authgasm in a unique way outside of rails, you need to assign a controller object to Authgasm via Authgasm::Session::Base.controller = obj.

Returns:

  • (Boolean)


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

def activated?
  !controller.blank?
end

.controllerObject

:nodoc:



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

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

.controller=(value) ⇒ Object

:nodoc:



17
18
19
# File 'lib/authgasm/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


29
30
31
32
# File 'lib/authgasm/session/base.rb', line 29

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



35
36
37
38
# File 'lib/authgasm/session/base.rb', line 35

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

.find(id = nil) ⇒ Object

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.record
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.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/authgasm/session/base.rb', line 50

def find(id = nil)
  args = [id].compact
  session = new(*args)
  find_with.each do |find_method|
    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)
      end
      return session
    end
  end
  nil
end

.klassObject

:nodoc:



65
66
67
68
69
70
71
72
# File 'lib/authgasm/session/base.rb', line 65

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

.klass_nameObject

:nodoc:



74
75
76
77
78
79
# File 'lib/authgasm/session/base.rb', line 74

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

Instance Method Details

#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.



130
131
132
# File 'lib/authgasm/session/base.rb', line 130

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

#credentials=(values) ⇒ Object

Lets you set your loging and password via a hash format.

Raises:

  • (ArgumentError)


135
136
137
138
139
# File 'lib/authgasm/session/base.rb', line 135

def credentials=(values)
  return if values.blank? || !values.is_a?(Hash)
  raise(ArgumentError, "Only 2 credentials are allowed: #{} and #{password_field}") if (values.keys - [.to_sym, .to_s, password_field.to_sym, password_field.to_s]).size > 0
  values.each { |field, value| send("#{field}=", value) }
end

#destroyObject

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



142
143
144
145
146
147
148
# File 'lib/authgasm/session/base.rb', line 142

def destroy
  errors.clear
  @record = nil
  controller.cookies.delete cookie_key
  controller.session[session_key] = nil
  true
end

#errorsObject

The errors in Authgasm 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


163
164
165
# File 'lib/authgasm/session/base.rb', line 163

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

#inspectObject

:nodoc:



183
184
185
186
187
188
189
190
191
192
193
# File 'lib/authgasm/session/base.rb', line 183

def inspect # :nodoc:
  details = {}
  case 
  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

Returns:

  • (Boolean)


196
197
198
# File 'lib/authgasm/session/base.rb', line 196

def new_session?
  new_session != false
end

#remember_me?Boolean

Allows users to be remembered via a cookie.

Returns:

  • (Boolean)


201
202
203
# File 'lib/authgasm/session/base.rb', line 201

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.



206
207
208
209
# File 'lib/authgasm/session/base.rb', line 206

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



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/authgasm/session/base.rb', line 217

def save
  if valid?
    update_session!
    controller.cookies[cookie_key] = {
      :value => record.send(remember_token_field),
      :expires => remember_me_until
    }
    
    record. = 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_from_session(false)
    
    self.new_session = false
    self
  end
end

#save!Object

Same as save but raises an exception when authentication fails

Raises:



245
246
247
248
249
# File 'lib/authgasm/session/base.rb', line 245

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

#valid?Boolean

Returns:

  • (Boolean)


258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/authgasm/session/base.rb', line 258

def valid?
  errors.clear
  temp_record = unauthorized_record
  
  case 
  when :credentials
    errors.add(, "can not be blank") if send().blank?
    errors.add(password_field, "can not be blank") if send("protected_#{password_field}").blank?
    return false if errors.count > 0

    temp_record = klass.send(, send())

    if temp_record.blank?
      errors.add(, "was not found")
      return false
    end
    
    unless temp_record.send(verify_password_method, send("protected_#{password_field}"))
      errors.add(password_field, "is invalid")
      return false
    end
  when :unauthorized_record
    if temp_record.blank?
      errors.add_to_base("You can not log in with a blank record.")
      return false
    end
    
    if temp_record.new_record?
      errors.add_to_base("You can not login with a new record.") if temp_record.new_record?
      return false
    end
  else
    errors.add_to_base("You must provide some form of credentials before logging in.")
    return false
  end

  [:active, :approved, :confirmed].each do |required_status|
    if temp_record.respond_to?("#{required_status}?") && !temp_record.send("#{required_status}?") 
      errors.add_to_base("Your account has not been marked as #{required_status}")       
      return false
    end
  end
  
  # All is good, lets set the record
  @record = temp_record
  
  true
end

#valid_cookie?Boolean

Returns:

  • (Boolean)


323
324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/authgasm/session/base.rb', line 323

def valid_cookie?
  if cookie_credentials
    self.unauthorized_record = klass.send("find_by_#{remember_token_field}", cookie_credentials)
    result = valid?
    if result
      update_session!
      self.new_session = false
      return result
    end
  end
  
  false
end

#valid_http_auth?Boolean

Returns:

  • (Boolean)


307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
# File 'lib/authgasm/session/base.rb', line 307

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

#valid_session?Boolean

Returns:

  • (Boolean)


337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/authgasm/session/base.rb', line 337

def valid_session?
  if session_credentials
    self.unauthorized_record = klass.send("find_by_#{remember_token_field}", cookie_credentials)
    result = valid?
    if result
      self.new_session = false
      return result
    end
  end
  
  false
end