api_guard_grape 0.5.5 → 0.5.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/api_guard/jwt_auth/json_web_token.rb +89 -2
- data/lib/api_guard/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5cbdbe6a99ddb95a194ca2d457a00c632dcd8e70731b6e8bcebf02388c32a7ed
|
4
|
+
data.tar.gz: ded2f1d9537467657b493269e3a06093b2208f871a356f056aaf1179cd8e6e85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 37e5bb2e16a4d3733b630577c070be248fc9d24aa70209434fd0709b2c6efa60b32e3a90b76d08d4d7f127e3a2e0ef48b7ff4832bfd66a1f89f1120a911020ab
|
7
|
+
data.tar.gz: 97c8f918a4de68e43c42b207aeb964a8cd5b7c2ff12658533a61db86921b7b2cdd0e6fcd8f4467faa9e21a9706c527a05afe1f3fe440b4b962c00b99892f3d4e
|
@@ -110,12 +110,10 @@ module ApiGuard
|
|
110
110
|
|
111
111
|
# blacklisted ======================================================
|
112
112
|
def self.blacklisted_token_association(resource)
|
113
|
-
debugger
|
114
113
|
resource.class.blacklisted_token_association
|
115
114
|
end
|
116
115
|
|
117
116
|
def self.token_blacklisting_enabled?(resource)
|
118
|
-
debugger
|
119
117
|
blacklisted_token_association(resource).present?
|
120
118
|
end
|
121
119
|
|
@@ -138,6 +136,95 @@ module ApiGuard
|
|
138
136
|
blacklisted_tokens_for(current_resource).create(token: @token, expire_at: Time.at(@decoded_token[:exp]).utc)
|
139
137
|
end
|
140
138
|
|
139
|
+
|
140
|
+
def self.method_missing(name, *args)
|
141
|
+
method_name = name.to_s
|
142
|
+
|
143
|
+
if method_name.start_with?('authenticate_and_set_')
|
144
|
+
resource_name = method_name.split('authenticate_and_set_')[1]
|
145
|
+
authenticate_and_set_resource(resource_name)
|
146
|
+
else
|
147
|
+
super
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def self.respond_to_missing?(method_name, include_private = false)
|
152
|
+
method_name.to_s.start_with?('authenticate_and_set_') || super
|
153
|
+
end
|
154
|
+
|
155
|
+
# Authenticate the JWT token and set resource
|
156
|
+
def self.authenticate_and_set_resource(resource_name)
|
157
|
+
@resource_name = resource_name
|
158
|
+
|
159
|
+
@token = request.headers['Authorization']&.split('Bearer ')&.last
|
160
|
+
return render_error(401, message: I18n.t('api_guard.access_token.missing')) unless @token
|
161
|
+
|
162
|
+
authenticate_token
|
163
|
+
|
164
|
+
# Render error response only if no resource found and no previous render happened
|
165
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid')) if !current_resource && !performed?
|
166
|
+
rescue JWT::DecodeError => e
|
167
|
+
if e.message == 'Signature has expired'
|
168
|
+
render_error(401, message: I18n.t('api_guard.access_token.expired'))
|
169
|
+
else
|
170
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid'))
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# Decode the JWT token
|
175
|
+
# and don't verify token expiry for refresh token API request
|
176
|
+
def self.decode_token
|
177
|
+
# TODO: Set token refresh controller dynamic
|
178
|
+
verify_token = (controller_name != 'tokens' || action_name != 'create')
|
179
|
+
@decoded_token = decode(@token, verify_token)
|
180
|
+
end
|
181
|
+
|
182
|
+
# Returns whether the JWT token is issued after the last password change
|
183
|
+
# Returns true if password hasn't changed by the user
|
184
|
+
def self.valid_issued_at?(resource)
|
185
|
+
return true unless ApiGuard.invalidate_old_tokens_on_password_change
|
186
|
+
|
187
|
+
!resource.token_issued_at || @decoded_token[:iat] >= resource.token_issued_at.to_i
|
188
|
+
end
|
189
|
+
|
190
|
+
# Defines "current_{{resource_name}}" method and "@current_{{resource_name}}" instance variable
|
191
|
+
# that returns "resource" value
|
192
|
+
def self.define_current_resource_accessors(resource)
|
193
|
+
define_singleton_method("current_#{@resource_name}") do
|
194
|
+
instance_variable_get("@current_#{@resource_name}") ||
|
195
|
+
instance_variable_set("@current_#{@resource_name}", resource)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
# Authenticate the resource with the '{{resource_name}}_id' in the decoded JWT token
|
200
|
+
# and also, check for valid issued at time and not blacklisted
|
201
|
+
#
|
202
|
+
# Also, set "current_{{resource_name}}" method and "@current_{{resource_name}}" instance variable
|
203
|
+
# for accessing the authenticated resource
|
204
|
+
def self.authenticate_token
|
205
|
+
return unless decode_token
|
206
|
+
|
207
|
+
resource = find_resource_from_token(@resource_name.classify.constantize)
|
208
|
+
|
209
|
+
if resource && valid_issued_at?(resource) && !blacklisted?(resource)
|
210
|
+
define_current_resource_accessors(resource)
|
211
|
+
else
|
212
|
+
render_error(401, message: I18n.t('api_guard.access_token.invalid'))
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def self.find_resource_from_token(resource_class)
|
217
|
+
resource_id = @decoded_token[:"#{@resource_name}_id"]
|
218
|
+
return if resource_id.blank?
|
219
|
+
|
220
|
+
resource_class.find_by(id: resource_id)
|
221
|
+
end
|
222
|
+
|
223
|
+
def self.current_resource
|
224
|
+
return unless respond_to?("current_#{@resource_name}")
|
225
|
+
|
226
|
+
public_send("current_#{@resource_name}")
|
227
|
+
end
|
141
228
|
end
|
142
229
|
end
|
143
230
|
end
|
data/lib/api_guard/version.rb
CHANGED