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 +5 -5
- data/.rubocop.yml +2 -0
- data/.travis.yml +2 -0
- data/CHANGELOG.md +7 -0
- data/README.md +7 -1
- data/lib/tiddle.rb +2 -2
- data/lib/tiddle/strategy.rb +8 -1
- data/lib/tiddle/token_issuer.rb +20 -9
- data/lib/tiddle/version.rb +1 -1
- data/spec/rails_app/config/application.rb +0 -2
- data/spec/rails_app/db/migrate/20150217000000_create_tables.rb +1 -0
- data/spec/strategy_spec.rb +38 -0
- data/tiddle.gemspec +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 636a498dc602f9309c1baf81f3f34276aad7e710fd14d170c02ba5af381b40f1
|
4
|
+
data.tar.gz: 670f3801abc579331c721d66ee5cf68e46817a89bdadfc6356d0f02ce0276176
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5305d3d877befdee9203d7001f05e07ef38a3ad77abcc74563140f2217f69319d39d723be4453410b1935ed01a839995e8c296c767349b2355657b36ba7532b
|
7
|
+
data.tar.gz: c114628903a18817a6a99ab3e233639d4e2c428e7216c06e46eed4407aac243f89533db8cae5edf05335d351c4903ea3559da60e1b42821b3c98ffdbf984eb0b
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -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
|
+
```
|
data/lib/tiddle.rb
CHANGED
@@ -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)
|
data/lib/tiddle/strategy.rb
CHANGED
@@ -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
|
data/lib/tiddle/token_issuer.rb
CHANGED
@@ -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
|
-
|
21
|
-
|
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.
|
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
|
data/lib/tiddle/version.rb
CHANGED
@@ -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
|
|
data/spec/strategy_spec.rb
CHANGED
@@ -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
|
data/tiddle.gemspec
CHANGED
@@ -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.
|
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
|
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:
|
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.
|
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.
|
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.
|
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
|