grape-jwt-authentication 1.0.1
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 +7 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +43 -0
- data/.travis.yml +20 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +114 -0
- data/LICENSE +21 -0
- data/README.md +391 -0
- data/Rakefile +8 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/doc/assets/logo.png +0 -0
- data/doc/assets/project.png +0 -0
- data/doc/assets/project.xcf +0 -0
- data/grape-jwt-authentication.gemspec +39 -0
- data/lib/grape/jwt/authentication.rb +64 -0
- data/lib/grape/jwt/authentication/configuration.rb +130 -0
- data/lib/grape/jwt/authentication/jwt.rb +112 -0
- data/lib/grape/jwt/authentication/jwt_handler.rb +118 -0
- data/lib/grape/jwt/authentication/rsa_public_key.rb +126 -0
- data/lib/grape/jwt/authentication/version.rb +9 -0
- metadata +261 -0
@@ -0,0 +1,126 @@
|
|
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
|
+
if remote?
|
65
|
+
HTTParty.get(url).body
|
66
|
+
else
|
67
|
+
File.read(url)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# A helper for the caching configuration.
|
72
|
+
#
|
73
|
+
# @return [Boolean]
|
74
|
+
def cache?
|
75
|
+
caching && true
|
76
|
+
end
|
77
|
+
|
78
|
+
# A helper to determine if the configured URL is on a remote server or
|
79
|
+
# it is local on the filesystem. Whenever the configured URL specifies
|
80
|
+
# the HTTP/HTTPS protocol, we assume it is remote.
|
81
|
+
#
|
82
|
+
# @return [Boolean]
|
83
|
+
def remote?
|
84
|
+
!(url =~ /^https?/).nil?
|
85
|
+
end
|
86
|
+
|
87
|
+
# This getter passes back the default RSA public key. You can change
|
88
|
+
# this the way you like by configuring your URL with the help of the
|
89
|
+
# same named setter.
|
90
|
+
#
|
91
|
+
# @return [String] The configured public key location
|
92
|
+
def url
|
93
|
+
unless @url
|
94
|
+
conf = Grape::Jwt::Authentication.configuration
|
95
|
+
return conf.rsa_public_key_url
|
96
|
+
end
|
97
|
+
@url
|
98
|
+
end
|
99
|
+
|
100
|
+
# This getter passes back the default public key cache expiration time.
|
101
|
+
# You can change this time with the help of the same named setter.
|
102
|
+
#
|
103
|
+
# @return [Integer] The configured cache expiration time
|
104
|
+
def expiration
|
105
|
+
unless @expiration
|
106
|
+
conf = Grape::Jwt::Authentication.configuration
|
107
|
+
return conf.rsa_public_key_expiration
|
108
|
+
end
|
109
|
+
@expiration
|
110
|
+
end
|
111
|
+
|
112
|
+
# This getter passes back the caching flag. You can change this flag
|
113
|
+
# with the help of the same named setter.
|
114
|
+
#
|
115
|
+
# @return [Boolean] Whenever we should cache or not
|
116
|
+
def caching
|
117
|
+
unless @caching
|
118
|
+
conf = Grape::Jwt::Authentication.configuration
|
119
|
+
return conf.rsa_public_key_caching
|
120
|
+
end
|
121
|
+
@caching
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
metadata
ADDED
@@ -0,0 +1,261 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: grape-jwt-authentication
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Hermann Mayer
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-23 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.16'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.16'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.15'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.15'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: vcr
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '3.1'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '3.1'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: timecop
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: 0.9.1
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: 0.9.1
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rack
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '2.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '2.0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rack-test
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: 0.8.2
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: 0.8.2
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: activesupport
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: 3.2.0
|
146
|
+
type: :runtime
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 3.2.0
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: grape
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '1.0'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '1.0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: httparty
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :runtime
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: jwt
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '2.1'
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '2.1'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: recursive-open-struct
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '1.0'
|
202
|
+
type: :runtime
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '1.0'
|
209
|
+
description: A reusable Grape JWT authentication concern
|
210
|
+
email:
|
211
|
+
- hermann.mayer92@gmail.com
|
212
|
+
executables: []
|
213
|
+
extensions: []
|
214
|
+
extra_rdoc_files: []
|
215
|
+
files:
|
216
|
+
- ".gitignore"
|
217
|
+
- ".rspec"
|
218
|
+
- ".rubocop.yml"
|
219
|
+
- ".travis.yml"
|
220
|
+
- CHANGELOG.md
|
221
|
+
- Gemfile
|
222
|
+
- Gemfile.lock
|
223
|
+
- LICENSE
|
224
|
+
- README.md
|
225
|
+
- Rakefile
|
226
|
+
- bin/console
|
227
|
+
- bin/setup
|
228
|
+
- doc/assets/logo.png
|
229
|
+
- doc/assets/project.png
|
230
|
+
- doc/assets/project.xcf
|
231
|
+
- grape-jwt-authentication.gemspec
|
232
|
+
- lib/grape/jwt/authentication.rb
|
233
|
+
- lib/grape/jwt/authentication/configuration.rb
|
234
|
+
- lib/grape/jwt/authentication/jwt.rb
|
235
|
+
- lib/grape/jwt/authentication/jwt_handler.rb
|
236
|
+
- lib/grape/jwt/authentication/rsa_public_key.rb
|
237
|
+
- lib/grape/jwt/authentication/version.rb
|
238
|
+
homepage: https://github.com/hausgold/grape-jwt-authentication
|
239
|
+
licenses: []
|
240
|
+
metadata: {}
|
241
|
+
post_install_message:
|
242
|
+
rdoc_options: []
|
243
|
+
require_paths:
|
244
|
+
- lib
|
245
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
246
|
+
requirements:
|
247
|
+
- - ">="
|
248
|
+
- !ruby/object:Gem::Version
|
249
|
+
version: '0'
|
250
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
251
|
+
requirements:
|
252
|
+
- - ">="
|
253
|
+
- !ruby/object:Gem::Version
|
254
|
+
version: '0'
|
255
|
+
requirements: []
|
256
|
+
rubyforge_project:
|
257
|
+
rubygems_version: 2.6.13
|
258
|
+
signing_key:
|
259
|
+
specification_version: 4
|
260
|
+
summary: A reusable Grape JWT authentication concern
|
261
|
+
test_files: []
|