authie 3.3.2 → 4.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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, :class_name => 'Authie::Session', :as => :user, :dependent => :delete_all
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
@@ -1,3 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authie
2
- VERSION = '3.3.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
@@ -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)
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: 3.3.2
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: 2020-09-25 00:00:00.000000000 Z
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: '0'
278
+ version: 1.3.1
70
279
  requirements: []
71
- rubygems_version: 3.0.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