api_guard_grape 0.5.5 → 0.5.6
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
- 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