tiddle 1.0.2 → 1.1.0
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 +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
|