authie 3.1.5 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 99773bd27a0e94b3e5eaaf65806c19f309d8baed70db28a5acd11079aea2ed14
4
- data.tar.gz: 2c83b6a5436566f3257f4f20da5c777e3d9c4333c6409a625867199fb11e20fb
3
+ metadata.gz: a3bbd79539a591d214d378e2f70f91ffb144fd6c0dfb31c36a4c0ea3d86bf1a5
4
+ data.tar.gz: 2ba2f38bc671db30ccbde3a6eda511aa642d7d9191dbb2d4311c890ff720249c
5
5
  SHA512:
6
- metadata.gz: 6e39d36cb66fc54bcdbcb0902098c8aaac9171add9147f4206b29586324db75c40de475c8bbd6c015e76fcdba7fe13a06d4d3f677f75c2c5a41c528b9695f86e
7
- data.tar.gz: aced039e0b8409e5b727f50a2176efb73e52fad85c8347d418e8a004bfab8632a4ac7b34d98e504c46649676b881ac340f07a7f831d1de2ad0fda0996ecafd7b
6
+ metadata.gz: 9b325154016b3844263b77a71c484158ee256ab1ff4a67b77f670d167beff464805ab4b8a654931205124389c612a22723133f46f5b0123b9ad7102343c96b50
7
+ data.tar.gz: 9925f9aec3113b474b2a857676c163f570531fa5a5958d272a715fd448b7b5d2de8a1698ca23547023d8d01614009ca04035c11fc9d98ced2f83a1a228b2eaf9
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class CreateAuthieSessions < ActiveRecord::Migration[4.2]
2
4
  def change
3
5
  create_table :authie_sessions do |t|
4
6
  t.string :token, :browser_id
5
7
  t.integer :user_id
6
- t.boolean :active, :default => true
8
+ t.boolean :active, default: true
7
9
  t.text :data
8
10
  t.datetime :expires_at
9
11
  t.datetime :login_at
@@ -11,7 +13,7 @@ class CreateAuthieSessions < ActiveRecord::Migration[4.2]
11
13
  t.datetime :last_activity_at
12
14
  t.string :last_activity_ip, :last_activity_path
13
15
  t.string :user_agent
14
- t.timestamps :null => true
16
+ t.timestamps null: true
15
17
  end
16
18
  end
17
19
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddIndexesToAuthieSessions < ActiveRecord::Migration[4.2]
2
4
  def change
3
5
  add_column :authie_sessions, :user_type, :string
4
- add_index :authie_sessions, :token, :length => 10
5
- add_index :authie_sessions, :browser_id, :length => 10
6
+ add_index :authie_sessions, :token, length: 10
7
+ add_index :authie_sessions, :browser_id, length: 10
6
8
  add_index :authie_sessions, :user_id
7
9
  end
8
10
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddParentIdToAuthieSessions < ActiveRecord::Migration[4.2]
2
4
  def change
3
5
  add_column :authie_sessions, :parent_id, :integer
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddTwoFactorAuthFieldsToAuthie < ActiveRecord::Migration[4.2]
2
4
  def change
3
5
  add_column :authie_sessions, :two_factored_at, :datetime
4
6
  add_column :authie_sessions, :two_factored_ip, :string
5
- add_column :authie_sessions, :requests, :integer, :default => 0
7
+ add_column :authie_sessions, :requests, :integer, default: 0
6
8
  add_column :authie_sessions, :password_seen_at, :datetime
7
9
  end
8
10
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddTokenHashesToAuthieSessions < ActiveRecord::Migration[4.2]
2
4
  def change
3
5
  add_column :authie_sessions, :token_hash, :string
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddIndexToTokenHashesOnAuthieSessions < ActiveRecord::Migration[4.2]
2
4
  def change
3
- add_index :authie_sessions, :token_hash, :length => 10
5
+ add_index :authie_sessions, :token_hash, length: 10
4
6
  end
5
7
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class AddHostToAuthieSessions < ActiveRecord::Migration[4.2]
2
4
  def change
3
5
  add_column :authie_sessions, :host, :string
data/lib/authie.rb CHANGED
@@ -1,8 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'authie/version'
2
4
  require 'authie/config'
3
5
  require 'authie/error'
4
6
  require 'authie/user'
5
7
 
6
- if defined?(Rails)
7
- require 'authie/engine'
8
- end
8
+ require 'authie/engine' if defined?(Rails)
data/lib/authie/config.rb CHANGED
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'authie/event_manager'
2
4
 
3
5
  module Authie
4
6
  class Config
5
-
6
7
  def initialize
7
8
  @callbacks = {}
8
9
  end
@@ -10,17 +11,15 @@ module Authie
10
11
  def session_inactivity_timeout
11
12
  @session_inactivity_timeout || 12.hours
12
13
  end
13
- attr_writer :session_inactivity_timeout
14
+ attr_writer :session_inactivity_timeout, :persistent_session_length, :sudo_session_timeout, :browser_id_cookie_name
14
15
 
15
16
  def persistent_session_length
16
17
  @persistent_session_length || 2.months
17
18
  end
18
- attr_writer :persistent_session_length
19
19
 
20
20
  def sudo_session_timeout
21
21
  @sudo_session_timeout || 10.minutes
22
22
  end
23
- attr_writer :sudo_session_timeout
24
23
 
25
24
  def user_relationship_options
26
25
  @user_relationship_options ||= {}
@@ -29,10 +28,9 @@ module Authie
29
28
  def browser_id_cookie_name
30
29
  @browser_id_cookie_name || :browser_id
31
30
  end
32
- attr_writer :browser_id_cookie_name
33
31
 
34
32
  def events
35
- @event_manager ||= EventManager.new
33
+ @events ||= EventManager.new
36
34
  end
37
35
  end
38
36
 
@@ -44,5 +42,4 @@ module Authie
44
42
  block.call(config)
45
43
  config
46
44
  end
47
-
48
45
  end
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'securerandom'
4
+ require 'authie/session'
5
+
1
6
  module Authie
2
7
  class ControllerDelegate
3
-
4
8
  def initialize(controller)
5
9
  @controller = controller
6
10
  end
@@ -9,24 +13,22 @@ module Authie
9
13
  def set_browser_id
10
14
  until cookies[Authie.config.browser_id_cookie_name]
11
15
  proposed_browser_id = SecureRandom.uuid
12
- unless Session.where(:browser_id => proposed_browser_id).exists?
13
- cookies[Authie.config.browser_id_cookie_name] = {
14
- :value => proposed_browser_id,
15
- :expires => 5.years.from_now,
16
- :httponly => true,
17
- :secure => @controller.request.ssl?
18
- }
19
- # Dispatch an event when the browser ID is set.
20
- Authie.config.events.dispatch(:set_browser_id, proposed_browser_id)
21
- end
16
+ next if Authie::Session.where(browser_id: proposed_browser_id).exists?
17
+
18
+ cookies[Authie.config.browser_id_cookie_name] = {
19
+ value: proposed_browser_id,
20
+ expires: 5.years.from_now,
21
+ httponly: true,
22
+ secure: @controller.request.ssl?
23
+ }
24
+ # Dispatch an event when the browser ID is set.
25
+ Authie.config.events.dispatch(:set_browser_id, proposed_browser_id)
22
26
  end
23
27
  end
24
28
 
25
29
  # Touch the auth session on each request if logged in
26
30
  def touch_auth_session
27
- if logged_in?
28
- auth_session.touch!
29
- end
31
+ auth_session.touch! if logged_in?
30
32
  end
31
33
 
32
34
  # Return the currently logged in user object
@@ -36,11 +38,27 @@ module Authie
36
38
 
37
39
  # Set the currently logged in user
38
40
  def current_user=(user)
41
+ create_auth_session(user)
42
+ end
43
+
44
+ # Create a new session for the given user
45
+ def create_auth_session(user)
39
46
  if user
40
- @auth_session = Session.start(@controller, :user => user)
47
+ @auth_session = Authie::Session.start(@controller, user: user)
41
48
  else
42
49
  auth_session.invalidate! if logged_in?
43
- @auth_session = nil
50
+ @auth_session = :none
51
+ end
52
+ end
53
+
54
+ # Invalidate an existing auth session
55
+ def invalidate_auth_session
56
+ if logged_in?
57
+ auth_session.invalidate!
58
+ @auth_session = :none
59
+ true
60
+ else
61
+ false
44
62
  end
45
63
  end
46
64
 
@@ -51,7 +69,8 @@ module Authie
51
69
 
52
70
  # Return the currently logged in user session
53
71
  def auth_session
54
- @auth_session ||= Session.get_session(@controller)
72
+ @auth_session ||= Authie::Session.get_session(@controller)
73
+ @auth_session == :none ? nil : @auth_session
55
74
  end
56
75
 
57
76
  private
@@ -60,6 +79,5 @@ module Authie
60
79
  def cookies
61
80
  @controller.send(:cookies)
62
81
  end
63
-
64
82
  end
65
83
  end
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'authie/controller_delegate'
2
4
 
3
5
  module Authie
4
6
  module ControllerExtension
5
-
6
7
  def self.included(base)
7
8
  base.helper_method :logged_in?, :current_user, :auth_session
8
9
  before_action_method = base.respond_to?(:before_action) ? :before_action : :before_filter
@@ -31,6 +32,14 @@ module Authie
31
32
  auth_session_delegate.current_user = user
32
33
  end
33
34
 
35
+ def create_auth_session(user)
36
+ auth_session_delegate.create_auth_session(user)
37
+ end
38
+
39
+ def invalidate_auth_session
40
+ auth_session_delegate.invalidate_auth_session
41
+ end
42
+
34
43
  def logged_in?
35
44
  auth_session_delegate.logged_in?
36
45
  end
@@ -38,6 +47,5 @@ module Authie
38
47
  def auth_session
39
48
  auth_session_delegate.auth_session
40
49
  end
41
-
42
50
  end
43
51
  end
data/lib/authie/engine.rb CHANGED
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authie
2
4
  class Engine < ::Rails::Engine
3
-
4
5
  engine_name 'authie'
5
6
 
6
- initializer 'authie.initialize' do |app|
7
+ initializer 'authie.initialize' do |_app|
7
8
  ActiveSupport.on_load :active_record do
8
9
  require 'authie/session'
9
10
  end
@@ -12,8 +13,6 @@ module Authie
12
13
  require 'authie/controller_extension'
13
14
  include Authie::ControllerExtension
14
15
  end
15
-
16
16
  end
17
-
18
17
  end
19
18
  end
data/lib/authie/error.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authie
2
4
  class Error < StandardError
3
5
  end
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authie
2
4
  class EventManager
3
-
4
5
  def initialize
5
6
  @callbacks = {}
6
7
  end
7
8
 
8
9
  def dispatch(event, *args)
9
- if callbacks = @callbacks[event.to_sym]
10
- callbacks.each do |cb|
11
- cb.call(*args)
12
- end
10
+ callbacks = @callbacks[event.to_sym]
11
+ return if callbacks.nil?
12
+
13
+ callbacks.each do |cb|
14
+ cb.call(*args)
13
15
  end
14
16
  end
15
17
 
@@ -19,10 +21,10 @@ module Authie
19
21
  end
20
22
 
21
23
  def remove(event, block)
22
- if cb = @callbacks[event.to_sym]
23
- cb.delete(block)
24
- end
25
- end
24
+ cb = @callbacks[event.to_sym]
25
+ return if cb.nil?
26
26
 
27
+ cb.delete(block)
28
+ end
27
29
  end
28
30
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # If you're dealing with your authentication in a middleware and you only have
2
4
  # access to your rack environment, this will wrap around rack and make it look
3
5
  # close enough to an ActionController to work with Authie
@@ -9,7 +11,6 @@
9
11
 
10
12
  module Authie
11
13
  class RackController
12
-
13
14
  attr_reader :request
14
15
 
15
16
  def initialize(env)
@@ -26,27 +27,22 @@ module Authie
26
27
  def set_browser_id
27
28
  until cookies[:browser_id]
28
29
  proposed_browser_id = SecureRandom.uuid
29
- unless Session.where(:browser_id => proposed_browser_id).exists?
30
- cookies[:browser_id] = {:value => proposed_browser_id, :expires => 20.years.from_now}
30
+ unless Session.where(browser_id: proposed_browser_id).exists?
31
+ cookies[:browser_id] = { value: proposed_browser_id, expires: 20.years.from_now }
31
32
  end
32
33
  end
33
34
  end
34
35
 
35
36
  def current_user=(user)
36
- Session.start(self, :user => user)
37
+ Session.start(self, user: user)
37
38
  end
38
39
 
39
40
  def current_user
40
- if auth_session.is_a?(Session)
41
- auth_session.user
42
- else
43
- nil
44
- end
41
+ auth_session.user if auth_session.is_a?(Session)
45
42
  end
46
43
 
47
44
  def auth_session
48
45
  @auth_session ||= Session.get_session(self)
49
46
  end
50
-
51
47
  end
52
48
  end
@@ -1,46 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'secure_random_string'
4
+
1
5
  module Authie
2
6
  class Session < ActiveRecord::Base
3
-
4
7
  # Errors which will be raised when there's an issue with a session's
5
8
  # validity in the request.
6
9
  class ValidityError < Error; end
10
+
7
11
  class InactiveSession < ValidityError; end
12
+
8
13
  class ExpiredSession < ValidityError; end
14
+
9
15
  class BrowserMismatch < ValidityError; end
16
+
10
17
  class HostMismatch < ValidityError; end
11
18
 
12
19
  class NoParentSessionForRevert < Error; end
13
20
 
14
21
  # Set table name
15
- self.table_name = "authie_sessions"
22
+ self.table_name = 'authie_sessions'
16
23
 
17
24
  # Relationships
18
- user_options = {:polymorphic => true}.merge(Authie.config.user_relationship_options)
19
- user_options[:optional] = true if ActiveRecord::VERSION::MAJOR >= 5
20
- belongs_to :user, user_options
21
-
22
- parent_options = {:class_name => "Authie::Session"}
25
+ parent_options = { class_name: 'Authie::Session' }
23
26
  parent_options[:optional] = true if ActiveRecord::VERSION::MAJOR >= 5
24
- belongs_to :parent, parent_options
27
+ belongs_to :parent, **parent_options
25
28
 
26
29
  # Scopes
27
- scope :active, -> { where(:active => true) }
28
- scope :asc, -> { order(:last_activity_at => :desc) }
30
+ scope :active, -> { where(active: true) }
31
+ scope :asc, -> { order(last_activity_at: :desc) }
32
+ scope :for_user, ->(user) { where(user_type: user.class.name, user_id: user.id) }
29
33
 
30
34
  # Attributes
31
35
  serialize :data, Hash
32
- attr_accessor :controller
33
- attr_accessor :temporary_token
36
+ attr_accessor :controller, :temporary_token
34
37
 
35
38
  before_validation do
36
- if self.user_agent.is_a?(String)
37
- self.user_agent = self.user_agent[0,255]
38
- end
39
+ self.user_agent = user_agent[0, 255] if user_agent.is_a?(String)
40
+
41
+ self.last_activity_path = last_activity_path[0, 255] if last_activity_path.is_a?(String)
39
42
  end
40
43
 
41
44
  before_create do
42
- self.temporary_token = SecureRandom.base64(32)
43
- self.token_hash = self.class.hash_token(self.temporary_token)
45
+ self.temporary_token = SecureRandomString.new(44)
46
+ self.token_hash = self.class.hash_token(temporary_token)
44
47
  if controller
45
48
  self.user_agent = controller.request.user_agent
46
49
  set_cookie!
@@ -51,84 +54,119 @@ module Authie
51
54
  cookies.delete(:user_session) if controller
52
55
  end
53
56
 
57
+ # Return the user that
58
+ def user
59
+ return unless user_id && user_type
60
+
61
+ @user ||= user_type.constantize.find_by(id: user_id) || :none
62
+ @user == :none ? nil : @user
63
+ end
64
+
65
+ # Set the user
66
+ def user=(user)
67
+ if user
68
+ self.user_type = user.class.name
69
+ self.user_id = user.id
70
+ else
71
+ self.user_type = nil
72
+ self.user_id = nil
73
+ end
74
+ end
75
+
54
76
  # This method should be called each time a user performs an
55
77
  # action while authenticated with this session.
56
78
  def touch!
57
- self.check_security!
79
+ check_security!
58
80
  self.last_activity_at = Time.now
59
81
  self.last_activity_ip = controller.request.ip
60
82
  self.last_activity_path = controller.request.path
61
83
  self.requests += 1
62
- self.save!
84
+ save!
63
85
  Authie.config.events.dispatch(:session_touched, self)
64
86
  true
65
87
  end
66
88
 
67
89
  # Sets the cookie on the associated controller.
68
- def set_cookie!
90
+ # rubocop:disable Naming/AccessorMethodName
91
+ def set_cookie!(value = temporary_token)
69
92
  cookies[:user_session] = {
70
- :value => self.temporary_token,
71
- :secure => controller.request.ssl?,
72
- :httponly => true,
73
- :expires => self.expires_at
93
+ value: value,
94
+ secure: controller.request.ssl?,
95
+ httponly: true,
96
+ expires: expires_at
74
97
  }
75
98
  Authie.config.events.dispatch(:session_cookie_updated, self)
76
99
  true
77
100
  end
101
+ # rubocop:enable Naming/AccessorMethodName
102
+
103
+ # Sets the cookie for the parent session on the associated controller.
104
+ def set_parent_cookie!
105
+ cookies[:parent_user_session] = {
106
+ value: cookies[:user_session],
107
+ secure: controller.request.ssl?,
108
+ httponly: true,
109
+ expires: expires_at
110
+ }
111
+ Authie.config.events.dispatch(:parent_session_cookie_updated, self)
112
+ true
113
+ end
78
114
 
79
115
  # Check the security of the session to ensure it can be used.
80
116
  def check_security!
81
- if controller
82
- if cookies[:browser_id] != self.browser_id
83
- invalidate!
84
- Authie.config.events.dispatch(:browser_id_mismatch_error, self)
85
- raise BrowserMismatch, "Browser ID mismatch"
86
- end
87
-
88
- unless self.active?
89
- invalidate!
90
- Authie.config.events.dispatch(:invalid_session_error, self)
91
- raise InactiveSession, "Session is no longer active"
92
- end
93
-
94
- if self.expired?
95
- invalidate!
96
- Authie.config.events.dispatch(:expired_session_error, self)
97
- raise ExpiredSession, "Persistent session has expired"
98
- end
99
-
100
- if self.inactive?
101
- invalidate!
102
- Authie.config.events.dispatch(:inactive_session_error, self)
103
- raise InactiveSession, "Non-persistent session has expired"
104
- end
105
-
106
- if self.host && self.host != controller.request.host
107
- invalidate!
108
- Authie.config.events.dispatch(:host_mismatch_error, self)
109
- raise HostMismatch, "Session was created on #{self.host} but accessed using #{controller.request.host}"
110
- end
117
+ raise Authie::Error, 'Cannot check security without a controller' unless controller
118
+
119
+ if cookies[:browser_id] != browser_id
120
+ invalidate!
121
+ Authie.config.events.dispatch(:browser_id_mismatch_error, self)
122
+ raise BrowserMismatch, 'Browser ID mismatch'
123
+ end
124
+
125
+ unless active?
126
+ invalidate!
127
+ Authie.config.events.dispatch(:invalid_session_error, self)
128
+ raise InactiveSession, 'Session is no longer active'
129
+ end
130
+
131
+ if expired?
132
+ invalidate!
133
+ Authie.config.events.dispatch(:expired_session_error, self)
134
+ raise ExpiredSession, 'Persistent session has expired'
111
135
  end
136
+
137
+ if inactive?
138
+ invalidate!
139
+ Authie.config.events.dispatch(:inactive_session_error, self)
140
+ raise InactiveSession, 'Non-persistent session has expired'
141
+ end
142
+
143
+ if host && host != controller.request.host
144
+ invalidate!
145
+ Authie.config.events.dispatch(:host_mismatch_error, self)
146
+ raise HostMismatch, "Session was created on #{host} but accessed using #{controller.request.host}"
147
+ end
148
+
149
+ true
112
150
  end
113
151
 
114
152
  # Has this persistent session expired?
115
153
  def expired?
116
- self.expires_at &&
117
- self.expires_at < Time.now
154
+ expires_at &&
155
+ expires_at < Time.now
118
156
  end
119
157
 
120
158
  # Has a non-persistent session become inactive?
121
159
  def inactive?
122
- self.expires_at.nil? &&
123
- self.last_activity_at &&
124
- self.last_activity_at < Authie.config.session_inactivity_timeout.ago
160
+ expires_at.nil? &&
161
+ last_activity_at &&
162
+ last_activity_at < Authie.config.session_inactivity_timeout.ago
125
163
  end
126
164
 
127
165
  # Allow this session to persist rather than expiring at the end of the
128
166
  # current browser session
129
167
  def persist!
130
168
  self.expires_at = Authie.config.persistent_session_length.from_now
131
- self.save!
169
+ save!
132
170
  set_cookie!
133
171
  end
134
172
 
@@ -140,16 +178,14 @@ module Authie
140
178
  # Activate an old session
141
179
  def activate!
142
180
  self.active = true
143
- self.save!
181
+ save!
144
182
  end
145
183
 
146
184
  # Mark this session as invalid
147
185
  def invalidate!
148
186
  self.active = false
149
- self.save!
150
- if controller
151
- cookies.delete(:user_session)
152
- end
187
+ save!
188
+ cookies.delete(:user_session) if controller
153
189
  Authie.config.events.dispatch(:session_invalidated, self)
154
190
  true
155
191
  end
@@ -158,7 +194,7 @@ module Authie
158
194
  def set(key, value)
159
195
  self.data ||= {}
160
196
  self.data[key.to_s] = value
161
- self.save!
197
+ save!
162
198
  end
163
199
 
164
200
  # Get some additional data from this session
@@ -168,71 +204,71 @@ module Authie
168
204
 
169
205
  # Invalidate all sessions but this one for this user
170
206
  def invalidate_others!
171
- self.class.where("id != ?", self.id).where(:user => self.user).each do |s|
172
- s.invalidate!
173
- end
207
+ self.class.where('id != ?', id).for_user(user).each(&:invalidate!)
174
208
  end
175
209
 
176
210
  # Note that we have just seen the user enter their password.
177
211
  def see_password!
178
212
  self.password_seen_at = Time.now
179
- self.save!
213
+ save!
180
214
  Authie.config.events.dispatch(:seen_password, self)
181
215
  true
182
216
  end
183
217
 
184
218
  # Have we seen the user's password recently in this sesion?
185
219
  def recently_seen_password?
186
- !!(self.password_seen_at && self.password_seen_at >= Authie.config.sudo_session_timeout.ago)
220
+ !!(password_seen_at && password_seen_at >= Authie.config.sudo_session_timeout.ago)
187
221
  end
188
222
 
189
223
  # Is two factor authentication required for this request?
190
224
  def two_factored?
191
- !!(two_factored_at || self.parent_id)
225
+ !!(two_factored_at || parent_id)
192
226
  end
193
227
 
194
228
  # Mark this request as two factor authoritsed
195
229
  def mark_as_two_factored!
196
230
  self.two_factored_at = Time.now
197
231
  self.two_factored_ip = controller.request.ip
198
- self.save!
232
+ save!
199
233
  Authie.config.events.dispatch(:marked_as_two_factored, self)
200
234
  true
201
235
  end
202
236
 
203
237
  # Create a new session for impersonating for the given user
204
238
  def impersonate!(user)
205
- self.class.start(controller, :user => user, :parent => self)
239
+ set_parent_cookie!
240
+ self.class.start(controller, user: user, parent: self)
206
241
  end
207
242
 
208
243
  # Revert back to the parent session
209
244
  def revert_to_parent!
210
- if self.parent
211
- self.invalidate!
212
- self.parent.activate!
213
- self.parent.controller = self.controller
214
- self.parent.set_cookie!
215
- self.parent
216
- else
217
- raise NoParentSessionForRevert, "Session does not have a parent therefore cannot be reverted."
245
+ unless parent && cookies[:parent_user_session]
246
+ raise NoParentSessionForRevert, 'Session does not have a parent therefore cannot be reverted.'
218
247
  end
248
+
249
+ invalidate!
250
+ parent.activate!
251
+ parent.controller = controller
252
+ parent.set_cookie!(cookies[:parent_user_session])
253
+ cookies.delete(:parent_user_session)
254
+ parent
219
255
  end
220
256
 
221
257
  # Is this the first session for this session's browser?
222
258
  def first_session_for_browser?
223
- self.class.where("id < ?", self.id).where(:user => self.user, :browser_id => self.browser_id).empty?
259
+ self.class.where('id < ?', id).for_user(user).where(browser_id: browser_id).empty?
224
260
  end
225
261
 
226
262
  # Is this the first session for the IP?
227
263
  def first_session_for_ip?
228
- self.class.where("id < ?", self.id).where(:user => self.user, :login_ip => self.login_ip).empty?
264
+ self.class.where('id < ?', id).for_user(user).where(login_ip: login_ip).empty?
229
265
  end
230
266
 
231
267
  # Find a session from the database for the given controller instance.
232
268
  # Returns a session object or :none if no session is found.
233
269
  def self.get_session(controller)
234
270
  cookies = controller.send(:cookies)
235
- if cookies[:user_session] && session = self.find_session_by_token(cookies[:user_session])
271
+ if cookies[:user_session] && (session = find_session_by_token(cookies[:user_session]))
236
272
  session.temporary_token = cookies[:user_session]
237
273
  session.controller = controller
238
274
  session
@@ -244,15 +280,19 @@ module Authie
244
280
  # Find a session by a token (either from a hash or from the raw token)
245
281
  def self.find_session_by_token(token)
246
282
  return nil if token.blank?
247
- self.active.where("token = ? OR token_hash = ?", token, self.hash_token(token)).first
283
+
284
+ active.where('token = ? OR token_hash = ?', token, hash_token(token)).first
248
285
  end
249
286
 
250
287
  # Create a new session and return the newly created session object.
251
288
  # Any other sessions for the browser will be invalidated.
252
289
  def self.start(controller, params = {})
253
290
  cookies = controller.send(:cookies)
254
- self.active.where(:browser_id => cookies[:browser_id]).each(&:invalidate!)
255
- session = self.new(params)
291
+ active.where(browser_id: cookies[:browser_id]).each(&:invalidate!)
292
+ user_object = params.delete(:user)
293
+
294
+ session = new(params)
295
+ session.user = user_object
256
296
  session.controller = controller
257
297
  session.browser_id = cookies[:browser_id]
258
298
  session.login_at = Time.now
@@ -267,9 +307,10 @@ module Authie
267
307
  def self.cleanup
268
308
  Authie.config.events.dispatch(:before_cleanup)
269
309
  # Invalidate transient sessions that haven't been used
270
- self.active.where("expires_at IS NULL AND last_activity_at < ?", Authie.config.session_inactivity_timeout.ago).each(&:invalidate!)
310
+ active.where('expires_at IS NULL AND last_activity_at < ?',
311
+ Authie.config.session_inactivity_timeout.ago).each(&:invalidate!)
271
312
  # Invalidate persistent sessions that have expired
272
- self.active.where("expires_at IS NOT NULL AND expires_at < ?", Time.now).each(&:invalidate!)
313
+ active.where('expires_at IS NOT NULL AND expires_at < ?', Time.now).each(&:invalidate!)
273
314
  Authie.config.events.dispatch(:after_cleanup)
274
315
  true
275
316
  end
@@ -281,9 +322,9 @@ module Authie
281
322
 
282
323
  # Convert all existing active sessions to store their tokens in the database
283
324
  def self.convert_tokens_to_hashes
284
- active.where(:token_hash => nil).where("token is not null").each do |s|
285
- hash = self.hash_token(s.token)
286
- self.where(:id => s.id).update_all(:token_hash => hash, :token => nil)
325
+ active.where(token_hash: nil).where('token is not null').each do |s|
326
+ hash = hash_token(s.token)
327
+ where(id: s.id).update_all(token_hash: hash, token: nil)
287
328
  end
288
329
  end
289
330
 
@@ -293,6 +334,5 @@ module Authie
293
334
  def cookies
294
335
  controller.send(:cookies)
295
336
  end
296
-
297
337
  end
298
338
  end
data/lib/authie/user.rb CHANGED
@@ -1,9 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authie
2
4
  module User
3
-
4
5
  def self.included(base)
5
- base.has_many :user_sessions, :class_name => 'Authie::Session', :as => :user, :dependent => :delete_all
6
+ base.has_many :user_sessions, class_name: 'Authie::Session', as: :user, dependent: :delete_all
6
7
  end
7
-
8
8
  end
9
9
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authie
2
- VERSION = '3.1.5'
4
+ VERSION = '3.4.0'
3
5
  end
metadata CHANGED
@@ -1,42 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: authie
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.5
4
+ version: 3.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Cooke
8
8
  autorequire:
9
9
  bindir: bin
10
- cert_chain:
11
- - |
12
- -----BEGIN CERTIFICATE-----
13
- MIIEZDCCAsygAwIBAgIBATANBgkqhkiG9w0BAQsFADA8MQswCQYDVQQDDAJtZTEZ
14
- MBcGCgmSJomT8ixkARkWCWFkYW1jb29rZTESMBAGCgmSJomT8ixkARkWAmlvMB4X
15
- DTE4MDMwNTE3MzAwNVoXDTE5MDMwNTE3MzAwNVowPDELMAkGA1UEAwwCbWUxGTAX
16
- BgoJkiaJk/IsZAEZFglhZGFtY29va2UxEjAQBgoJkiaJk/IsZAEZFgJpbzCCAaIw
17
- DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAOH6HpXwjmVYrUQxUHm25mLm9qYK
18
- WS66Me1IfMUX3ZREZ/GzqiJZdV6itPuaaaKpbcm2A/KjgGSPOi9FZBneZ5KvbIeK
19
- /GsixL98kxB06q9DZwJbFz7Inklxkd/S0anm+PxtWkQP1TLkMsviRcBPEAqSLON9
20
- dCKC7+3kibhatdlsbqIQaeEhSoCUipYMi7ZyFHu5Qz+zMwc8JwHvQ4yi8cMa/QZ+
21
- s1tN4mkp/6vWWj4G4lF3YjFYyt2txJcK5ELDtyBy7a3vbMImPy9pplFx1/M6SNpn
22
- 7Pck0LqDprRzJXsGjq3CbC0nUaudFjUPr31KwxMYq1u13aQL9YuO3GeQCQ3gvdlJ
23
- TSd7zoGgLwrMGmXqgd392Psr29yp+WBLcvhFUJnNPDV8nlph/cqmRzoIewP1kdPq
24
- pEIUIJQdyKJU7gmFlJ1FurarkuT0a2Rgs99WokCoXLxuPmRWQRN1sH2nHL70jgAR
25
- UuvyXEtyALHoCn3VqBR7ZvpfDblUzfANQDhBgwIDAQABo3EwbzAJBgNVHRMEAjAA
26
- MAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUa7gxxSE4SO2Ors4B+y3qANdMpo4wGgYD
27
- VR0RBBMwEYEPbWVAYWRhbWNvb2tlLmlvMBoGA1UdEgQTMBGBD21lQGFkYW1jb29r
28
- ZS5pbzANBgkqhkiG9w0BAQsFAAOCAYEAkbz/AJwBsRKwgt2BhWqgr/egf/37IS3s
29
- utVox7feYutKyFDHXYvCjm64XUJNioG7ipbRwOOGs5bEYfwgkabcAQnxSlkdNjc4
30
- JIgL/cF4YRg8uJG7DH+LwpydXHqr7RneDiONuiHlEN/1EZZ8tjwXypdwzhQ2/6ot
31
- YOxdSi/mXdoDoFlIebsLyInUZjqnm7dQ9nTTUNSB+1LoOD8ARNhTIPnKCnxwZd56
32
- giOxoHuJIOhgi6U2zicZJHv8lUj2Lc3bcirQk5eeOFRPVGQSpLLoqA7dtS7Jy4cv
33
- 3c5m+HyxSxzlrcVHMAgJYemK0uhVQD9Y6JwHKDroWDH+MPALjlScw8ui1jmNuH31
34
- n5JOH/07C4gYcwTjJmtoRSov46Z6Gn5cc6NFkQpA185pbRLqEDKzusXvBOQlAOLh
35
- iyQrH6PJ0xgVJNYx+DLq3eFmo2hYJkw/lVhYAK+MdajtYJbD5VvCIEHO0d5RRgV+
36
- qnCNZoPPy0UtRmGKZTMZvVJEZiw4g0fY
37
- -----END CERTIFICATE-----
38
- date: 2018-03-14 00:00:00.000000000 Z
39
- dependencies: []
10
+ cert_chain: []
11
+ date: 2021-03-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: secure_random_string
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
40
27
  description: A Rails library for storing user sessions in a backend database
41
28
  email:
42
29
  - me@adamcooke.io
@@ -81,8 +68,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
68
  - !ruby/object:Gem::Version
82
69
  version: '0'
83
70
  requirements: []
84
- rubyforge_project:
85
- rubygems_version: 2.7.4
71
+ rubygems_version: 3.0.3
86
72
  signing_key:
87
73
  specification_version: 4
88
74
  summary: A Rails library for storing user sessions in a backend database
checksums.yaml.gz.sig DELETED
Binary file
data.tar.gz.sig DELETED
Binary file
metadata.gz.sig DELETED
Binary file