authie 3.1.5 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
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