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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03fd89353f83f1dff916ed717aeb63ab7a957c867f82849e7b9db0c59f8b495e
4
- data.tar.gz: 3934bf4a9824a8d81d28e4ec1eed7d4a4a4fa0fc526154375ad35316fdc10c84
3
+ metadata.gz: 5cbdbe6a99ddb95a194ca2d457a00c632dcd8e70731b6e8bcebf02388c32a7ed
4
+ data.tar.gz: ded2f1d9537467657b493269e3a06093b2208f871a356f056aaf1179cd8e6e85
5
5
  SHA512:
6
- metadata.gz: 16190fb470832b3f483d8879dd41dc4eff235fe84a3274ad4ca31ced70f503a165270b9745ed83c4ae894ac614097adde6fb35434a8659fe9e1b154a93c9bfb3
7
- data.tar.gz: 6345f644b9a59ffd6da22f9f5284baf2a8ac4ef572a95263d15e73c4f5448bb181f7a891f081edfc27422e5b4ca35293b8eb68c8d16dfa63570b2a6eba61c6b3
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ApiGuard
4
- VERSION = '0.5.5'
4
+ VERSION = '0.5.6'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: api_guard_grape
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.5
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Prateek Singh