authie 3.3.2 → 4.0.0.rc3
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 +4 -4
- data/db/migrate/20141012174250_create_authie_sessions.rb +4 -2
- data/db/migrate/20141013115205_add_indexes_to_authie_sessions.rb +4 -2
- data/db/migrate/20150109144120_add_parent_id_to_authie_sessions.rb +2 -0
- data/db/migrate/20150305135400_add_two_factor_auth_fields_to_authie.rb +3 -1
- data/db/migrate/20170417170000_add_token_hashes_to_authie_sessions.rb +2 -0
- data/db/migrate/20170421174100_add_index_to_token_hashes_on_authie_sessions.rb +3 -1
- data/db/migrate/20180215152200_add_host_to_authie_sessions.rb +2 -0
- data/lib/authie/config.rb +19 -35
- data/lib/authie/controller_delegate.rb +67 -40
- data/lib/authie/controller_extension.rb +14 -37
- data/lib/authie/engine.rb +3 -3
- data/lib/authie/error.rb +2 -0
- data/lib/authie/event_manager.rb +12 -8
- data/lib/authie/rack_controller.rb +6 -10
- data/lib/authie/session.rb +243 -290
- data/lib/authie/session_model.rb +141 -0
- data/lib/authie/user.rb +3 -3
- data/lib/authie/version.rb +8 -1
- data/lib/authie.rb +3 -3
- metadata +214 -5
@@ -0,0 +1,141 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_record/base'
|
4
|
+
require 'secure_random_string'
|
5
|
+
require 'authie/config'
|
6
|
+
|
7
|
+
module Authie
|
8
|
+
class SessionModel < ActiveRecord::Base
|
9
|
+
attr_accessor :temporary_token
|
10
|
+
|
11
|
+
self.table_name = 'authie_sessions'
|
12
|
+
|
13
|
+
belongs_to :parent, class_name: 'Authie::SessionModel', optional: true
|
14
|
+
|
15
|
+
scope :active, -> { where(active: true) }
|
16
|
+
scope :asc, -> { order(last_activity_at: :desc) }
|
17
|
+
scope :for_user, ->(user) { where(user_type: user.class.name, user_id: user.id) }
|
18
|
+
|
19
|
+
# Attributes
|
20
|
+
serialize :data, Hash
|
21
|
+
|
22
|
+
before_validation do
|
23
|
+
self.user_agent = user_agent[0, 255] if user_agent.is_a?(String)
|
24
|
+
self.last_activity_path = last_activity_path[0, 255] if last_activity_path.is_a?(String)
|
25
|
+
end
|
26
|
+
|
27
|
+
before_create do
|
28
|
+
self.temporary_token = SecureRandomString.new(44)
|
29
|
+
self.token_hash = self.class.hash_token(temporary_token)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Return the user that
|
33
|
+
def user
|
34
|
+
return unless user_id && user_type
|
35
|
+
return @user if instance_variable_defined?('@user')
|
36
|
+
|
37
|
+
@user = user_type.constantize.find_by(id: user_id)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Set the user
|
41
|
+
def user=(user)
|
42
|
+
@user = user
|
43
|
+
if user
|
44
|
+
self.user_type = user.class.name
|
45
|
+
self.user_id = user.id
|
46
|
+
else
|
47
|
+
self.user_type = nil
|
48
|
+
self.user_id = nil
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def expired?
|
53
|
+
expires_at.present? &&
|
54
|
+
expires_at < Time.now
|
55
|
+
end
|
56
|
+
|
57
|
+
def inactive?
|
58
|
+
expires_at.nil? &&
|
59
|
+
last_activity_at.present? &&
|
60
|
+
last_activity_at < Authie.config.session_inactivity_timeout.ago
|
61
|
+
end
|
62
|
+
|
63
|
+
def persistent?
|
64
|
+
!!expires_at
|
65
|
+
end
|
66
|
+
|
67
|
+
def activate!
|
68
|
+
self.active = true
|
69
|
+
save!
|
70
|
+
end
|
71
|
+
|
72
|
+
def invalidate!
|
73
|
+
self.active = false
|
74
|
+
save!
|
75
|
+
true
|
76
|
+
end
|
77
|
+
|
78
|
+
def set(key, value)
|
79
|
+
self.data ||= {}
|
80
|
+
self.data[key.to_s] = value
|
81
|
+
save!
|
82
|
+
end
|
83
|
+
|
84
|
+
def get(key)
|
85
|
+
(self.data ||= {})[key.to_s]
|
86
|
+
end
|
87
|
+
|
88
|
+
def invalidate_others!
|
89
|
+
self.class.where('id != ?', id).for_user(user).each(&:invalidate!).inspect
|
90
|
+
end
|
91
|
+
|
92
|
+
# Have we seen the user's password recently in this sesion?
|
93
|
+
def recently_seen_password?
|
94
|
+
!!(password_seen_at && password_seen_at >= Authie.config.sudo_session_timeout.ago)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Is two factor authentication required for this request?
|
98
|
+
def two_factored?
|
99
|
+
!!(two_factored_at || parent_id)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Is this the first session for this session's browser?
|
103
|
+
def first_session_for_browser?
|
104
|
+
self.class.where('id < ?', id).for_user(user).where(browser_id: browser_id).empty?
|
105
|
+
end
|
106
|
+
|
107
|
+
# Is this the first session for the IP?
|
108
|
+
def first_session_for_ip?
|
109
|
+
self.class.where('id < ?', id).for_user(user).where(login_ip: login_ip).empty?
|
110
|
+
end
|
111
|
+
|
112
|
+
class << self
|
113
|
+
# Find a session from the database for the given controller instance.
|
114
|
+
# Returns a session object or :none if no session is found.
|
115
|
+
|
116
|
+
# Find a session by a token (either from a hash or from the raw token)
|
117
|
+
def find_session_by_token(token)
|
118
|
+
return nil if token.blank?
|
119
|
+
|
120
|
+
active.where(token_hash: hash_token(token)).first
|
121
|
+
end
|
122
|
+
|
123
|
+
# Cleanup any old sessions.
|
124
|
+
def cleanup
|
125
|
+
Authie.config.events.dispatch(:before_cleanup)
|
126
|
+
# Invalidate transient sessions that haven't been used
|
127
|
+
active.where('expires_at IS NULL AND last_activity_at < ?',
|
128
|
+
Authie.config.session_inactivity_timeout.ago).each(&:invalidate!)
|
129
|
+
# Invalidate persistent sessions that have expired
|
130
|
+
active.where('expires_at IS NOT NULL AND expires_at < ?', Time.now).each(&:invalidate!)
|
131
|
+
Authie.config.events.dispatch(:after_cleanup)
|
132
|
+
true
|
133
|
+
end
|
134
|
+
|
135
|
+
# Return a hash of a given token
|
136
|
+
def hash_token(token)
|
137
|
+
Digest::SHA256.hexdigest(token)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
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, :
|
6
|
+
base.has_many :user_sessions, class_name: 'Authie::SessionModel', as: :user, dependent: :delete_all
|
6
7
|
end
|
7
|
-
|
8
8
|
end
|
9
9
|
end
|
data/lib/authie/version.rb
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Authie
|
2
|
-
|
4
|
+
VERSION_FILE_ROOT = File.expand_path('../../VERSION', __dir__)
|
5
|
+
VERSION = if File.file?(VERSION_FILE_ROOT)
|
6
|
+
File.read(VERSION_FILE_ROOT).strip.sub(/\Av/, '')
|
7
|
+
else
|
8
|
+
'0.0.0.dev'
|
9
|
+
end
|
3
10
|
end
|
data/lib/authie.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: authie
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0.rc3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Cooke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '8.0'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '5.0'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '8.0'
|
13
33
|
- !ruby/object:Gem::Dependency
|
14
34
|
name: secure_random_string
|
15
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -24,6 +44,194 @@ dependencies:
|
|
24
44
|
- - ">="
|
25
45
|
- !ruby/object:Gem::Version
|
26
46
|
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: appraisal
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - '='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.4.1
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 2.4.1
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: rails
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '5.0'
|
68
|
+
- - "<"
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '8.0'
|
71
|
+
type: :development
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '5.0'
|
78
|
+
- - "<"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '8.0'
|
81
|
+
- !ruby/object:Gem::Dependency
|
82
|
+
name: rspec
|
83
|
+
requirement: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - ">="
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
- !ruby/object:Gem::Dependency
|
96
|
+
name: rspec-core
|
97
|
+
requirement: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
- !ruby/object:Gem::Dependency
|
110
|
+
name: rspec-expectations
|
111
|
+
requirement: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
type: :development
|
117
|
+
prerelease: false
|
118
|
+
version_requirements: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
- !ruby/object:Gem::Dependency
|
124
|
+
name: rspec-mocks
|
125
|
+
requirement: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - ">="
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
type: :development
|
131
|
+
prerelease: false
|
132
|
+
version_requirements: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - ">="
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
- !ruby/object:Gem::Dependency
|
138
|
+
name: rspec-rails
|
139
|
+
requirement: !ruby/object:Gem::Requirement
|
140
|
+
requirements:
|
141
|
+
- - ">="
|
142
|
+
- !ruby/object:Gem::Version
|
143
|
+
version: '0'
|
144
|
+
type: :development
|
145
|
+
prerelease: false
|
146
|
+
version_requirements: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: '0'
|
151
|
+
- !ruby/object:Gem::Dependency
|
152
|
+
name: rubocop
|
153
|
+
requirement: !ruby/object:Gem::Requirement
|
154
|
+
requirements:
|
155
|
+
- - '='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: 1.17.0
|
158
|
+
type: :development
|
159
|
+
prerelease: false
|
160
|
+
version_requirements: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - '='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: 1.17.0
|
165
|
+
- !ruby/object:Gem::Dependency
|
166
|
+
name: simplecov
|
167
|
+
requirement: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
type: :development
|
173
|
+
prerelease: false
|
174
|
+
version_requirements: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - ">="
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '0'
|
179
|
+
- !ruby/object:Gem::Dependency
|
180
|
+
name: simplecov-console
|
181
|
+
requirement: !ruby/object:Gem::Requirement
|
182
|
+
requirements:
|
183
|
+
- - ">="
|
184
|
+
- !ruby/object:Gem::Version
|
185
|
+
version: '0'
|
186
|
+
type: :development
|
187
|
+
prerelease: false
|
188
|
+
version_requirements: !ruby/object:Gem::Requirement
|
189
|
+
requirements:
|
190
|
+
- - ">="
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
version: '0'
|
193
|
+
- !ruby/object:Gem::Dependency
|
194
|
+
name: solargraph
|
195
|
+
requirement: !ruby/object:Gem::Requirement
|
196
|
+
requirements:
|
197
|
+
- - ">="
|
198
|
+
- !ruby/object:Gem::Version
|
199
|
+
version: '0'
|
200
|
+
type: :development
|
201
|
+
prerelease: false
|
202
|
+
version_requirements: !ruby/object:Gem::Requirement
|
203
|
+
requirements:
|
204
|
+
- - ">="
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: '0'
|
207
|
+
- !ruby/object:Gem::Dependency
|
208
|
+
name: sqlite3
|
209
|
+
requirement: !ruby/object:Gem::Requirement
|
210
|
+
requirements:
|
211
|
+
- - '='
|
212
|
+
- !ruby/object:Gem::Version
|
213
|
+
version: 1.4.2
|
214
|
+
type: :development
|
215
|
+
prerelease: false
|
216
|
+
version_requirements: !ruby/object:Gem::Requirement
|
217
|
+
requirements:
|
218
|
+
- - '='
|
219
|
+
- !ruby/object:Gem::Version
|
220
|
+
version: 1.4.2
|
221
|
+
- !ruby/object:Gem::Dependency
|
222
|
+
name: timecop
|
223
|
+
requirement: !ruby/object:Gem::Requirement
|
224
|
+
requirements:
|
225
|
+
- - ">="
|
226
|
+
- !ruby/object:Gem::Version
|
227
|
+
version: '0'
|
228
|
+
type: :development
|
229
|
+
prerelease: false
|
230
|
+
version_requirements: !ruby/object:Gem::Requirement
|
231
|
+
requirements:
|
232
|
+
- - ">="
|
233
|
+
- !ruby/object:Gem::Version
|
234
|
+
version: '0'
|
27
235
|
description: A Rails library for storing user sessions in a backend database
|
28
236
|
email:
|
29
237
|
- me@adamcooke.io
|
@@ -47,6 +255,7 @@ files:
|
|
47
255
|
- lib/authie/event_manager.rb
|
48
256
|
- lib/authie/rack_controller.rb
|
49
257
|
- lib/authie/session.rb
|
258
|
+
- lib/authie/session_model.rb
|
50
259
|
- lib/authie/user.rb
|
51
260
|
- lib/authie/version.rb
|
52
261
|
homepage: https://github.com/adamcooke/authie
|
@@ -64,11 +273,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
64
273
|
version: '0'
|
65
274
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
66
275
|
requirements:
|
67
|
-
- - "
|
276
|
+
- - ">"
|
68
277
|
- !ruby/object:Gem::Version
|
69
|
-
version:
|
278
|
+
version: 1.3.1
|
70
279
|
requirements: []
|
71
|
-
rubygems_version: 3.
|
280
|
+
rubygems_version: 3.3.7
|
72
281
|
signing_key:
|
73
282
|
specification_version: 4
|
74
283
|
summary: A Rails library for storing user sessions in a backend database
|