padlock_auth-jwt 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 76622de62cd8065e302932783de9a3c02bff49880ec8f376fcdeed84cce97223
4
+ data.tar.gz: 460cb25344c8150779ad54a189a8d9ec371c63ae7bd1adf4b3b9af3183deca62
5
+ SHA512:
6
+ metadata.gz: 39e6d74dbedae4ca68c3cef9a19bc3bcc8a4d2307877f2b557c616fd56ea4815e0e176726bb1a539141a2eb66b6c0bc503dce1160d290f4802f7cb2a4f928e2d
7
+ data.tar.gz: 4f3e41598b073669229e2de1da5543801e7b1182976dbdb67e84260af17215bb1245160da24a580bdd31454060d671f5a61b0510908983c31246c9eb3ec6ab0a
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright Ben Morrall
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # PadlockAuth::Jwt
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem "padlock_auth-jwt"
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install padlock_auth-jwt
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/setup"
2
+
3
+ require "bundler/gem_tasks"
4
+
5
+ require "rspec/core/rake_task"
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "standard/rake"
9
+
10
+ task default: %i[
11
+ spec
12
+ standard
13
+ ]
@@ -0,0 +1,22 @@
1
+ en:
2
+ padlock_auth:
3
+ errors:
4
+ messages:
5
+ invalid_token:
6
+ invalid_jwt_token: "The access token is not a valid JWT."
7
+ invalid_signature: "The access token has an invalid signature."
8
+ missing_exp_claim: "The access token is missing a required exp claim."
9
+ missing_nbf_claim: "The access token is missing a required nbf claim."
10
+ missing_iss_claim: "The access token is missing a required iss claim."
11
+ missing_aud_claim: "The access token is missing a required aud claim."
12
+ missing_jti_claim: "The access token is missing a required jti claim."
13
+ missing_iat_claim: "The access token is missing a required iat claim."
14
+ missing_sub_claim: "The access token is missing a required sub claim."
15
+ invalid_exp_claim: "The access token has expired."
16
+ invalid_nbf_claim: "The access token is not yet valid."
17
+ invalid_iss_claim: "The access token is from an unknown issuer."
18
+ invalid_jti_claim: "The access token was revoked."
19
+ invalid_sub_claim: "The access token is for a different subject."
20
+ forbidden_token:
21
+ invalid_jwt_token: "The access token is not a valid JWT."
22
+ invalid_aud_claim: 'Access to this resource requires audience "%{oauth_scopes}".'
@@ -0,0 +1,171 @@
1
+ require "jwt"
2
+
3
+ module PadlockAuth
4
+ module Jwt
5
+ class AccessToken < PadlockAuth::AbstractAccessToken
6
+ def initialize(jwt, strategy)
7
+ @jwt = jwt
8
+ @encoded_token = JWT::EncodedToken.new(jwt)
9
+ @strategy = strategy
10
+ end
11
+
12
+ def accessible?
13
+ return false unless valid_jwt_token?
14
+
15
+ return false unless valid_signature?
16
+
17
+ return false unless includes_required_claims?
18
+
19
+ # "exp" (Expiration Time) Claim
20
+ return false unless valid_exp_claim?
21
+
22
+ # "nbf" (Not Before) Claim
23
+ return false unless valid_nbf_claim?
24
+
25
+ # "iss" (Issuer) Claim
26
+ return false unless valid_iss_claim?
27
+
28
+ # "jti" (JWT ID) Claim
29
+ return false unless valid_jti_claim?
30
+
31
+ # "sub" (Subject) Claim
32
+ return false unless valid_sub_claim?
33
+
34
+ true
35
+ end
36
+
37
+ def invalid_token_reason
38
+ return :invalid_jwt_token unless valid_jwt_token?
39
+ return :invalid_signature unless valid_signature?
40
+
41
+ return :missing_exp_claim unless includes_required_exp_claim?
42
+ return :invalid_exp_claim unless valid_exp_claim?
43
+
44
+ return :missing_nbf_claim unless includes_required_nbf_claim?
45
+ return :invalid_nbf_claim unless valid_nbf_claim?
46
+
47
+ return :missing_iss_claim unless includes_required_iss_claim?
48
+ return :invalid_iss_claim unless valid_iss_claim?
49
+
50
+ return :missing_aud_claim unless includes_required_aud_claim?
51
+ # validity checked by #includes_scope?
52
+
53
+ return :missing_jti_claim unless includes_required_jti_claim?
54
+ return :invalid_jti_claim unless valid_jti_claim?
55
+
56
+ return :missing_iat_claim unless includes_required_iat_claim?
57
+
58
+ return :missing_sub_claim unless includes_required_sub_claim?
59
+ return :invalid_sub_claim unless valid_sub_claim?
60
+
61
+ super # :unknown
62
+ end
63
+
64
+ def includes_scope?(required_scopes)
65
+ return false unless valid_jwt_token?
66
+
67
+ required_scopes.none? || valid_aud_claim?(required_scopes.map(&:to_s))
68
+ end
69
+
70
+ def forbidden_token_reason
71
+ return :invalid_jwt_token unless valid_jwt_token?
72
+
73
+ :invalid_aud_claim
74
+ end
75
+
76
+ def header
77
+ @encoded_token.header if valid_jwt_token?
78
+ end
79
+
80
+ def payload
81
+ @encoded_token.payload if valid_jwt_token?
82
+ end
83
+
84
+ private
85
+
86
+ # https://datatracker.ietf.org/doc/html/rfc9068#JWTATLValidate
87
+ # The resource server MUST verify that the "typ" header value is "at+jwt" or "application/at+jwt" and reject tokens carrying any other value.
88
+ def valid_jwt_token?
89
+ return @valid_jwt_token if instance_variable_defined?(:@valid_jwt_token)
90
+ @valid_jwt_token = @encoded_token.header.present? &&
91
+ @strategy.header_types.include?(@encoded_token.header["typ"])
92
+ rescue JWT::DecodeError
93
+ @valid_jwt_token = false
94
+ end
95
+
96
+ def valid_signature?
97
+ return @valid_signature if instance_variable_defined?(:@valid_signature)
98
+ @valid_signature = @encoded_token.valid_signature?(algorithm: @strategy.algorithm, key: @strategy.secret_key)
99
+ end
100
+
101
+ def includes_required_claims?
102
+ includes_required_exp_claim? &&
103
+ includes_required_nbf_claim? &&
104
+ includes_required_iss_claim? &&
105
+ includes_required_aud_claim? &&
106
+ includes_required_jti_claim? &&
107
+ includes_required_iat_claim? &&
108
+ includes_required_sub_claim?
109
+ end
110
+
111
+ def includes_required_exp_claim?
112
+ !@strategy.exp_required? || @encoded_token.valid_claims?(required: ["exp"])
113
+ end
114
+
115
+ def includes_required_nbf_claim?
116
+ !@strategy.nbf_required? || @encoded_token.valid_claims?(required: ["nbf"])
117
+ end
118
+
119
+ def includes_required_iss_claim?
120
+ !@strategy.iss_required? || @encoded_token.valid_claims?(required: ["iss"])
121
+ end
122
+
123
+ def includes_required_aud_claim?
124
+ !@strategy.aud_required? || @encoded_token.valid_claims?(required: ["aud"])
125
+ end
126
+
127
+ def includes_required_jti_claim?
128
+ !@strategy.jti_required? || @encoded_token.valid_claims?(required: ["jti"])
129
+ end
130
+
131
+ def includes_required_iat_claim?
132
+ !@strategy.iat_required? || @encoded_token.valid_claims?(required: ["iat"])
133
+ end
134
+
135
+ def includes_required_sub_claim?
136
+ !@strategy.sub_required? || @encoded_token.valid_claims?(required: ["sub"])
137
+ end
138
+
139
+ def valid_exp_claim?
140
+ return @valid_exp_claim if instance_variable_defined?(:@valid_exp_claim)
141
+ @valid_exp_claim = @encoded_token.valid_claims?(exp: {leeway: @strategy.expiry_leeway})
142
+ end
143
+
144
+ def valid_nbf_claim?
145
+ return @valid_nbf_claim if instance_variable_defined?(:@valid_nbf_claim)
146
+ @valid_nbf_claim = @encoded_token.valid_claims?(nbf: {leeway: @strategy.not_before_leeway})
147
+ end
148
+
149
+ def valid_iss_claim?
150
+ return @valid_iss_claim if instance_variable_defined?(:@valid_iss_claim)
151
+ @valid_iss_claim = @strategy.issuers.none? || @encoded_token.valid_claims?(iss: @strategy.issuers)
152
+ end
153
+
154
+ def valid_aud_claim?(required_scopes)
155
+ @encoded_token.valid_claims?(aud: required_scopes.map(&:to_s))
156
+ end
157
+
158
+ def valid_jti_claim?
159
+ return @valid_jti_claim if instance_variable_defined?(:@valid_jti_claim)
160
+ @valid_jti_claim = @encoded_token.valid_claims?(jti: @strategy.verify_jti)
161
+ end
162
+
163
+ def valid_sub_claim?
164
+ return true if @strategy.subject.blank?
165
+
166
+ return @valid_sub_claim if instance_variable_defined?(:@valid_sub_claim)
167
+ @valid_sub_claim = @encoded_token.valid_claims?(sub: @strategy.subject)
168
+ end
169
+ end
170
+ end
171
+ end
@@ -0,0 +1,25 @@
1
+ module PadlockAuth
2
+ module Jwt
3
+ module Errors
4
+ # Invalid Token errors
5
+
6
+ class InvalidSignature < PadlockAuth::Errors::InvalidToken; end
7
+
8
+ class MissingRequiredClaim < PadlockAuth::Errors::InvalidToken; end
9
+
10
+ class InvalidExpClaim < PadlockAuth::Errors::TokenExpired; end
11
+
12
+ class InvalidNbfClaim < PadlockAuth::Errors::InvalidToken; end
13
+
14
+ class InvalidIssClaim < PadlockAuth::Errors::InvalidToken; end
15
+
16
+ class InvalidJtiClaim < PadlockAuth::Errors::TokenRevoked; end
17
+
18
+ class InvalidSubClaim < PadlockAuth::Errors::InvalidToken; end
19
+
20
+ # Forbidden Token errors
21
+
22
+ class InvalidAudClaim < PadlockAuth::Errors::TokenForbidden; end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ module PadlockAuth
2
+ module Jwt
3
+ module Http
4
+ # Adds JWT specific errors to the ForbiddenTokenResponse
5
+ class ForbiddenTokenResponse < PadlockAuth::Http::ForbiddenTokenResponse
6
+ protected
7
+
8
+ def exception_class
9
+ PadlockAuth::Jwt::Errors::InvalidAudClaim
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,35 @@
1
+ module PadlockAuth
2
+ module Jwt
3
+ module Http
4
+ # Adds JWT specific errors to the InvalidTokenResponse
5
+ class InvalidTokenResponse < PadlockAuth::Http::InvalidTokenResponse
6
+ protected
7
+
8
+ def exception_class
9
+ jwt_errors_mapping.fetch(reason) { super }
10
+ end
11
+
12
+ private
13
+
14
+ def jwt_errors_mapping
15
+ {
16
+ invalid_signature: PadlockAuth::Jwt::Errors::InvalidSignature,
17
+ missing_exp_claim: PadlockAuth::Jwt::Errors::MissingRequiredClaim,
18
+ missing_nbf_claim: PadlockAuth::Jwt::Errors::MissingRequiredClaim,
19
+ missing_iss_claim: PadlockAuth::Jwt::Errors::MissingRequiredClaim,
20
+ missing_aud_claim: PadlockAuth::Jwt::Errors::MissingRequiredClaim,
21
+ missing_jti_claim: PadlockAuth::Jwt::Errors::MissingRequiredClaim,
22
+ missing_iat_claim: PadlockAuth::Jwt::Errors::MissingRequiredClaim,
23
+ missing_sub_claim: PadlockAuth::Jwt::Errors::MissingRequiredClaim,
24
+ invalid_exp_claim: PadlockAuth::Jwt::Errors::InvalidExpClaim,
25
+ invalid_nbf_claim: PadlockAuth::Jwt::Errors::InvalidNbfClaim,
26
+ invalid_iss_claim: PadlockAuth::Jwt::Errors::InvalidIssClaim,
27
+ invalid_jti_claim: PadlockAuth::Jwt::Errors::InvalidJtiClaim,
28
+ invalid_sub_claim: PadlockAuth::Jwt::Errors::InvalidSubClaim
29
+
30
+ }
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,9 @@
1
+ module PadlockAuthJwt
2
+ class Railtie < ::Rails::Railtie
3
+ initializer "padlock_auth-jwt.i18n" do
4
+ Dir.glob(File.join(File.dirname(__FILE__), "..", "..", "..", "config", "locales", "*.yml")).each do |file|
5
+ I18n.load_path << File.expand_path(file)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,208 @@
1
+ module PadlockAuth
2
+ module Jwt
3
+ class Strategy < PadlockAuth::AbstractStrategy
4
+ include PadlockAuth::Mixins::BuildWith
5
+
6
+ class Builder < PadlockAuth::Utils::AbstractBuilder
7
+ def nbf_leeway(nbf_leeway)
8
+ not_before_leeway(nbf_leeway)
9
+ end
10
+ end
11
+
12
+ build_with Builder
13
+
14
+ extend PadlockAuth::Config::Option
15
+
16
+ # Token Factory
17
+
18
+ def build_access_token(raw_token)
19
+ Jwt::AccessToken.new(raw_token, self)
20
+ end
21
+
22
+ # HTTP Responses
23
+
24
+ def build_invalid_token_response(access_token)
25
+ Jwt::Http::InvalidTokenResponse.from_access_token(access_token)
26
+ end
27
+
28
+ def build_forbidden_token_response(access_token, scopes)
29
+ Jwt::Http::ForbiddenTokenResponse.from_access_token(access_token, scopes)
30
+ end
31
+
32
+ # Signature
33
+
34
+ option :secret_key
35
+
36
+ # https://datatracker.ietf.org/doc/html/rfc7518#section-3.1
37
+ option :algorithm, default: "RS256"
38
+
39
+ # "typ" (Type) Header Parameter
40
+ #
41
+ # RFC9068 registers the "application/at+jwt" media type, which can be used to
42
+ # indicate that the content is a JWT access token. JWT access tokens MUST include this media
43
+ # type in the "typ" header parameter to explicitly declare that the JWT represents an access
44
+ # token complying with this profile.
45
+
46
+ # https://datatracker.ietf.org/doc/html/rfc9068#JWTATLValidate
47
+ REQUIRED_HEADER_TYPES = ["at+jwt", "application/at+jwt"]
48
+
49
+ option :header_types, default: REQUIRED_HEADER_TYPES
50
+
51
+ def header_types
52
+ Array.wrap(@header_types || REQUIRED_HEADER_TYPES)
53
+ end
54
+
55
+ # "exp" (Expiration Time) Claim
56
+ #
57
+ # The "exp" (expiration time) claim identifies the expiration time on
58
+ # or after which the JWT MUST NOT be accepted for processing. The
59
+ # processing of the "exp" claim requires that the current date/time
60
+ # MUST be before the expiration date/time listed in the "exp" claim.
61
+ #
62
+ # Implementers MAY provide for some small leeway, usually no more than
63
+ # a few minutes, to account for clock skew. Its value MUST be a number
64
+ # containing a NumericDate value. Use of this claim is OPTIONAL.
65
+
66
+ # @!attribute require_exp [r] Boolean
67
+ option :require_exp, default: true
68
+
69
+ def exp_required?
70
+ !!require_exp
71
+ end
72
+
73
+ option :expiry_leeway, default: 0
74
+
75
+ # "nbf" (Not Before) Claim
76
+ #
77
+ # The "nbf" (not before) claim identifies the time before which the JWT
78
+ # MUST NOT be accepted for processing. The processing of the "nbf"
79
+ # claim requires that the current date/time MUST be after or equal to
80
+ # the not-before date/time listed in the "nbf" claim. Implementers MAY
81
+ # provide for some small leeway, usually no more than a few minutes, to
82
+ # account for clock skew. Its value MUST be a number containing a
83
+ # NumericDate value. Use of this claim is OPTIONAL.
84
+
85
+ option :require_nbf, default: false
86
+
87
+ def nbf_required?
88
+ !!require_nbf
89
+ end
90
+
91
+ option :not_before_leeway, default: 0
92
+
93
+ # "iss" (Issuer) Claim
94
+ #
95
+ # The "iss" (issuer) claim identifies the principal that issued the
96
+ # JWT. The processing of this claim is generally application specific.
97
+ # The "iss" value is a case-sensitive string containing a StringOrURI
98
+ # value. Use of this claim is OPTIONAL.
99
+
100
+ # @!attribute require_iss [r] Boolean
101
+ option :require_iss, default: false
102
+
103
+ def iss_required?
104
+ !!require_iss
105
+ end
106
+
107
+ option :issuers, default: nil
108
+
109
+ def issuers
110
+ Array.wrap(@issuers)
111
+ end
112
+
113
+ # "aud" (Audience) Claim
114
+ #
115
+ # The "aud" (audience) claim identifies the recipients that the JWT is
116
+ # intended for. Each principal intended to process the JWT MUST
117
+ # identify itself with a value in the audience claim. If the principal
118
+ # processing the claim does not identify itself with a value in the
119
+ # "aud" claim when this claim is present, then the JWT MUST be
120
+ # rejected. In the general case, the "aud" value is an array of case-
121
+ # sensitive strings, each containing a StringOrURI value. In the
122
+ # special case when the JWT has one audience, the "aud" value MAY be a
123
+ # single case-sensitive string containing a StringOrURI value. The
124
+ # interpretation of audience values is generally application specific.
125
+ # Use of this claim is OPTIONAL.
126
+
127
+ option :require_aud, default: true
128
+
129
+ def aud_required?
130
+ !!require_aud
131
+ end
132
+
133
+ # "jti" (JWT ID) Claim
134
+ #
135
+ # The "jti" (JWT ID) claim provides a unique identifier for the JWT.
136
+ # The identifier value MUST be assigned in a manner that ensures that
137
+ # there is a negligible probability that the same value will be
138
+ # accidentally assigned to a different data object; if the application
139
+ # uses multiple issuers, collisions MUST be prevented among values
140
+ # produced by different issuers as well. The "jti" claim can be used
141
+ # to prevent the JWT from being replayed. The "jti" value is a case-
142
+ # sensitive string. Use of this claim is OPTIONAL.
143
+
144
+ option :require_jti, default: true
145
+
146
+ def jti_required?
147
+ !!require_jti
148
+ end
149
+
150
+ option :verify_jti, default: proc { true }
151
+
152
+ # "iat" (Issued At) Claim
153
+ #
154
+ # The "iat" (issued at) claim identifies the time at which the JWT was
155
+ # issued. This claim can be used to determine the age of the JWT. Its
156
+ # value MUST be a number containing a NumericDate value. Use of this
157
+ # claim is OPTIONAL.
158
+
159
+ option :require_iat, default: true
160
+
161
+ def iat_required?
162
+ !!require_iat
163
+ end
164
+
165
+ # "sub" (Subject) Claim
166
+ #
167
+ # The "sub" (subject) claim identifies the principal that is the
168
+ # subject of the JWT. The claims in a JWT are normally statements
169
+ # about the subject. The subject value MUST either be scoped to be
170
+ # locally unique in the context of the issuer or be globally unique.
171
+ # The processing of this claim is generally application specific. The
172
+ # "sub" value is a case-sensitive string containing a StringOrURI
173
+ # value. Use of this claim is OPTIONAL.
174
+
175
+ option :require_sub, default: true
176
+
177
+ def sub_required?
178
+ !!require_sub
179
+ end
180
+
181
+ option :subject, default: nil
182
+
183
+ def subject
184
+ Array.wrap(@subject)
185
+ end
186
+
187
+ # Builder Validation
188
+
189
+ def validate!
190
+ raise ArgumentError, "secret_key is required" unless secret_key.present?
191
+
192
+ raise ArgumentError, "algorithm is required" unless algorithm.present?
193
+
194
+ raise ArgumentError, "header_types cannot be empty" unless header_types.present?
195
+
196
+ if subject.present? && !sub_required?
197
+ raise ArgumentError, "subject is not required"
198
+ end
199
+
200
+ if iss_required? && issuers.blank?
201
+ raise ArgumentError, "issuers are required when require_iss is true"
202
+ end
203
+
204
+ true
205
+ end
206
+ end
207
+ end
208
+ end
@@ -0,0 +1,5 @@
1
+ module PadlockAuth
2
+ module Jwt
3
+ VERSION = "0.1.0"
4
+ end
5
+ end
@@ -0,0 +1,18 @@
1
+ require "padlock_auth"
2
+
3
+ require "padlock_auth/jwt/version"
4
+ require "padlock_auth/jwt/errors"
5
+
6
+ module PadlockAuth
7
+ module Jwt
8
+ autoload :AccessToken, "padlock_auth/jwt/access_token"
9
+ autoload :Strategy, "padlock_auth/jwt/strategy"
10
+
11
+ module Http
12
+ autoload :InvalidTokenResponse, "padlock_auth/jwt/http/invalid_token_response"
13
+ autoload :ForbiddenTokenResponse, "padlock_auth/jwt/http/forbidden_token_response"
14
+ end
15
+ end
16
+ end
17
+
18
+ require "padlock_auth/jwt/railtie"
@@ -0,0 +1 @@
1
+ require "padlock_auth/jwt"
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :padlock_auth_jwt do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: padlock_auth-jwt
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Ben Morrall
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2024-12-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: padlock_auth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: jwt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 2.9.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 2.9.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec-rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: standard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 1.41.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: 1.41.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Allows API endpoints to be secured by a JWT Access Token.
84
+ email:
85
+ - bemo56@hotmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - MIT-LICENSE
91
+ - README.md
92
+ - Rakefile
93
+ - config/locales/padlock_auth-jwt.en.yml
94
+ - lib/padlock_auth-jwt.rb
95
+ - lib/padlock_auth/jwt.rb
96
+ - lib/padlock_auth/jwt/access_token.rb
97
+ - lib/padlock_auth/jwt/errors.rb
98
+ - lib/padlock_auth/jwt/http/forbidden_token_response.rb
99
+ - lib/padlock_auth/jwt/http/invalid_token_response.rb
100
+ - lib/padlock_auth/jwt/railtie.rb
101
+ - lib/padlock_auth/jwt/strategy.rb
102
+ - lib/padlock_auth/jwt/version.rb
103
+ - lib/tasks/padlock_auth/jwt_tasks.rake
104
+ homepage: https://github.com/bmorrall/padlock_auth-jwt
105
+ licenses:
106
+ - MIT
107
+ metadata:
108
+ homepage_uri: https://github.com/bmorrall/padlock_auth-jwt
109
+ source_code_uri: https://github.com/bmorrall/padlock_auth-jwt
110
+ changelog_uri: https://github.com/bmorrall/padlock_auth-jwt/main/CHANGELOG.md
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubygems_version: 3.5.17
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: Adds JWT Support to PadlockAuth.
130
+ test_files: []