drillbit 0.0.1 → 1.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/drillbit/authorizable_resource.rb +1 -0
- data/lib/drillbit/authorizers/query.rb +4 -2
- data/lib/drillbit/configuration.rb +53 -6
- data/lib/drillbit/resource/naming.rb +3 -1
- data/lib/drillbit/serializers/json_api.rb +11 -1
- data/lib/drillbit/tokens/json_web_token.rb +106 -10
- data/lib/drillbit/tokens/json_web_tokens/null.rb +45 -2
- data/lib/drillbit/tokens/json_web_tokens/password_reset.rb +14 -0
- data/lib/drillbit/version.rb +1 -1
- data/spec/drillbit/authorizers/query_spec.rb +3 -2
- data/spec/drillbit/tokens/json_web_token_spec.rb +89 -1
- data/spec/drillbit/tokens/json_web_tokens/password_reset_spec.rb +43 -0
- metadata +19 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8653add9748daa722199cda827ade767201495db
|
4
|
+
data.tar.gz: bad41a3d97ac655776263d7fc5770c71e09ab062
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8bbd110a4c40d5beecd18b3c4b72e91b239c0b7824f7c142006d6d29caf2722ec438b5acdf5fafc573165e9edbffc49aa960c51d30b43c202eaea032cc4f7b7
|
7
|
+
data.tar.gz: 4e6b1c5897fa747f3497cdb17a10bed6d355fe093d7e0f7e2a65810ab8aec65b3166cdc204e0f1927f0f96cbf5d628f46b534eb8f2095ba129d0309188932e87
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
@@ -4,11 +4,13 @@ module Authorizers
|
|
4
4
|
class Query
|
5
5
|
attr_accessor :token,
|
6
6
|
:user,
|
7
|
+
:params,
|
7
8
|
:resource
|
8
9
|
|
9
|
-
def initialize(token:, user:, resource:, **other)
|
10
|
+
def initialize(token:, user:, params:, resource:, **other)
|
10
11
|
self.token = token
|
11
12
|
self.user = user
|
13
|
+
self.params = params
|
12
14
|
self.resource = resource
|
13
15
|
|
14
16
|
other.each do |name, value|
|
@@ -17,7 +19,7 @@ class Query
|
|
17
19
|
end
|
18
20
|
|
19
21
|
def able_to_index?
|
20
|
-
|
22
|
+
false
|
21
23
|
end
|
22
24
|
|
23
25
|
def able_to_show?
|
@@ -1,19 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
module Drillbit
|
3
3
|
class Configuration
|
4
|
-
|
5
|
-
:allowed_subdomains,
|
4
|
+
attr_writer \
|
6
5
|
:allowed_api_subdomains,
|
6
|
+
:allowed_subdomains,
|
7
7
|
:application_name,
|
8
|
+
:available_token_roles,
|
8
9
|
:default_api_version,
|
10
|
+
:default_token_audience,
|
11
|
+
:default_token_roles,
|
12
|
+
:default_token_expiration_in_minutes,
|
13
|
+
:default_token_issuer,
|
14
|
+
:default_token_subject,
|
9
15
|
:token_private_key
|
10
16
|
|
17
|
+
attr_accessor \
|
18
|
+
:application_name
|
19
|
+
|
11
20
|
def to_h
|
12
21
|
{
|
13
|
-
|
14
|
-
|
15
|
-
application_name:
|
16
|
-
default_api_version:
|
22
|
+
allowed_api_subdomains: allowed_api_subdomains,
|
23
|
+
allowed_subdomains: allowed_subdomains,
|
24
|
+
application_name: application_name,
|
25
|
+
default_api_version: default_api_version,
|
26
|
+
default_token_issuer: default_token_issuer,
|
27
|
+
default_token_subject: default_token_subject,
|
28
|
+
default_token_expiration_in_minutes: token_expiration_in_minutes,
|
17
29
|
}
|
18
30
|
end
|
19
31
|
|
@@ -24,6 +36,41 @@ module Drillbit
|
|
24
36
|
def allowed_api_subdomains
|
25
37
|
@allowed_api_subdomains || ['api']
|
26
38
|
end
|
39
|
+
|
40
|
+
def default_token_audience
|
41
|
+
@default_token_audience || 'public'
|
42
|
+
end
|
43
|
+
|
44
|
+
def available_token_roles
|
45
|
+
@available_token_roles || %w{standard admin password_reset email_verification}
|
46
|
+
end
|
47
|
+
|
48
|
+
def default_api_version
|
49
|
+
@default_api_version || '1'
|
50
|
+
end
|
51
|
+
|
52
|
+
def default_token_roles
|
53
|
+
@default_token_roles || %w{standard}
|
54
|
+
end
|
55
|
+
|
56
|
+
def default_token_issuer
|
57
|
+
@default_token_issuer || 'drillbit'
|
58
|
+
end
|
59
|
+
|
60
|
+
def default_token_subject
|
61
|
+
@default_token_subject || 'User'
|
62
|
+
end
|
63
|
+
|
64
|
+
def default_token_expiration_in_minutes
|
65
|
+
@default_token_expiration_in_minutes || (7 * 24 * 60)
|
66
|
+
end
|
67
|
+
|
68
|
+
def token_private_key
|
69
|
+
return unless @token_private_key
|
70
|
+
return @token_private_key if @token_private_key.respond_to?(:sign)
|
71
|
+
|
72
|
+
OpenSSL::PKey::RSA.new(@token_private_key)
|
73
|
+
end
|
27
74
|
end
|
28
75
|
|
29
76
|
def self.configure
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
# rubocop:disable Metrics/LineLength
|
2
3
|
module Drillbit
|
3
4
|
module Resource
|
4
5
|
module Naming
|
5
|
-
CONTROLLER_RESOURCE_NAME_PATTERN = /\A((.*?::)?.*?)(\w
|
6
|
+
CONTROLLER_RESOURCE_NAME_PATTERN = /\A((.*?::)?.*?)(\w+?)(?:Index|Indicies)?Controller\z/
|
6
7
|
|
7
8
|
module ClassMethods
|
8
9
|
def plural_resource_name
|
@@ -31,3 +32,4 @@ module Naming
|
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
35
|
+
# rubocop:enable Metrics/LineLength
|
@@ -3,7 +3,17 @@ module Drillbit
|
|
3
3
|
module Serializers
|
4
4
|
module JsonApi
|
5
5
|
def json_api_type
|
6
|
-
object.
|
6
|
+
object.
|
7
|
+
class.
|
8
|
+
name.
|
9
|
+
gsub(/\A[^:]+::/, '').
|
10
|
+
split('::').
|
11
|
+
reverse.
|
12
|
+
join('::').
|
13
|
+
tableize.
|
14
|
+
dasherize.
|
15
|
+
tr('/', '-').
|
16
|
+
pluralize
|
7
17
|
end
|
8
18
|
end
|
9
19
|
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'jwt'
|
3
3
|
require 'json/jwt'
|
4
|
+
require 'drillbit/configuration'
|
4
5
|
require 'drillbit/tokens/json_web_tokens/invalid'
|
5
6
|
require 'drillbit/tokens/json_web_tokens/null'
|
6
7
|
|
8
|
+
# :reek:TooManyMethods
|
7
9
|
module Drillbit
|
8
10
|
module Tokens
|
9
11
|
class JsonWebToken
|
@@ -27,15 +29,60 @@ class JsonWebToken
|
|
27
29
|
].freeze
|
28
30
|
|
29
31
|
attr_accessor :data,
|
32
|
+
:headers,
|
30
33
|
:private_key
|
31
34
|
|
32
35
|
def initialize(data:,
|
36
|
+
headers: {},
|
33
37
|
private_key: Drillbit.configuration.token_private_key)
|
34
38
|
|
35
39
|
self.data = data
|
40
|
+
self.headers = headers
|
36
41
|
self.private_key = private_key
|
37
42
|
end
|
38
43
|
|
44
|
+
def self.build_from_request(request_token)
|
45
|
+
return Tokens::JsonWebTokens::Null.instance unless request_token
|
46
|
+
|
47
|
+
data, headers = *request_token
|
48
|
+
|
49
|
+
new(data: data, headers: headers)
|
50
|
+
end
|
51
|
+
|
52
|
+
# rubocop:disable Metrics/ParameterLists, Metrics/AbcSize, Metrics/LineLength
|
53
|
+
# :reek:DuplicateMethodCall
|
54
|
+
def self.build(id: SecureRandom.uuid,
|
55
|
+
audience: Drillbit.configuration.default_token_audience,
|
56
|
+
expiration: Time.now.utc.to_i + (60 * Drillbit.configuration.default_token_expiration_in_minutes),
|
57
|
+
issuer: Drillbit.configuration.default_token_issuer || 'Drillbit',
|
58
|
+
issued_at: Time.now.utc,
|
59
|
+
not_before: Time.now.utc,
|
60
|
+
owner: nil,
|
61
|
+
roles: Drillbit.configuration.default_token_roles,
|
62
|
+
subject: Drillbit.configuration.default_token_subject,
|
63
|
+
subject_id:,
|
64
|
+
token_private_key: Drillbit.configuration.token_private_key)
|
65
|
+
|
66
|
+
owner ||= subject_id
|
67
|
+
|
68
|
+
new(
|
69
|
+
private_key: token_private_key,
|
70
|
+
data: {
|
71
|
+
'aud' => audience,
|
72
|
+
'exp' => expiration.to_i,
|
73
|
+
'iat' => issued_at.to_i,
|
74
|
+
'iss' => issuer,
|
75
|
+
'jti' => id,
|
76
|
+
'nbf' => not_before.to_i,
|
77
|
+
'own' => owner,
|
78
|
+
'rol' => roles.join(','),
|
79
|
+
'sid' => subject_id,
|
80
|
+
'sub' => subject,
|
81
|
+
},
|
82
|
+
)
|
83
|
+
end
|
84
|
+
# rubocop:enable Metrics/ParameterLists, Metrics/AbcSize, Metrics/LineLength
|
85
|
+
|
39
86
|
def valid?
|
40
87
|
true
|
41
88
|
end
|
@@ -45,7 +92,53 @@ class JsonWebToken
|
|
45
92
|
end
|
46
93
|
|
47
94
|
def to_h
|
48
|
-
data
|
95
|
+
[data, headers]
|
96
|
+
end
|
97
|
+
|
98
|
+
def audience
|
99
|
+
data['aud']
|
100
|
+
end
|
101
|
+
|
102
|
+
def issued_at
|
103
|
+
data['iat']
|
104
|
+
end
|
105
|
+
|
106
|
+
def issuer
|
107
|
+
data['iss']
|
108
|
+
end
|
109
|
+
|
110
|
+
def expiration
|
111
|
+
data['exp']
|
112
|
+
end
|
113
|
+
|
114
|
+
def id
|
115
|
+
data['jti']
|
116
|
+
end
|
117
|
+
|
118
|
+
def not_before
|
119
|
+
data['nbf']
|
120
|
+
end
|
121
|
+
|
122
|
+
def owner_id
|
123
|
+
data['own']
|
124
|
+
end
|
125
|
+
|
126
|
+
def subject_id
|
127
|
+
data['sid']
|
128
|
+
end
|
129
|
+
|
130
|
+
def subject
|
131
|
+
data['sub']
|
132
|
+
end
|
133
|
+
|
134
|
+
Drillbit.configuration.available_token_roles.each do |role|
|
135
|
+
define_method("#{role}?") do
|
136
|
+
roles.include? role
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def roles
|
141
|
+
@roles ||= data['rol'].split(',')
|
49
142
|
end
|
50
143
|
|
51
144
|
def to_jwt
|
@@ -91,18 +184,21 @@ class JsonWebToken
|
|
91
184
|
|
92
185
|
return JsonWebTokens::Null.instance if signed_token.to_s == ''
|
93
186
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
187
|
+
decoded = JWT.decode(
|
188
|
+
signed_token,
|
189
|
+
private_key,
|
190
|
+
true,
|
191
|
+
algorithm: 'RS256',
|
192
|
+
verify_expiration: true,
|
193
|
+
verify_not_before: true,
|
194
|
+
verify_iat: true,
|
195
|
+
leeway: 5,
|
103
196
|
)
|
104
197
|
|
198
|
+
data, headers = *decoded
|
199
|
+
|
105
200
|
new(data: data,
|
201
|
+
headers: headers,
|
106
202
|
private_key: private_key)
|
107
203
|
rescue *TRANSFORMATION_EXCEPTIONS
|
108
204
|
JsonWebTokens::Invalid.instance
|
@@ -1,12 +1,55 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
require 'drillbit/configuration'
|
2
3
|
require 'drillbit/tokens/null'
|
3
4
|
|
4
5
|
module Drillbit
|
5
6
|
module Tokens
|
6
7
|
module JsonWebTokens
|
7
8
|
class Null < Tokens::Null
|
8
|
-
def
|
9
|
-
|
9
|
+
def audience
|
10
|
+
nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def issued_at
|
14
|
+
nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def issuer
|
18
|
+
nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def expiration
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
def id
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def not_before
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def owner_id
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def subject_id
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def subject
|
42
|
+
nil
|
43
|
+
end
|
44
|
+
|
45
|
+
Drillbit.configuration.available_token_roles.each do |role|
|
46
|
+
define_method("#{role}?") do
|
47
|
+
false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def roles
|
52
|
+
[]
|
10
53
|
end
|
11
54
|
end
|
12
55
|
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'drillbit/tokens/json_web_token'
|
3
|
+
|
4
|
+
module Drillbit
|
5
|
+
module Tokens
|
6
|
+
module JsonWebTokens
|
7
|
+
class PasswordReset < JsonWebToken
|
8
|
+
def self.build(expiration: Time.now.utc.to_i + (30 * 60), **attrs)
|
9
|
+
super(expiration: expiration, **attrs)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
data/lib/drillbit/version.rb
CHANGED
@@ -8,9 +8,10 @@ RSpec.describe Query do
|
|
8
8
|
it 'does not authorize the resource by default' do
|
9
9
|
authorizer = Query.new(token: '123',
|
10
10
|
user: 'my_user',
|
11
|
-
resource: 'my_resource'
|
11
|
+
resource: 'my_resource',
|
12
|
+
params: 'my_params')
|
12
13
|
|
13
|
-
expect(authorizer).
|
14
|
+
expect(authorizer).not_to be_able_to_index
|
14
15
|
expect(authorizer).not_to be_able_to_show
|
15
16
|
expect(authorizer).not_to be_able_to_create
|
16
17
|
expect(authorizer).not_to be_able_to_update
|
@@ -41,7 +41,17 @@ RSpec.describe JsonWebToken do
|
|
41
41
|
private_key: test_private_key)
|
42
42
|
|
43
43
|
expect(token).to be_a JsonWebToken
|
44
|
-
expect(token.to_h).to eql(
|
44
|
+
expect(token.to_h).to eql(
|
45
|
+
[
|
46
|
+
{
|
47
|
+
'bar' => 'baz',
|
48
|
+
},
|
49
|
+
{
|
50
|
+
'typ' => 'JWT',
|
51
|
+
'alg' => 'RS256',
|
52
|
+
},
|
53
|
+
],
|
54
|
+
)
|
45
55
|
end
|
46
56
|
|
47
57
|
it 'can convert an empty signed token' do
|
@@ -130,6 +140,84 @@ RSpec.describe JsonWebToken do
|
|
130
140
|
]
|
131
141
|
end
|
132
142
|
# rubocop:enable Metrics/LineLength
|
143
|
+
|
144
|
+
it 'can accept roles as a string but convert them to an array' do
|
145
|
+
token = JsonWebToken.new(data: { 'rol' => 'bar,baz' },
|
146
|
+
private_key: test_private_key)
|
147
|
+
|
148
|
+
expect(token.roles).to eql %w{bar baz}
|
149
|
+
|
150
|
+
jwe_s = token.to_jwe_s
|
151
|
+
|
152
|
+
converted_token = JsonWebToken.from_jwe(jwe_s,
|
153
|
+
private_key: test_private_key)
|
154
|
+
|
155
|
+
expect(converted_token.data['rol']).to eql 'bar,baz'
|
156
|
+
expect(converted_token.roles).to eql %w{bar baz}
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'can build a token by explicitly specifying all the data', :time_mock do
|
160
|
+
token = JsonWebToken.build(id: 'test_id',
|
161
|
+
audience: 'audience',
|
162
|
+
expiration: 20.years.from_now,
|
163
|
+
issuer: 'issuer',
|
164
|
+
issued_at: 5.minutes.ago,
|
165
|
+
not_before: 1.month.ago,
|
166
|
+
owner: 'subject_id',
|
167
|
+
roles: %w{my_role},
|
168
|
+
subject: 'my_subject',
|
169
|
+
subject_id: 'subject_id',
|
170
|
+
token_private_key: test_private_key)
|
171
|
+
|
172
|
+
jwe_s = token.to_jwe_s
|
173
|
+
|
174
|
+
converted_token = JsonWebToken.from_jwe(jwe_s,
|
175
|
+
private_key: test_private_key)
|
176
|
+
|
177
|
+
expect(converted_token.to_h).to eql(
|
178
|
+
[
|
179
|
+
{
|
180
|
+
'aud' => 'audience',
|
181
|
+
'exp' => 1_974_477_600,
|
182
|
+
'iat' => 1_343_325_300,
|
183
|
+
'iss' => 'issuer',
|
184
|
+
'jti' => 'test_id',
|
185
|
+
'nbf' => 1_340_733_600,
|
186
|
+
'own' => 'subject_id',
|
187
|
+
'rol' => 'my_role',
|
188
|
+
'sid' => 'subject_id',
|
189
|
+
'sub' => 'my_subject',
|
190
|
+
},
|
191
|
+
{
|
192
|
+
'typ' => 'JWT',
|
193
|
+
'alg' => 'RS256',
|
194
|
+
},
|
195
|
+
],
|
196
|
+
)
|
197
|
+
end
|
198
|
+
|
199
|
+
it 'can build a token by only specifying the subject ID', :time_mock do
|
200
|
+
token = JsonWebToken.build(subject_id: 'subject_id',
|
201
|
+
token_private_key: test_private_key)
|
202
|
+
|
203
|
+
jwe_s = token.to_jwe_s
|
204
|
+
|
205
|
+
converted_token = JsonWebToken.from_jwe(jwe_s,
|
206
|
+
private_key: test_private_key)
|
207
|
+
|
208
|
+
expect(converted_token.to_h).to include(
|
209
|
+
'aud' => 'public',
|
210
|
+
'exp' => 1_343_930_400,
|
211
|
+
'iat' => 1_343_325_600,
|
212
|
+
'iss' => 'drillbit',
|
213
|
+
'jti' => match(uuid_regex),
|
214
|
+
'nbf' => 1_343_325_600,
|
215
|
+
'own' => 'subject_id',
|
216
|
+
'rol' => 'standard',
|
217
|
+
'sid' => 'subject_id',
|
218
|
+
'sub' => 'User',
|
219
|
+
)
|
220
|
+
end
|
133
221
|
end
|
134
222
|
end
|
135
223
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'drillbit/tokens/json_web_tokens/password_reset'
|
4
|
+
|
5
|
+
module Drillbit
|
6
|
+
module Tokens
|
7
|
+
module JsonWebTokens
|
8
|
+
RSpec.describe PasswordReset do
|
9
|
+
it 'can build a token that expires during the password reset timeframe', :time_mock do
|
10
|
+
token = JsonWebToken.build(id: 'test_id',
|
11
|
+
subject_id: 'subject_id',
|
12
|
+
token_private_key: test_private_key)
|
13
|
+
|
14
|
+
jwe_s = token.to_jwe_s
|
15
|
+
|
16
|
+
converted_token = JsonWebToken.from_jwe(jwe_s,
|
17
|
+
private_key: test_private_key)
|
18
|
+
|
19
|
+
expect(converted_token.to_h).to eql(
|
20
|
+
[
|
21
|
+
{
|
22
|
+
'aud' => 'public',
|
23
|
+
'exp' => 1_343_930_400,
|
24
|
+
'iat' => 1_343_325_600,
|
25
|
+
'iss' => 'drillbit',
|
26
|
+
'jti' => 'test_id',
|
27
|
+
'nbf' => 1_343_325_600,
|
28
|
+
'own' => 'subject_id',
|
29
|
+
'rol' => 'standard',
|
30
|
+
'sid' => 'subject_id',
|
31
|
+
'sub' => 'User',
|
32
|
+
},
|
33
|
+
{
|
34
|
+
'typ' => 'JWT',
|
35
|
+
'alg' => 'RS256',
|
36
|
+
},
|
37
|
+
],
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: drillbit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- thegranddesign
|
@@ -31,7 +31,7 @@ cert_chain:
|
|
31
31
|
zRIv8lqQM8QFT76rzP5SBCERwN+ltKAFbQ5/FwmZNGWYnmCP3RZMQiRnbh+9H9lh
|
32
32
|
mlbwaYZTjgsXq6cy8N38EecewgBbZYS1IYJraE/M
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date: 2016-05-
|
34
|
+
date: 2016-05-12 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: erratum
|
@@ -103,6 +103,20 @@ dependencies:
|
|
103
103
|
- - "~>"
|
104
104
|
- !ruby/object:Gem::Version
|
105
105
|
version: '0.0'
|
106
|
+
- !ruby/object:Gem::Dependency
|
107
|
+
name: timecop
|
108
|
+
requirement: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - "~>"
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 0.7.0
|
113
|
+
type: :development
|
114
|
+
prerelease: false
|
115
|
+
version_requirements: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - "~>"
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: 0.7.0
|
106
120
|
description: ''
|
107
121
|
email: rubygems@livinghighontheblog.com
|
108
122
|
executables: []
|
@@ -155,6 +169,7 @@ files:
|
|
155
169
|
- lib/drillbit/tokens/json_web_token.rb
|
156
170
|
- lib/drillbit/tokens/json_web_tokens/invalid.rb
|
157
171
|
- lib/drillbit/tokens/json_web_tokens/null.rb
|
172
|
+
- lib/drillbit/tokens/json_web_tokens/password_reset.rb
|
158
173
|
- lib/drillbit/tokens/null.rb
|
159
174
|
- lib/drillbit/version.rb
|
160
175
|
- spec/drillbit/accept_header_spec.rb
|
@@ -183,6 +198,7 @@ files:
|
|
183
198
|
- spec/drillbit/resource/processors/sorting_spec.rb
|
184
199
|
- spec/drillbit/tokens/base64_spec.rb
|
185
200
|
- spec/drillbit/tokens/json_web_token_spec.rb
|
201
|
+
- spec/drillbit/tokens/json_web_tokens/password_reset_spec.rb
|
186
202
|
- spec/fixtures/test_rsa_key
|
187
203
|
- spec/fixtures/test_rsa_key.pub
|
188
204
|
- spec/spec_helper.rb
|
@@ -238,6 +254,7 @@ test_files:
|
|
238
254
|
- spec/drillbit/resource/processors/sorting_spec.rb
|
239
255
|
- spec/drillbit/tokens/base64_spec.rb
|
240
256
|
- spec/drillbit/tokens/json_web_token_spec.rb
|
257
|
+
- spec/drillbit/tokens/json_web_tokens/password_reset_spec.rb
|
241
258
|
- spec/fixtures/test_rsa_key
|
242
259
|
- spec/fixtures/test_rsa_key.pub
|
243
260
|
- spec/spec_helper.rb
|
metadata.gz.sig
CHANGED
Binary file
|