jwt_keeper 6.0.0 → 6.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 +4 -4
- data/jwt_keeper.gemspec +2 -1
- data/lib/generators/templates/jwt_keeper.rb +2 -4
- data/lib/jwt_keeper/datastore.rb +26 -13
- data/lib/jwt_keeper/version.rb +1 -1
- data/spec/lib/jwt_keeper/datastore_spec.rb +78 -41
- data/spec/spec_helper.rb +3 -1
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d6ad212dc01831b9bae31adab98ba2edbe1fd803923e32eb9817e2b96515c706
|
4
|
+
data.tar.gz: c6ef8deb150ffeed569d4da108ac745a907c8bfc065c5564cd49b6aff978f00e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87f73d56ceb956a78337d4df685ac8fb86b6eda03046ba137f92f689eb10b5485103f9ea003ccdb7643149b4e74722d674571ec698e8eed40eb0a2d3b1b2feb2
|
7
|
+
data.tar.gz: 7695c3ce514f9e150d492766b90e7b76e04cb5c496e422aa265d6f255a311e72d986319f169fc0bb5919a42fbe4cb364da700bfeb42fb947bfdb9a6841c5c280
|
data/jwt_keeper.gemspec
CHANGED
@@ -28,8 +28,9 @@ Gem::Specification.new do |spec|
|
|
28
28
|
spec.add_development_dependency 'rspec', '~> 3.8'
|
29
29
|
spec.add_development_dependency 'fuubar'
|
30
30
|
spec.add_development_dependency 'simplecov'
|
31
|
+
spec.add_development_dependency 'redis-client'
|
32
|
+
spec.add_development_dependency 'redis'
|
31
33
|
|
32
|
-
spec.add_dependency 'redis'
|
33
34
|
spec.add_dependency 'rails'
|
34
35
|
spec.add_dependency 'activesupport'
|
35
36
|
spec.add_dependency 'jwt', '>= 1.5'
|
@@ -27,10 +27,8 @@ JWTKeeper.configure do |config|
|
|
27
27
|
# config.audience = 'example.com'
|
28
28
|
|
29
29
|
# the location of redis config file
|
30
|
-
# config.redis_connection =
|
31
|
-
# config.redis_connection =
|
32
|
-
# Redis.new(url: ENV['REDISCLOUD_URL'] || 'redis://localhost:6379/')
|
33
|
-
# end
|
30
|
+
# config.redis_connection = RedisClient.new(connection_options)
|
31
|
+
# config.redis_connection = RedisClient.config(connection_options).new_pool(size: ENV.fetch('RAILS_MAX_THREADS', 5))
|
34
32
|
|
35
33
|
# A unique idenfitier for the token version.
|
36
34
|
# config.version = 1
|
data/lib/jwt_keeper/datastore.rb
CHANGED
@@ -27,27 +27,40 @@ module JWTKeeper
|
|
27
27
|
|
28
28
|
# @!visibility private
|
29
29
|
def set_with_expiry(jti, seconds, type)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
redis.setex
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
30
|
+
with_redis do |redis|
|
31
|
+
if redis.respond_to?(:call) # For RedisClient
|
32
|
+
redis.call('SETEX', jti, seconds, type)
|
33
|
+
elsif redis.respond_to?(:setex) # For Redis
|
34
|
+
redis.setex(jti, seconds, type)
|
35
|
+
else
|
36
|
+
throw 'Bad Redis Connection'
|
37
|
+
end
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
# @!visibility private
|
42
42
|
def get(jti)
|
43
|
+
with_redis do |redis|
|
44
|
+
if redis.respond_to?(:call) # For RedisClient
|
45
|
+
redis.call('GET', jti)
|
46
|
+
elsif redis.respond_to?(:get) # For Redis
|
47
|
+
redis.get(jti)
|
48
|
+
else
|
49
|
+
throw 'Bad Redis Connection'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# @!visibility private
|
55
|
+
def with_redis
|
43
56
|
redis = JWTKeeper.configuration.redis_connection
|
44
57
|
|
45
|
-
if redis.
|
46
|
-
redis.
|
47
|
-
|
48
|
-
|
58
|
+
if redis.respond_to?(:with)
|
59
|
+
redis.with do |conn|
|
60
|
+
yield conn
|
61
|
+
end
|
49
62
|
else
|
50
|
-
|
63
|
+
yield(redis)
|
51
64
|
end
|
52
65
|
end
|
53
66
|
end
|
data/lib/jwt_keeper/version.rb
CHANGED
@@ -1,70 +1,107 @@
|
|
1
1
|
RSpec.describe JWTKeeper::Datastore do
|
2
|
-
include_context 'initialize config'
|
3
2
|
let(:jti) { SecureRandom.uuid }
|
4
3
|
|
5
|
-
|
6
|
-
|
4
|
+
shared_examples 'Datastore Specs' do
|
5
|
+
describe '.rotate' do
|
6
|
+
before { described_class.rotate(jti, 30) }
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
it 'stores a token_id with a soft expiry' do
|
9
|
+
expect(described_class.send(:get, jti)).to eq 'soft'
|
10
|
+
end
|
10
11
|
end
|
11
|
-
end
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
13
|
+
describe '.pending?' do
|
14
|
+
context 'with a missing token' do
|
15
|
+
it 'returns false' do
|
16
|
+
expect(described_class.pending?(jti)).to be false
|
17
|
+
end
|
17
18
|
end
|
18
|
-
end
|
19
19
|
|
20
|
-
|
21
|
-
|
20
|
+
context 'with a revoked token' do
|
21
|
+
before { described_class.revoke(jti, 30) }
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
it 'returns false' do
|
24
|
+
expect(described_class.pending?(jti)).to be false
|
25
|
+
end
|
25
26
|
end
|
26
|
-
end
|
27
27
|
|
28
|
-
|
29
|
-
|
28
|
+
context 'with a pending token' do
|
29
|
+
before { described_class.rotate(jti, 30) }
|
30
30
|
|
31
|
-
|
32
|
-
|
31
|
+
it 'returns true' do
|
32
|
+
expect(described_class.pending?(jti)).to be true
|
33
|
+
end
|
33
34
|
end
|
34
35
|
end
|
35
|
-
end
|
36
36
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
describe '.revoke' do
|
38
|
+
before do
|
39
|
+
described_class.revoke(jti, 30)
|
40
|
+
end
|
41
41
|
|
42
|
-
|
43
|
-
|
42
|
+
it 'stores a token_id with a hard expiry' do
|
43
|
+
expect(described_class.send(:get, jti)).to eq 'hard'
|
44
|
+
end
|
44
45
|
end
|
45
|
-
end
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
47
|
+
describe '.revoked?' do
|
48
|
+
context 'with a missing token' do
|
49
|
+
it 'returns false' do
|
50
|
+
expect(described_class.revoked?(jti)).to be false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'with a revoked token' do
|
55
|
+
before { described_class.revoke(jti, 30) }
|
56
|
+
|
57
|
+
it 'returns true' do
|
58
|
+
expect(described_class.revoked?(jti)).to be true
|
59
|
+
end
|
51
60
|
end
|
52
|
-
end
|
53
61
|
|
54
|
-
|
55
|
-
|
62
|
+
context 'with a pending token' do
|
63
|
+
before { described_class.rotate(jti, 30) }
|
56
64
|
|
57
|
-
|
58
|
-
|
65
|
+
it 'returns false' do
|
66
|
+
expect(described_class.revoked?(jti)).to be false
|
67
|
+
end
|
59
68
|
end
|
60
69
|
end
|
70
|
+
end
|
61
71
|
|
62
|
-
|
63
|
-
|
72
|
+
context 'with Redis' do
|
73
|
+
include_context 'initialize config'
|
74
|
+
|
75
|
+
let(:redis_connection) { Redis.new(url: ENV['REDIS_URL']) }
|
76
|
+
|
77
|
+
include_examples 'Datastore Specs'
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'with Redis Connection Pool' do
|
81
|
+
include_context 'initialize config'
|
64
82
|
|
65
|
-
|
66
|
-
|
83
|
+
let(:redis_connection) do
|
84
|
+
ConnectionPool.new(size: ENV.fetch('RAILS_MAX_THREADS', 5)) do
|
85
|
+
Redis.new(url: ENV['REDISCLOUD_URL'] || 'redis://localhost:6379/')
|
67
86
|
end
|
68
87
|
end
|
88
|
+
|
89
|
+
include_examples 'Datastore Specs'
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'with RedisClient' do
|
93
|
+
include_context 'initialize config'
|
94
|
+
|
95
|
+
let(:redis_connection) { RedisClient.new(url: ENV['REDIS_URL']) }
|
96
|
+
|
97
|
+
include_examples 'Datastore Specs'
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'with RedisClient Pool' do
|
101
|
+
include_context 'initialize config'
|
102
|
+
|
103
|
+
let(:redis_connection) { RedisClient.config(url: ENV['REDIS_URL']).new_pool(size: ENV.fetch('RAILS_MAX_THREADS', 5)) }
|
104
|
+
|
105
|
+
include_examples 'Datastore Specs'
|
69
106
|
end
|
70
107
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -39,6 +39,7 @@ RSpec.configure do |config|
|
|
39
39
|
end
|
40
40
|
|
41
41
|
RSpec.shared_context 'initialize config' do
|
42
|
+
let(:redis_connection) { RedisClient.new(url: ENV['REDIS_URL']) }
|
42
43
|
let(:config) do
|
43
44
|
{
|
44
45
|
algorithm: 'HS256',
|
@@ -46,12 +47,13 @@ RSpec.shared_context 'initialize config' do
|
|
46
47
|
expiry: 24.hours,
|
47
48
|
issuer: 'api.example.com',
|
48
49
|
audience: 'example.com',
|
49
|
-
redis_connection:
|
50
|
+
redis_connection: redis_connection,
|
50
51
|
version: nil,
|
51
52
|
cookie_lock: false
|
52
53
|
}
|
53
54
|
end
|
54
55
|
|
56
|
+
|
55
57
|
before(:each) do
|
56
58
|
JWTKeeper.configure(JWTKeeper::Configuration.new(config))
|
57
59
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt_keeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.
|
4
|
+
version: 6.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Rivera
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-02-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -137,6 +137,20 @@ dependencies:
|
|
137
137
|
- - ">="
|
138
138
|
- !ruby/object:Gem::Version
|
139
139
|
version: '0'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: redis-client
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
140
154
|
- !ruby/object:Gem::Dependency
|
141
155
|
name: redis
|
142
156
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,7 +158,7 @@ dependencies:
|
|
144
158
|
- - ">="
|
145
159
|
- !ruby/object:Gem::Version
|
146
160
|
version: '0'
|
147
|
-
type: :
|
161
|
+
type: :development
|
148
162
|
prerelease: false
|
149
163
|
version_requirements: !ruby/object:Gem::Requirement
|
150
164
|
requirements:
|
@@ -249,7 +263,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
249
263
|
- !ruby/object:Gem::Version
|
250
264
|
version: '0'
|
251
265
|
requirements: []
|
252
|
-
rubygems_version: 3.
|
266
|
+
rubygems_version: 3.4.1
|
253
267
|
signing_key:
|
254
268
|
specification_version: 4
|
255
269
|
summary: JWT for Rails made easy
|