tiddle 1.0.2 → 1.1.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
- SHA1:
3
- metadata.gz: 1fa66626fb86bdb8e5e02ff35478ba8429a8f416
4
- data.tar.gz: 6cc2d9b7fb7f389a2345eb7c3eef23cb9d580b2f
2
+ SHA256:
3
+ metadata.gz: 636a498dc602f9309c1baf81f3f34276aad7e710fd14d170c02ba5af381b40f1
4
+ data.tar.gz: 670f3801abc579331c721d66ee5cf68e46817a89bdadfc6356d0f02ce0276176
5
5
  SHA512:
6
- metadata.gz: bc942083526221652b791dd9fd8f69cded955daa2f542dc7089def991997f503f08331690ec11b35d232a782d7e16bd3dfc3c964a13886044799d77e73f7d9b9
7
- data.tar.gz: e5b5d147c14bc589affe4bae4623352e0f77d7be8210312f563e1d672f1eb5d3b2fa347f545ea809ac43722a5f9a141075e34e3c24d9643812c0b5ff81c063c6
6
+ metadata.gz: d5305d3d877befdee9203d7001f05e07ef38a3ad77abcc74563140f2217f69319d39d723be4453410b1935ed01a839995e8c296c767349b2355657b36ba7532b
7
+ data.tar.gz: c114628903a18817a6a99ab3e233639d4e2c428e7216c06e46eed4407aac243f89533db8cae5edf05335d351c4903ea3559da60e1b42821b3c98ffdbf984eb0b
@@ -26,3 +26,5 @@ Naming/FileName:
26
26
  Metrics/BlockLength:
27
27
  Exclude:
28
28
  - 'spec/**/*'
29
+ Metrics/MethodLength:
30
+ Max: 15
@@ -1,8 +1,10 @@
1
1
  language: ruby
2
+ before_install: gem update --system
2
3
  rvm:
3
4
  - "2.2.8"
4
5
  - "2.3.5"
5
6
  - "2.4.2"
7
+ - "2.5.0"
6
8
  gemfile:
7
9
  - "gemfiles/rails4.2.gemfile"
8
10
  - "gemfiles/rails5.0.gemfile"
@@ -1,3 +1,10 @@
1
+ ### 1.1.0
2
+
3
+ New feature: optional token expiration after period of inactivity - #37
4
+
5
+ You have to add `expires_in` field to the database table holding the tokens
6
+ to benefit from this feature.
7
+
1
8
  ### 1.0.0
2
9
 
3
10
  No major changes - just a stable version release.
data/README.md CHANGED
@@ -40,7 +40,7 @@ end
40
40
  2) Generate the model which stores authentication tokens. The model name is not important, but the Devise-enabled model should have association called ```authentication_tokens```.
41
41
 
42
42
  ```
43
- rails g model AuthenticationToken body:string user:references last_used_at:datetime ip_address:string user_agent:string
43
+ rails g model AuthenticationToken body:string:index user:references last_used_at:datetime expires_in:integer ip_address:string user_agent:string
44
44
  ```
45
45
 
46
46
  ```ruby
@@ -111,3 +111,9 @@ Change ```config.authentication_keys``` in Devise intitializer and Tiddle will u
111
111
  Usually it makes sense to remove user's tokens after a password change. Depending on the project and on your taste, this can be done using various methods like running `user.authentication_tokens.destroy_all` after the password change or with an `after_save` callback in your model which runs `authentication_tokens.destroy_all if encrypted_password_changed?`.
112
112
 
113
113
  In case of a security breach, remove all existing tokens.
114
+
115
+ Tokens are expiring after certain period of inactivity. This behavior is optional. If you want your token to expire, create it passing `expires_in` option:
116
+
117
+ ```ruby
118
+ token = Tiddle.create_and_return_token(user, request, expires_in: 1.month)
119
+ ```
@@ -5,8 +5,8 @@ require "tiddle/rails"
5
5
  require "tiddle/token_issuer"
6
6
 
7
7
  module Tiddle
8
- def self.create_and_return_token(resource, request)
9
- TokenIssuer.build.create_and_return_token(resource, request)
8
+ def self.create_and_return_token(resource, request, options = {})
9
+ TokenIssuer.build.create_and_return_token(resource, request, options)
10
10
  end
11
11
 
12
12
  def self.expire_token(resource, request)
@@ -12,7 +12,7 @@ module Devise
12
12
  return fail(:invalid_token) unless resource
13
13
 
14
14
  token = Tiddle::TokenIssuer.build.find_token(resource, token_from_headers)
15
- if token
15
+ if token && unexpired?(token)
16
16
  touch_token(token)
17
17
  return success!(resource)
18
18
  end
@@ -51,6 +51,13 @@ module Devise
51
51
  def touch_token(token)
52
52
  token.update_attribute(:last_used_at, Time.current) if token.last_used_at < 1.hour.ago
53
53
  end
54
+
55
+ def unexpired?(token)
56
+ return true unless token.respond_to?(:expires_in)
57
+ return true if token.expires_in.blank? || token.expires_in.zero?
58
+
59
+ Time.current <= token.last_used_at + token.expires_in
60
+ end
54
61
  end
55
62
  end
56
63
  end
@@ -12,15 +12,13 @@ module Tiddle
12
12
  self.maximum_tokens_per_user = maximum_tokens_per_user
13
13
  end
14
14
 
15
- def create_and_return_token(resource, request)
15
+ def create_and_return_token(resource, request, expires_in: nil)
16
16
  token_class = authentication_token_class(resource)
17
17
  token, token_body = Devise.token_generator.generate(token_class, :body)
18
18
 
19
- resource.authentication_tokens
20
- .create! body: token_body,
21
- last_used_at: Time.current,
22
- ip_address: request.remote_ip,
23
- user_agent: request.user_agent
19
+ resource.authentication_tokens.create!(
20
+ token_attributes(token_body, request, expires_in)
21
+ )
24
22
 
25
23
  token
26
24
  end
@@ -33,9 +31,7 @@ module Tiddle
33
31
  def find_token(resource, token_from_headers)
34
32
  token_class = authentication_token_class(resource)
35
33
  token_body = Devise.token_generator.digest(token_class, :body, token_from_headers)
36
- resource.authentication_tokens.detect do |token|
37
- Devise.secure_compare(token.body, token_body)
38
- end
34
+ resource.authentication_tokens.find_by(body: token_body)
39
35
  end
40
36
 
41
37
  def purge_old_tokens(resource)
@@ -52,5 +48,20 @@ module Tiddle
52
48
  def authentication_token_class(resource)
53
49
  resource.association(:authentication_tokens).klass
54
50
  end
51
+
52
+ def token_attributes(token_body, request, expires_in)
53
+ attributes = {
54
+ body: token_body,
55
+ last_used_at: Time.current,
56
+ ip_address: request.remote_ip,
57
+ user_agent: request.user_agent
58
+ }
59
+
60
+ if expires_in
61
+ attributes.merge(expires_in: expires_in)
62
+ else
63
+ attributes
64
+ end
65
+ end
55
66
  end
56
67
  end
@@ -1,3 +1,3 @@
1
1
  module Tiddle
2
- VERSION = "1.0.2".freeze
2
+ VERSION = "1.1.0".freeze
3
3
  end
@@ -1,10 +1,8 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
2
 
3
3
  require "active_model/railtie"
4
- require "active_job/railtie"
5
4
  require "active_record/railtie"
6
5
  require "action_controller/railtie"
7
- require "action_mailer/railtie"
8
6
  require "action_view/railtie"
9
7
 
10
8
  module RailsApp
@@ -56,6 +56,7 @@ class CreateTables < migration_class
56
56
  t.string :body, null: false
57
57
  t.references :authenticatable, null: false, polymorphic: true
58
58
  t.datetime :last_used_at, null: false
59
+ t.integer :expires_in, null: false, default: 0
59
60
  t.string :ip_address
60
61
  t.string :user_agent
61
62
 
@@ -159,4 +159,42 @@ describe "Authentication using Tiddle strategy", type: :request do
159
159
  expect(response.status).to eq 200
160
160
  end
161
161
  end
162
+
163
+ context "when token has expires_in set up" do
164
+ before do
165
+ @user = User.create!(email: "test@example.com", password: "12345678")
166
+ @token = Tiddle.create_and_return_token(@user, FakeRequest.new, expires_in: 1.week)
167
+ end
168
+
169
+ describe "token is not expired" do
170
+ it "does allow to access endpoints which require authentication" do
171
+ warningless_get(
172
+ secrets_path,
173
+ headers: {
174
+ "X-USER-EMAIL" => "test@example.com",
175
+ "X-USER-TOKEN" => @token
176
+ }
177
+ )
178
+ expect(response.status).to eq 200
179
+ end
180
+ end
181
+
182
+ describe "token is expired" do
183
+ before do
184
+ token = @user.authentication_tokens.order(:id).last
185
+ token.update_attribute(:last_used_at, 1.month.ago)
186
+ end
187
+
188
+ it "does not allow to access endpoints which require authentication" do
189
+ warningless_get(
190
+ secrets_path,
191
+ headers: {
192
+ "X-USER-EMAIL" => "test@example.com",
193
+ "X-USER-TOKEN" => @token
194
+ }
195
+ )
196
+ expect(response.status).to eq 401
197
+ end
198
+ end
199
+ end
162
200
  end
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
 
19
19
  spec.required_ruby_version = '>= 2.2.0'
20
20
 
21
- spec.add_dependency "devise", ">= 4.0.0.rc1", "< 4.4"
21
+ spec.add_dependency "devise", ">= 4.0.0.rc1", "< 4.5"
22
22
  spec.add_dependency "activerecord", ">= 4.2.0"
23
23
  spec.add_development_dependency "bundler", "~> 1.7"
24
24
  spec.add_development_dependency "rake", "~> 12.0"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tiddle
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Niedzielski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-14 00:00:00.000000000 Z
11
+ date: 2018-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: devise
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: 4.0.0.rc1
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '4.4'
22
+ version: '4.5'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,7 @@ dependencies:
29
29
  version: 4.0.0.rc1
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '4.4'
32
+ version: '4.5'
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: activerecord
35
35
  requirement: !ruby/object:Gem::Requirement
@@ -224,7 +224,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
224
224
  version: '0'
225
225
  requirements: []
226
226
  rubyforge_project:
227
- rubygems_version: 2.6.13
227
+ rubygems_version: 2.7.3
228
228
  signing_key:
229
229
  specification_version: 4
230
230
  summary: Token authentication for Devise which supports multiple tokens per model