grape-jwt-authentication 1.1.0 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff7b66cbce6da2abf8a94f05de6e1193c28609ee3603c7373a7b189f1e9b67d4
4
- data.tar.gz: 29f400c994e453466570810c10c1fcc6d674074a1edf5c2a3f8d282146c3e9fa
3
+ metadata.gz: 8e9342b70db03baa2d358176c7a95c64ce06d60905245dc68939059ce5fc853a
4
+ data.tar.gz: '025155931791462ef7afc5366410ed3426bb8a5f15d3d4a641c7e70d232da84b'
5
5
  SHA512:
6
- metadata.gz: 4f7b6a29dbe8c3e6fe6e230efd52605b3729757b77ad47d2ead3d27f88f022d63d0f65a4eb11cbf99c5b23490331b1489d077e5ba49c7dd876b2843d05eeb269
7
- data.tar.gz: d6235df2c6853433ed4a056eb2ddddeb84a2d64355fceac52181916afd6039a61c832f4a75b2283517f5abd2b3cdd40428ee007ba83babe0cc8f54692764a189
6
+ metadata.gz: 86cbd40f1df368f4836638dff6ee80c12c8a70aa0b7f3a39a763a7aa28b4bdf3a878634f5a8bb05bb91094e3d838e1f61b216dac84a84f17afa403bb69950820
7
+ data.tar.gz: 1c12302d38a2fb246db94353a4c55db7fa40f3717f0ba90ab7fe1e5391e926f7c8ac7cef2f710a79338260726c16bcad0b65c048719c0a9c05d51ded9f835475
data/.gitignore CHANGED
@@ -6,6 +6,7 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ /Gemfile.lock
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
@@ -1,14 +1,13 @@
1
1
  env:
2
2
  global:
3
- - CC_TEST_REPORTER_ID=6e5d2de1ccc0412cdc8d01fdddc560fe3051b14f1c15fea55b0d6e32e27a81cf
3
+ - CC_TEST_REPORTER_ID=ecb753423174dbd8e4aaf04fb62bf4ef9c2a54904ac49a33fdf2b908b3c5e5f3
4
4
 
5
5
  sudo: false
6
6
  language: ruby
7
7
  rvm:
8
+ - 2.6
8
9
  - 2.5
9
10
  - 2.4
10
- - 2.3
11
- - 2.2
12
11
 
13
12
  before_install: gem install bundler
14
13
 
@@ -1,3 +1,34 @@
1
+ ### 2.0.2
2
+
3
+ * Corrected some documentation glitches
4
+
5
+ ### 2.0.1
6
+
7
+ * Corrected a migration bug on the configuration which used the wrong namespace
8
+ for `RsaPublicKey` (resulted in `uninitialized constant
9
+ Grape::Jwt::Authentication::Configuration::RsaPublicKey`)
10
+
11
+ ### 2.0.0
12
+
13
+ * Extracted the JWT verification functionality into its own gem
14
+ ([keyless](https://github.com/hausgold/keyless)) (#6)
15
+ * This extraction allows users to use the JWT/RSA key handling without Grape
16
+ * The API/configuration stays the same
17
+ * With the major update to 2.0 we dropped a lot of code which is now located at
18
+ the Keyless gem:
19
+ * `Grape::Jwt::Authentication::Jwt` was replace with `Keyless::Jwt`
20
+ * `Grape::Jwt::Authentication::RsaPublicKey` was replace with `Keyless::RsaPublicKey`
21
+
22
+ ### 1.3.0
23
+
24
+ * Dropped support for EOL Ruby 2.3 (in addition to Grape)
25
+
26
+ ### 1.2.0
27
+
28
+ * Check the remote response on public key fetching (#3)
29
+ * Added support for Ruby 2.6
30
+ * Dropped support for EOL Ruby 2.2
31
+
1
32
  ### 1.1.0
2
33
 
3
34
  * Added the parsed and original token to the Rack environment (#2)
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
- ![grape-jwt-authentication](doc/assets/project.png)
1
+ ![grape-jwt-authentication](doc/assets/project.svg)
2
2
 
3
- [![Build Status](https://travis-ci.org/hausgold/grape-jwt-authentication.svg?branch=master)](https://travis-ci.org/hausgold/grape-jwt-authentication)
3
+ [![Build Status](https://travis-ci.com/hausgold/grape-jwt-authentication.svg?branch=master)](https://travis-ci.com/hausgold/grape-jwt-authentication)
4
4
  [![Gem Version](https://badge.fury.io/rb/grape-jwt-authentication.svg)](https://badge.fury.io/rb/grape-jwt-authentication)
5
- [![Maintainability](https://api.codeclimate.com/v1/badges/446f3eff18bebff9c174/maintainability)](https://codeclimate.com/github/hausgold/grape-jwt-authentication/maintainability)
6
- [![Test Coverage](https://api.codeclimate.com/v1/badges/446f3eff18bebff9c174/test_coverage)](https://codeclimate.com/github/hausgold/grape-jwt-authentication/test_coverage)
5
+ [![Maintainability](https://api.codeclimate.com/v1/badges/ab14a3bab572edfbf305/maintainability)](https://codeclimate.com/repos/5cac8bc06c282f791c009a66/maintainability)
6
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/ab14a3bab572edfbf305/test_coverage)](https://codeclimate.com/repos/5cac8bc06c282f791c009a66/test_coverage)
7
7
  [![API docs](https://img.shields.io/badge/docs-API-blue.svg)](https://www.rubydoc.info/gems/grape-jwt-authentication)
8
8
 
9
9
  This gem is dedicated to easily integrate a JWT authentication to your
@@ -185,18 +185,18 @@ have your own mechanism.
185
185
 
186
186
  ```ruby
187
187
  # Get your public key, by using the global configuration
188
- public_key = Grape::Jwt::Authentication::RsaPublicKey.fetch
188
+ public_key = Keyless::RsaPublicKey.fetch
189
189
  # => OpenSSL::PKey::RSA
190
190
 
191
191
  # Using a local configuration
192
- fetcher = Grape::Jwt::Authentication::RsaPublicKey.instance
192
+ fetcher = Keyless::RsaPublicKey.instance
193
193
  fetcher.url = 'https://your.identity.provider/rsa_public_key'
194
194
  public_key = fetcher.fetch
195
195
  # => OpenSSL::PKey::RSA
196
196
  ```
197
197
 
198
198
  The following examples show you how to configure the
199
- `Grape::Jwt::Authentication::RsaPublicKey` class the global way. This is useful
199
+ `Keyless::RsaPublicKey` class the global way. This is useful
200
200
  for a shared initializer place.
201
201
 
202
202
  ##### RSA public key location (URL)
@@ -261,7 +261,7 @@ the `RsaPublicKey` fetcher class. (by default)
261
261
  raw_token = 'eyJ0eXAiOiJKV1QifQ.eyJ0ZXN0Ijp0cnVlfQ.'
262
262
 
263
263
  # Parse the raw token and create a instance of it
264
- token = Grape::Jwt::Authentication::Jwt.new(raw_token)
264
+ token = Keyless::Jwt.new(raw_token)
265
265
 
266
266
  # Access the payload easily (recursive-open-struct)
267
267
  token.payload.test
@@ -274,7 +274,7 @@ token.valid?
274
274
  ```
275
275
 
276
276
  The following examples show you how to configure the
277
- `Grape::Jwt::Authentication::Jwt` class the global way. This is useful for a
277
+ `Keyless::Jwt` class the global way. This is useful for a
278
278
  shared initializer place.
279
279
 
280
280
  ##### Issuer verification
@@ -305,7 +305,7 @@ end
305
305
  You can configure a different JSON Web Token verification option hash if your
306
306
  algorithm differs or you want some extra/different options. Just watch out
307
307
  that you have to pass a proc to this configuration property. On the
308
- `Grape::Jwt::Authentication::Jwt` class it has to be a simple hash. The default
308
+ `Keyless::Jwt` class it has to be a simple hash. The default
309
309
  is here the `RS256` algorithm with enabled expiration check, and issuer+audience
310
310
  check when the `jwt_issuer` / `jwt_beholder` are configured accordingly.
311
311
 
@@ -323,7 +323,7 @@ end
323
323
  You can configure your own verification key on the `Jwt` wrapper class. This
324
324
  way you can pass your HMAC secret or your ECDSA public key to the JSON Web
325
325
  Token validation method. Here you need to pass a proc, on the
326
- `Grape::Jwt::Authentication::Jwt` class it has to be a scalar value. By default
326
+ `Keyless::Jwt` class it has to be a scalar value. By default
327
327
  we use the `RsaPublicKey` class to retrieve the RSA public key.
328
328
 
329
329
  ```ruby
@@ -394,7 +394,7 @@ Grape::Jwt::Authentication.configure do |conf|
394
394
  # Custom verification logic.
395
395
  conf.authenticator = proc do |token|
396
396
  # Parse and instantiate a JWT verification instance
397
- jwt = Grape::Jwt::Authentication::Jwt.new(token)
397
+ jwt = Keyless::Jwt.new(token)
398
398
 
399
399
  # We just allow valid access tokens
400
400
  jwt.access_token? && jwt.valid?
@@ -0,0 +1,68 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg
3
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
4
+ xmlns:cc="http://creativecommons.org/ns#"
5
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
6
+ xmlns:svg="http://www.w3.org/2000/svg"
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ version="1.1"
9
+ id="Ebene_1"
10
+ x="0px"
11
+ y="0px"
12
+ viewBox="0 0 800 200"
13
+ xml:space="preserve"
14
+ width="800"
15
+ height="200"><metadata
16
+ id="metadata33"><rdf:RDF><cc:Work
17
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
18
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
19
+ id="defs31" />
20
+ <style
21
+ type="text/css"
22
+ id="style2">
23
+ .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#E73E11;}
24
+ .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#0371B9;}
25
+ .st2{fill:#132E48;}
26
+ .st3{font-family:'OpenSans-Bold';}
27
+ .st4{font-size:29.5168px;}
28
+ .st5{fill-rule:evenodd;clip-rule:evenodd;fill:none;}
29
+ .st6{opacity:0.5;fill:#132E48;}
30
+ .st7{font-family:'OpenSans';}
31
+ .st8{font-size:12px;}
32
+ </style>
33
+ <g
34
+ transform="translate(0,1.53584)"
35
+ id="g828"><g
36
+ transform="translate(35.93985,35.66416)"
37
+ id="g8">
38
+ <path
39
+ style="clip-rule:evenodd;fill:#e73e11;fill-rule:evenodd"
40
+ id="path4"
41
+ d="m -0.1,124.4 c 0,0 33.7,-123.2 66.7,-123.2 12.8,0 26.9,21.9 38.8,47.2 -23.6,27.9 -66.6,59.7 -94,76 -7.1,0 -11.5,0 -11.5,0 z"
42
+ class="st0" />
43
+ <path
44
+ style="clip-rule:evenodd;fill:#0371b9;fill-rule:evenodd"
45
+ id="path6"
46
+ d="m 88.1,101.8 c 13.5,-10.4 18.4,-16.2 27.1,-25.4 10,25.7 16.7,48 16.7,48 0,0 -41.4,0 -78,0 14.6,-7.9 18.7,-10.7 34.2,-22.6 z"
47
+ class="st1" />
48
+ </g><text
49
+ y="106.40316"
50
+ x="192.43155"
51
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:29.51733398px;font-family:'Open Sans', sans-serif;-inkscape-font-specification:'OpenSans-Bold, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#132e48"
52
+ id="text10"
53
+ class="st2 st3 st4">grape-jwt-authentication</text>
54
+ <rect
55
+ style="clip-rule:evenodd;fill:none;fill-rule:evenodd"
56
+ id="rect12"
57
+ height="24"
58
+ width="314.5"
59
+ class="st5"
60
+ y="118.06416"
61
+ x="194.23985" /><text
62
+ y="127.22146"
63
+ x="194.21715"
64
+ style="font-size:12px;font-family:'Open Sans', sans-serif;opacity:0.5;fill:#132e48;-inkscape-font-specification:'Open Sans, sans-serif, Normal';font-weight:normal;font-style:normal;font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr;font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;"
65
+ id="text14"
66
+ class="st6 st7 st8">A reusable Grape JWT authentication concern</text>
67
+ </g>
68
+ </svg>
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ['lib']
23
23
 
24
- spec.add_development_dependency 'bundler', '~> 1.16'
24
+ spec.add_development_dependency 'bundler', '>= 1.16', '< 3'
25
25
  spec.add_development_dependency 'rack', '~> 2.0'
26
26
  spec.add_development_dependency 'rack-test', '~> 0.8.2'
27
27
  spec.add_development_dependency 'rake', '~> 10.0'
@@ -36,4 +36,5 @@ Gem::Specification.new do |spec|
36
36
  spec.add_runtime_dependency 'httparty'
37
37
  spec.add_runtime_dependency 'jwt', '~> 2.1'
38
38
  spec.add_runtime_dependency 'recursive-open-struct', '~> 1.0'
39
+ spec.add_runtime_dependency 'keyless', '~> 1.0'
39
40
  end
@@ -7,15 +7,13 @@ require 'active_support/cache'
7
7
  require 'active_support/core_ext/hash'
8
8
  require 'active_support/time'
9
9
  require 'active_support/time_with_zone'
10
-
11
10
  require 'jwt'
12
-
11
+ require 'keyless'
13
12
  require 'grape'
14
13
  require 'grape/jwt/authentication/version'
15
14
  require 'grape/jwt/authentication/configuration'
15
+ require 'grape/jwt/authentication/dependencies'
16
16
  require 'grape/jwt/authentication/jwt_handler'
17
- require 'grape/jwt/authentication/jwt'
18
- require 'grape/jwt/authentication/rsa_public_key'
19
17
 
20
18
  module Grape
21
19
  module Jwt
@@ -43,11 +41,13 @@ module Grape
43
41
  # end
44
42
  def self.configure
45
43
  yield(configuration)
44
+ configure_dependencies
46
45
  end
47
46
 
48
47
  # Reset the current configuration with the default one.
49
48
  def self.reset_configuration!
50
49
  self.configuration = Configuration.new
50
+ configure_dependencies
51
51
  end
52
52
 
53
53
  included do
@@ -65,7 +65,7 @@ module Grape
65
65
  # date, etc inside your API definition. When the authenticator stated
66
66
  # that the validation failed, then the parsed token is +nil+.
67
67
  #
68
- # @return [Grape::Jwt::Authentication::Jwt, nil] the parsed token
68
+ # @return [Keyless::Jwt, nil] the parsed token
69
69
  def request_jwt
70
70
  env['grape_jwt_auth.parsed_token']
71
71
  end
@@ -96,10 +96,10 @@ module Grape
96
96
  # You can configure a different JSON Web Token verification option hash
97
97
  # if your algorithm differs or you want some extra/different options.
98
98
  # Just watch out that you have to pass a proc to this configuration
99
- # property. On the {Grape::Jwt::Authentication::Jwt} class it has to be
100
- # a simple hash. The default is here the RS256 algorithm with enabled
101
- # expiration check, and issuer+audience check when the
102
- # {jwt_issuer}/{jwt_beholder} are configured accordingly.
99
+ # property. On the {Keyless::Jwt} class it has to be a simple hash. The
100
+ # default is here the RS256 algorithm with enabled expiration check,
101
+ # and issuer+audience check when the {jwt_issuer}/{jwt_beholder} are
102
+ # configured accordingly.
103
103
  config_accessor(:jwt_options) do
104
104
  proc do
105
105
  conf = Grape::Jwt::Authentication.configuration
@@ -117,12 +117,11 @@ module Grape
117
117
  # You can configure your own verification key on the Jwt wrapper class.
118
118
  # This way you can pass your HMAC secret or your ECDSA public key to
119
119
  # the JSON Web Token validation method. Here you need to pass a proc,
120
- # on the {Grape::Jwt::Authentication::Jwt} class it has to be a scalar
121
- # value. By default we use the
122
- # {Grape::Jwt::Authentication::RsaPublicKey} class to retrieve the RSA
123
- # public key.
120
+ # on the {Keyless::Jwt} class it has to be a scalar value. By default
121
+ # we use the {Keyless::RsaPublicKey} class to retrieve the RSA public
122
+ # key.
124
123
  config_accessor(:jwt_verification_key) do
125
- proc { RsaPublicKey.instance.fetch }
124
+ proc { Keyless::RsaPublicKey.instance.fetch }
126
125
  end
127
126
  end
128
127
  end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Grape
4
+ module Jwt
5
+ module Authentication
6
+ # Specifies which configuration keys are shared between keyless
7
+ # and grape-jwt-authentication, so that we can easily pass through
8
+ # our configuration to keyless.
9
+ KEYLESS_CONFIGURATION = %i[
10
+ authenticator rsa_public_key_url rsa_public_key_caching
11
+ rsa_public_key_expiration jwt_issuer jwt_beholder jwt_options
12
+ jwt_verification_key
13
+ ]
14
+
15
+ # (Re)configure our gem dependencies. We take care of setting up
16
+ # +Keyless+, which has been extracted from this gem.
17
+ def self.configure_dependencies
18
+ configure_keyless
19
+ end
20
+
21
+ # Configure the +Keyless+ gem with our configuration.
22
+ def self.configure_keyless
23
+ configuration = Grape::Jwt::Authentication.configuration
24
+
25
+ Keyless.configure do |keyless|
26
+ KEYLESS_CONFIGURATION.each do |option|
27
+ keyless.send("#{option}=", configuration.send(option))
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -91,8 +91,8 @@ module Grape
91
91
  # @param env [Hash{String => Mixed}] the Rack environment
92
92
  # @param token [String] the token parsed from the HTTP header
93
93
  def inject_token_into_env(env, token)
94
- env['grape_jwt_auth.parsed_token'] = Jwt.new(token)
95
- rescue *Jwt::RESCUE_JWT_EXCEPTIONS
94
+ env['grape_jwt_auth.parsed_token'] = Keyless::Jwt.new(token)
95
+ rescue *Keyless::Jwt::RESCUE_JWT_EXCEPTIONS
96
96
  env['grape_jwt_auth.parsed_token'] = nil
97
97
  ensure
98
98
  env['grape_jwt_auth.original_token'] = token
@@ -3,7 +3,7 @@
3
3
  module Grape
4
4
  module Jwt
5
5
  module Authentication
6
- VERSION = '1.1.0'.freeze
6
+ VERSION = '2.0.2'.freeze
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-jwt-authentication
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hermann Mayer
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-11-01 00:00:00.000000000 Z
11
+ date: 2020-09-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.16'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3'
20
23
  type: :development
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: '1.16'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: rack
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -206,6 +212,20 @@ dependencies:
206
212
  - - "~>"
207
213
  - !ruby/object:Gem::Version
208
214
  version: '1.0'
215
+ - !ruby/object:Gem::Dependency
216
+ name: keyless
217
+ requirement: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - "~>"
220
+ - !ruby/object:Gem::Version
221
+ version: '1.0'
222
+ type: :runtime
223
+ prerelease: false
224
+ version_requirements: !ruby/object:Gem::Requirement
225
+ requirements:
226
+ - - "~>"
227
+ - !ruby/object:Gem::Version
228
+ version: '1.0'
209
229
  description: A reusable Grape JWT authentication concern
210
230
  email:
211
231
  - hermann.mayer92@gmail.com
@@ -221,26 +241,22 @@ files:
221
241
  - ".travis.yml"
222
242
  - CHANGELOG.md
223
243
  - Gemfile
224
- - Gemfile.lock
225
244
  - LICENSE
226
245
  - README.md
227
246
  - Rakefile
228
247
  - bin/console
229
248
  - bin/setup
230
- - doc/assets/logo.png
231
- - doc/assets/project.png
232
- - doc/assets/project.xcf
249
+ - doc/assets/project.svg
233
250
  - grape-jwt-authentication.gemspec
234
251
  - lib/grape/jwt/authentication.rb
235
252
  - lib/grape/jwt/authentication/configuration.rb
236
- - lib/grape/jwt/authentication/jwt.rb
253
+ - lib/grape/jwt/authentication/dependencies.rb
237
254
  - lib/grape/jwt/authentication/jwt_handler.rb
238
- - lib/grape/jwt/authentication/rsa_public_key.rb
239
255
  - lib/grape/jwt/authentication/version.rb
240
256
  homepage: https://github.com/hausgold/grape-jwt-authentication
241
257
  licenses: []
242
258
  metadata: {}
243
- post_install_message:
259
+ post_install_message:
244
260
  rdoc_options: []
245
261
  require_paths:
246
262
  - lib
@@ -255,9 +271,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
255
271
  - !ruby/object:Gem::Version
256
272
  version: '0'
257
273
  requirements: []
258
- rubyforge_project:
259
- rubygems_version: 2.7.7
260
- signing_key:
274
+ rubygems_version: 3.1.4
275
+ signing_key:
261
276
  specification_version: 4
262
277
  summary: A reusable Grape JWT authentication concern
263
278
  test_files: []
@@ -1,114 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- grape-jwt-authentication (1.1.0)
5
- activesupport (>= 3.2.0)
6
- grape (~> 1.0)
7
- httparty
8
- jwt (~> 2.1)
9
- recursive-open-struct (~> 1.0)
10
-
11
- GEM
12
- remote: https://rubygems.org/
13
- specs:
14
- activesupport (5.2.1)
15
- concurrent-ruby (~> 1.0, >= 1.0.2)
16
- i18n (>= 0.7, < 2)
17
- minitest (~> 5.1)
18
- tzinfo (~> 1.1)
19
- addressable (2.5.2)
20
- public_suffix (>= 2.0.2, < 4.0)
21
- axiom-types (0.1.1)
22
- descendants_tracker (~> 0.0.4)
23
- ice_nine (~> 0.11.0)
24
- thread_safe (~> 0.3, >= 0.3.1)
25
- builder (3.2.3)
26
- coercible (1.0.0)
27
- descendants_tracker (~> 0.0.1)
28
- concurrent-ruby (1.0.5)
29
- crack (0.4.3)
30
- safe_yaml (~> 1.0.0)
31
- descendants_tracker (0.0.4)
32
- thread_safe (~> 0.3, >= 0.3.1)
33
- diff-lcs (1.3)
34
- docile (1.1.5)
35
- equalizer (0.0.11)
36
- grape (1.1.0)
37
- activesupport
38
- builder
39
- mustermann-grape (~> 1.0.0)
40
- rack (>= 1.3.0)
41
- rack-accept
42
- virtus (>= 1.0.0)
43
- hashdiff (0.3.7)
44
- httparty (0.16.2)
45
- multi_xml (>= 0.5.2)
46
- i18n (1.1.1)
47
- concurrent-ruby (~> 1.0)
48
- ice_nine (0.11.2)
49
- json (2.1.0)
50
- jwt (2.1.0)
51
- minitest (5.11.3)
52
- multi_xml (0.6.0)
53
- mustermann (1.0.3)
54
- mustermann-grape (1.0.0)
55
- mustermann (~> 1.0.0)
56
- public_suffix (3.0.1)
57
- rack (2.0.3)
58
- rack-accept (0.4.5)
59
- rack (>= 0.4)
60
- rack-test (0.8.2)
61
- rack (>= 1.0, < 3)
62
- rake (10.5.0)
63
- recursive-open-struct (1.1.0)
64
- rspec (3.7.0)
65
- rspec-core (~> 3.7.0)
66
- rspec-expectations (~> 3.7.0)
67
- rspec-mocks (~> 3.7.0)
68
- rspec-core (3.7.0)
69
- rspec-support (~> 3.7.0)
70
- rspec-expectations (3.7.0)
71
- diff-lcs (>= 1.2.0, < 2.0)
72
- rspec-support (~> 3.7.0)
73
- rspec-mocks (3.7.0)
74
- diff-lcs (>= 1.2.0, < 2.0)
75
- rspec-support (~> 3.7.0)
76
- rspec-support (3.7.0)
77
- safe_yaml (1.0.4)
78
- simplecov (0.15.1)
79
- docile (~> 1.1.0)
80
- json (>= 1.8, < 3)
81
- simplecov-html (~> 0.10.0)
82
- simplecov-html (0.10.2)
83
- thread_safe (0.3.6)
84
- timecop (0.9.1)
85
- tzinfo (1.2.5)
86
- thread_safe (~> 0.1)
87
- vcr (3.0.3)
88
- virtus (1.0.5)
89
- axiom-types (~> 0.1)
90
- coercible (~> 1.0)
91
- descendants_tracker (~> 0.0, >= 0.0.3)
92
- equalizer (~> 0.0, >= 0.0.9)
93
- webmock (3.1.1)
94
- addressable (>= 2.3.6)
95
- crack (>= 0.3.2)
96
- hashdiff
97
-
98
- PLATFORMS
99
- ruby
100
-
101
- DEPENDENCIES
102
- bundler (~> 1.16)
103
- grape-jwt-authentication!
104
- rack (~> 2.0)
105
- rack-test (~> 0.8.2)
106
- rake (~> 10.0)
107
- rspec (~> 3.0)
108
- simplecov (~> 0.15)
109
- timecop (~> 0.9.1)
110
- vcr (~> 3.0)
111
- webmock (~> 3.1)
112
-
113
- BUNDLED WITH
114
- 1.16.5
Binary file
Binary file
Binary file
@@ -1,113 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'recursive-open-struct'
4
-
5
- module Grape
6
- module Jwt
7
- module Authentication
8
- # A easy to use model for verification of JSON Web Tokens. This is just a
9
- # wrapper class for the excellent ruby-jwt gem. It's completely up to you
10
- # to use it. But be aware, its a bit optinionated by default.
11
- class Jwt
12
- # All the following JWT verification issues lead to a failed validation.
13
- RESCUE_JWT_EXCEPTIONS = [
14
- ::JWT::DecodeError,
15
- ::JWT::VerificationError,
16
- ::JWT::ExpiredSignature,
17
- ::JWT::IncorrectAlgorithm,
18
- ::JWT::ImmatureSignature,
19
- ::JWT::InvalidIssuerError,
20
- ::JWT::InvalidIatError,
21
- ::JWT::InvalidAudError,
22
- ::JWT::InvalidSubError,
23
- ::JWT::InvalidJtiError,
24
- ::JWT::InvalidPayload
25
- ].freeze
26
-
27
- # :reek:Attribute because its fine to be extern-modifiable at these
28
- # instances
29
- attr_reader :payload, :token
30
- attr_writer :verification_key, :jwt_options
31
- attr_accessor :issuer, :beholder
32
-
33
- # Setup a new JWT instance. You have to pass the raw JSON Web Token to
34
- # the initializer. Example:
35
- #
36
- # Jwt.new('j.w.t')
37
- # # => <Jwt>
38
- #
39
- # @return [Jwt]
40
- def initialize(token)
41
- parsed_payload = JWT.decode(token, nil, false).first.symbolize_keys
42
- @token = token
43
- @payload = RecursiveOpenStruct.new(parsed_payload)
44
- end
45
-
46
- # Checks if the payload says this is a refresh token.
47
- #
48
- # @return [Boolean] Whenever this is a access token
49
- def access_token?
50
- payload.typ == 'access'
51
- end
52
-
53
- # Checks if the payload says this is a refresh token.
54
- #
55
- # @return [Boolean] Whenever this is a refresh token
56
- def refresh_token?
57
- payload.typ == 'refresh'
58
- end
59
-
60
- # Retrives the expiration date from the payload when set.
61
- #
62
- # @return [nil|ActiveSupport::TimeWithZone] The expiration date
63
- def expires_at
64
- exp = payload.exp
65
- return nil unless exp
66
-
67
- Time.zone.at(exp)
68
- end
69
-
70
- # Deliver the public key for verification by default. This uses the
71
- # {RsaPublicKey} class, but you can configure the verification key the
72
- # way you like. (Especially for different algorithms, like HMAC or
73
- # ECDSA) Just make use of the same named setter.
74
- #
75
- # @return [OpenSSL::PKey::RSA|Mixed] The verification key
76
- def verification_key
77
- unless @verification_key
78
- conf = Grape::Jwt::Authentication.configuration
79
- return conf.jwt_verification_key.call
80
- end
81
- @verification_key
82
- end
83
-
84
- # This getter passes back the default JWT verification option hash
85
- # which is optinionated. You can change this the way you like by
86
- # configuring your options with the help of the same named setter.
87
- #
88
- # @return [Hash] The JWT verification options hash
89
- def jwt_options
90
- unless @jwt_options
91
- conf = Grape::Jwt::Authentication.configuration
92
- return conf.jwt_options.call
93
- end
94
- @jwt_options
95
- end
96
-
97
- # Verify the current token by our hard and strict rules. Whenever the
98
- # token was not parsed from a string, we encode the current state to a
99
- # JWT string representation and check this.
100
- #
101
- # @return [Boolean] Whenever the token is valid or not
102
- #
103
- # :reek:NilCheck because we have to check the token
104
- # origin and react on it
105
- def valid?
106
- JWT.decode(token, verification_key, true, jwt_options) && true
107
- rescue *RESCUE_JWT_EXCEPTIONS
108
- false
109
- end
110
- end
111
- end
112
- end
113
- end
@@ -1,127 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'singleton'
4
- require 'openssl'
5
- require 'httparty'
6
-
7
- module Grape
8
- module Jwt
9
- module Authentication
10
- # A common purpose RSA public key fetching/caching helper. With the help
11
- # of this class you are able to retrieve the RSA public key from a remote
12
- # server or a local file. This is naturally only useful if you care about
13
- # JSON Web Token which are signed by the RSA algorithm.
14
- class RsaPublicKey
15
- include Singleton
16
-
17
- # Setup all the getters and setters.
18
- attr_accessor :cache
19
- attr_writer :url, :expiration, :caching
20
-
21
- # Setup the instance.
22
- def initialize
23
- @expiration = 1.hour
24
- @cache = ActiveSupport::Cache::MemoryStore.new
25
- end
26
-
27
- # Just a simple shortcut class method to access the fetch method
28
- # without specifying the singleton instance.
29
- #
30
- # @return [OpenSSL::PKey::RSA]
31
- def self.fetch
32
- instance.fetch
33
- end
34
-
35
- # Configure the single instance. This is just a wrapper (like tap)
36
- # to the instance itself.
37
- def configure
38
- yield(self)
39
- end
40
-
41
- # Fetch the public key with the help of the configuration. You can
42
- # configure the public key location (local file, remote (HTTP/HTTPS)
43
- # file), whenever we should cache and how long to cache.
44
- #
45
- # @return [OpenSSL::PKey::RSA]
46
- def fetch
47
- encoded_key = if cache?
48
- cache.fetch('encoded_key', expires_in: expiration) do
49
- fetch_encoded_key
50
- end
51
- else
52
- fetch_encoded_key
53
- end
54
-
55
- OpenSSL::PKey::RSA.new(encoded_key)
56
- end
57
-
58
- # Fetch the encoded (DER, or PEM) public key from a remote or local
59
- # location.
60
- #
61
- # @return [String] The encoded public key
62
- def fetch_encoded_key
63
- raise ArgumentError, 'No URL for RsaPublicKey configured' unless url
64
-
65
- if remote?
66
- HTTParty.get(url).body
67
- else
68
- File.read(url)
69
- end
70
- end
71
-
72
- # A helper for the caching configuration.
73
- #
74
- # @return [Boolean]
75
- def cache?
76
- caching && true
77
- end
78
-
79
- # A helper to determine if the configured URL is on a remote server or
80
- # it is local on the filesystem. Whenever the configured URL specifies
81
- # the HTTP/HTTPS protocol, we assume it is remote.
82
- #
83
- # @return [Boolean]
84
- def remote?
85
- !(url =~ /^https?/).nil?
86
- end
87
-
88
- # This getter passes back the default RSA public key. You can change
89
- # this the way you like by configuring your URL with the help of the
90
- # same named setter.
91
- #
92
- # @return [String] The configured public key location
93
- def url
94
- unless @url
95
- conf = Grape::Jwt::Authentication.configuration
96
- return conf.rsa_public_key_url
97
- end
98
- @url
99
- end
100
-
101
- # This getter passes back the default public key cache expiration time.
102
- # You can change this time with the help of the same named setter.
103
- #
104
- # @return [Integer] The configured cache expiration time
105
- def expiration
106
- unless @expiration
107
- conf = Grape::Jwt::Authentication.configuration
108
- return conf.rsa_public_key_expiration
109
- end
110
- @expiration
111
- end
112
-
113
- # This getter passes back the caching flag. You can change this flag
114
- # with the help of the same named setter.
115
- #
116
- # @return [Boolean] Whenever we should cache or not
117
- def caching
118
- unless @caching
119
- conf = Grape::Jwt::Authentication.configuration
120
- return conf.rsa_public_key_caching
121
- end
122
- @caching
123
- end
124
- end
125
- end
126
- end
127
- end