jwt-authenticator 1.0.4 → 2.0.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/.ruby-version +1 -1
- data/Gemfile.lock +9 -9
- data/lib/jwt-authenticator.rb +24 -19
- data/lib/jwt-authenticator/version.rb +1 -1
- data/test/test-jwt-authenticator.rb +11 -17
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 707fad532a2bd87b7ab6a9e7839cd61789d53024a18f7b4849d5fbb6e44eb16c
|
4
|
+
data.tar.gz: 8e020e5ca4feac5e69dd276d93d8bce8b17928a75e0e20f2d4743656e33072cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c4868783d0751eeeda6c5e4c7ecab2f5b9c36f4b61881d82332b3bdd20e10a683265a4f9e8c05bc671ab4951e2dd7f25a91441e4f6ce6f438f6209c1ce548b9c
|
7
|
+
data.tar.gz: c90110f5b22510a4ce50630dea91a6f2ebb7cf711098f5e6500c27255b31aa8bcb55f734f07fffce52348aeb038eebe43ef0c4358870fcca0c890848343c8e21
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.7.
|
1
|
+
2.7.3
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
jwt-authenticator (
|
4
|
+
jwt-authenticator (2.0.0)
|
5
5
|
activesupport (>= 4.0, < 6.0)
|
6
6
|
jwt (~> 2.1)
|
7
7
|
method-not-implemented (~> 1.0)
|
@@ -9,23 +9,23 @@ PATH
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
activesupport (5.2.
|
12
|
+
activesupport (5.2.6)
|
13
13
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
14
|
i18n (>= 0.7, < 2)
|
15
15
|
minitest (~> 5.1)
|
16
16
|
tzinfo (~> 1.1)
|
17
|
-
concurrent-ruby (1.1.
|
18
|
-
i18n (1.8.
|
17
|
+
concurrent-ruby (1.1.9)
|
18
|
+
i18n (1.8.10)
|
19
19
|
concurrent-ruby (~> 1.0)
|
20
|
-
jwt (2.2.
|
20
|
+
jwt (2.2.3)
|
21
21
|
method-not-implemented (1.0.1)
|
22
|
-
minitest (5.14.
|
23
|
-
power_assert (
|
22
|
+
minitest (5.14.4)
|
23
|
+
power_assert (2.0.0)
|
24
24
|
rake (12.3.3)
|
25
|
-
test-unit (3.
|
25
|
+
test-unit (3.4.4)
|
26
26
|
power_assert
|
27
27
|
thread_safe (0.3.6)
|
28
|
-
tzinfo (1.2.
|
28
|
+
tzinfo (1.2.9)
|
29
29
|
thread_safe (~> 0.1)
|
30
30
|
|
31
31
|
PLATFORMS
|
data/lib/jwt-authenticator.rb
CHANGED
@@ -18,15 +18,19 @@ class JWT::Authenticator
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def call(token)
|
21
|
-
error!
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
error! type: :token_missing unless token.present?
|
22
|
+
|
23
|
+
returned = JWT.decode token, nil, true, @verification_options do |header|
|
24
|
+
public_key(header.deep_symbolize_keys)
|
25
|
+
end
|
26
|
+
|
25
27
|
returned.map(&:deep_symbolize_keys)
|
28
|
+
|
26
29
|
rescue JWT::ExpiredSignature => e
|
27
|
-
error!
|
30
|
+
error! message: e.inspect, type: :token_expired
|
31
|
+
|
28
32
|
rescue JWT::DecodeError => e
|
29
|
-
error!
|
33
|
+
error! message: e.inspect, type: :token_invalid
|
30
34
|
end
|
31
35
|
|
32
36
|
protected
|
@@ -37,7 +41,8 @@ protected
|
|
37
41
|
|
38
42
|
def token_verification_options_from_environment(namespace)
|
39
43
|
namespace = namespace.gsub(/_+\z/, "")
|
40
|
-
|
44
|
+
options = {
|
45
|
+
verify_expiration: ENV["#{namespace}_VERIFY_EXP"] != "false",
|
41
46
|
verify_not_before: ENV["#{namespace}_VERIFY_NBF"] != "false",
|
42
47
|
iss: ENV["#{namespace}_ISS"].to_s.split(",").map(&:squish).reject(&:blank?).presence, # Comma-separated values.
|
43
48
|
verify_iat: ENV["#{namespace}_VERIFY_IAT"] != "false",
|
@@ -49,16 +54,16 @@ protected
|
|
49
54
|
iat_leeway: ENV["#{namespace}_IAT_LEEWAY"].to_s.squish.yield_self { |n| n.to_i if n.present? },
|
50
55
|
exp_leeway: ENV["#{namespace}_EXP_LEEWAY"].to_s.squish.yield_self { |n| n.to_i if n.present? },
|
51
56
|
nbf_leeway: ENV["#{namespace}_NBF_LEEWAY"].to_s.squish.yield_self { |n| n.to_i if n.present? }
|
52
|
-
}
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
57
|
+
}
|
58
|
+
options.merge! \
|
59
|
+
verify_sub: options[:sub].present?,
|
60
|
+
verify_iss: options[:iss].present?,
|
61
|
+
verify_aud: options[:aud].present?
|
62
|
+
options.compact
|
58
63
|
end
|
59
64
|
|
60
|
-
def error!(
|
61
|
-
raise Error.new(
|
65
|
+
def error!(**options)
|
66
|
+
raise Error.new(**options)
|
62
67
|
end
|
63
68
|
|
64
69
|
class << self
|
@@ -68,11 +73,11 @@ protected
|
|
68
73
|
end
|
69
74
|
|
70
75
|
class Error < StandardError
|
71
|
-
attr_reader :
|
76
|
+
attr_reader :type
|
72
77
|
|
73
|
-
def initialize(message,
|
74
|
-
super
|
75
|
-
@
|
78
|
+
def initialize(message: nil, type:)
|
79
|
+
super message.presence || type.to_s.humanize
|
80
|
+
@type = type
|
76
81
|
end
|
77
82
|
end
|
78
83
|
end
|
@@ -76,13 +76,7 @@ class JWTAuthenticatorTest < Test::Unit::TestCase
|
|
76
76
|
test "blank token" do
|
77
77
|
error = assert_raises(JWT::Authenticator::Error) { JWT::Authenticator.instance.call(" ") }
|
78
78
|
assert_match(/\bmissing\b/i, error.message)
|
79
|
-
assert_equal(
|
80
|
-
end
|
81
|
-
|
82
|
-
test "token with invalid type" do
|
83
|
-
error = assert_raises(JWT::Authenticator::Error) { JWT::Authenticator.instance.call("Beer XXX.YYY.ZZZ") }
|
84
|
-
assert_match(/\binvalid\b/i, error.message)
|
85
|
-
assert_equal(102, error.code)
|
79
|
+
assert_equal(:token_missing, error.type)
|
86
80
|
end
|
87
81
|
|
88
82
|
test "token decoding and verification" do
|
@@ -96,63 +90,63 @@ class JWTAuthenticatorTest < Test::Unit::TestCase
|
|
96
90
|
jwt = my_api_v2_jwt_encode(my_api_v2_jwt_payload.merge(iss: "qux"))
|
97
91
|
error = assert_raises(JWT::Authenticator::Error) { my_api_v2_jwt_decode(jwt) }
|
98
92
|
assert_match(/\binvalid issuer\b/i, error.message)
|
99
|
-
assert_equal(
|
93
|
+
assert_equal(:token_invalid, error.type)
|
100
94
|
end
|
101
95
|
|
102
96
|
test "missing iss" do
|
103
97
|
jwt = my_api_v2_jwt_encode(my_api_v2_jwt_payload.tap { |p| p.delete(:iss) })
|
104
98
|
error = assert_raises(JWT::Authenticator::Error) { my_api_v2_jwt_decode(jwt) }
|
105
99
|
assert_match(/\binvalid issuer\b/i, error.message)
|
106
|
-
assert_equal(
|
100
|
+
assert_equal(:token_invalid, error.type)
|
107
101
|
end
|
108
102
|
|
109
103
|
test "missing aud" do
|
110
104
|
jwt = my_api_v2_jwt_encode(my_api_v2_jwt_payload.tap { |p| p.delete(:aud) })
|
111
105
|
error = assert_raises(JWT::Authenticator::Error) { my_api_v2_jwt_decode(jwt) }
|
112
106
|
assert_match(/\binvalid audience\b/i, error.message)
|
113
|
-
assert_equal(
|
107
|
+
assert_equal(:token_invalid, error.type)
|
114
108
|
end
|
115
109
|
|
116
110
|
test "wrong aud" do
|
117
111
|
jwt = my_api_v2_jwt_encode(my_api_v2_jwt_payload.merge(aud: "qux"))
|
118
112
|
error = assert_raises(JWT::Authenticator::Error) { my_api_v2_jwt_decode(jwt) }
|
119
113
|
assert_match(/\binvalid audience\b/i, error.message)
|
120
|
-
assert_equal(
|
114
|
+
assert_equal(:token_invalid, error.type)
|
121
115
|
end
|
122
116
|
|
123
117
|
test "missing sub" do
|
124
118
|
jwt = my_api_v2_jwt_encode(my_api_v2_jwt_payload.tap { |p| p.delete(:sub) })
|
125
119
|
error = assert_raises(JWT::Authenticator::Error) { my_api_v2_jwt_decode(jwt) }
|
126
120
|
assert_match(/\binvalid subject\b/i, error.message)
|
127
|
-
assert_equal(
|
121
|
+
assert_equal(:token_invalid, error.type)
|
128
122
|
end
|
129
123
|
|
130
124
|
test "wrong sub" do
|
131
125
|
jwt = my_api_v2_jwt_encode(my_api_v2_jwt_payload.merge(sub: "qux"))
|
132
126
|
error = assert_raises(JWT::Authenticator::Error) { my_api_v2_jwt_decode(jwt) }
|
133
127
|
assert_match(/\binvalid subject\b/i, error.message)
|
134
|
-
assert_equal(
|
128
|
+
assert_equal(:token_invalid, error.type)
|
135
129
|
end
|
136
130
|
|
137
131
|
test "token is expired" do
|
138
132
|
jwt = my_api_v2_jwt_encode(my_api_v2_jwt_payload.merge(exp: Time.now.to_i - 5))
|
139
133
|
error = assert_raises(JWT::Authenticator::Error) { my_api_v2_jwt_decode(jwt) }
|
140
134
|
assert_match(/\bexpired\b/i, error.message)
|
141
|
-
assert_equal(
|
135
|
+
assert_equal(:token_expired, error.type)
|
142
136
|
end
|
143
137
|
|
144
138
|
test "missing jti" do
|
145
139
|
jwt = my_api_v2_jwt_encode(my_api_v2_jwt_payload.tap { |p| p.delete(:jti) })
|
146
140
|
error = assert_raises(JWT::Authenticator::Error) { my_api_v2_jwt_decode(jwt) }
|
147
141
|
assert_match(/\bmissing jti\b/i, error.message)
|
148
|
-
assert_equal(
|
142
|
+
assert_equal(:token_invalid, error.type)
|
149
143
|
end
|
150
144
|
|
151
145
|
test "issued at in future" do
|
152
146
|
jwt = my_api_v2_jwt_encode(my_api_v2_jwt_payload.merge(iat: Time.now.to_i + 30))
|
153
147
|
error = assert_raises(JWT::Authenticator::Error) { my_api_v2_jwt_decode(jwt) }
|
154
148
|
assert_match(/\binvalid iat\b/i, error.message)
|
155
|
-
assert_equal(
|
149
|
+
assert_equal(:token_invalid, error.type)
|
156
150
|
end
|
157
151
|
|
158
152
|
test "loading token verification options from environment (authenticator nested under multiple modules)" do
|
@@ -185,6 +179,6 @@ private
|
|
185
179
|
end
|
186
180
|
|
187
181
|
def my_api_v2_jwt_decode(jwt)
|
188
|
-
MyAPIv2::JWTAuthenticator.call(
|
182
|
+
MyAPIv2::JWTAuthenticator.call(jwt)
|
189
183
|
end
|
190
184
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt-authenticator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yaroslav Konoplov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jwt
|
@@ -115,7 +115,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
115
115
|
- !ruby/object:Gem::Version
|
116
116
|
version: '0'
|
117
117
|
requirements: []
|
118
|
-
rubygems_version: 3.1.
|
118
|
+
rubygems_version: 3.1.6
|
119
119
|
signing_key:
|
120
120
|
specification_version: 4
|
121
121
|
summary: JSON Web Token authentication Ruby service.
|