model_driven_api 3.12.1 → 3.13.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
- data/app/controllers/api/v2/auth/oauth_controller.rb +9 -1
- data/config/routes.rb +3 -2
- data/lib/json_web_token.rb +28 -5
- data/lib/model_driven_api/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: 9fcc02687ce88ff1cc47523ddd04f9d1a7c4918d40c2f2765d59f19a1697c0dd
|
|
4
|
+
data.tar.gz: 2eb8c0586bbbdaed24d44d5c8de670ff5339df53c7d6609eedcb8559cc49e16a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c48fa599733f52da66626b80067df10d3cb223c3f950a3f3e4f62afe104e50f5b93778cf228b95b89268227b811e74e3b10455fd8d8a3cff0f9d8b8d0f1caf5b
|
|
7
|
+
data.tar.gz: bb50aa93d2b0ce0616e8128b9634b6e38e7fd066bb8fd7a0dba61429000dbf3d125b49930273ebe333126f8ee1104d922cf78eec8f4db6d946cb3f47768d8708
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
module Api::V2::Auth
|
|
2
2
|
class OauthController < ActionController::API
|
|
3
|
+
# L'identità arriva solo da request.env['omniauth.auth'], che il middleware OmniAuth imposta
|
|
4
|
+
# dopo aver verificato il login col provider; mai dai parametri della richiesta, che chiunque
|
|
5
|
+
# può inviare (fino alla 3.12.1 bastava una POST con email= per avere il JWT di quell'utente).
|
|
3
6
|
def callback
|
|
4
|
-
|
|
7
|
+
auth = request.env['omniauth.auth']
|
|
8
|
+
info = auth&.info
|
|
9
|
+
user = info && ThecoreAuthCommons.check_user(info.email,
|
|
10
|
+
info.first_name.presence || info.name,
|
|
11
|
+
info.last_name,
|
|
12
|
+
auth.provider)
|
|
5
13
|
|
|
6
14
|
unless user
|
|
7
15
|
render json: { error: "User not registered" }, status: :unauthorized
|
data/config/routes.rb
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
Rails.application.routes.draw do
|
|
4
4
|
scope ENV.fetch("RAILS_RELATIVE_URL_ROOT", "/") do
|
|
5
5
|
if ThecoreAuthCommons.oauth_vars?
|
|
6
|
-
# OmniAuth callbacks need these top-level paths:
|
|
7
|
-
|
|
6
|
+
# OmniAuth callbacks need these top-level paths. The callback goes straight to the controller:
|
|
7
|
+
# a redirect would drop the verified request.env['omniauth.auth'] the middleware has just set.
|
|
8
|
+
match "/auth/:provider/callback", to: "api/v2/auth/oauth#callback", via: [:get, :post], defaults: { format: :json }
|
|
8
9
|
match "/auth/failure", to: redirect("/api/v2/auth/failure"), via: [:get, :post]
|
|
9
10
|
end
|
|
10
11
|
namespace :api, constraints: { format: :json } do
|
data/lib/json_web_token.rb
CHANGED
|
@@ -1,21 +1,44 @@
|
|
|
1
1
|
class JsonWebToken
|
|
2
2
|
class << self
|
|
3
3
|
def encode(payload, expiry = ENV.fetch('SESSION_TIMEOUT_IN_MINUTES', 31).to_i.minutes.from_now.to_i)
|
|
4
|
-
result = ::JWT.encode(payload.merge(exp: expiry),
|
|
4
|
+
result = ::JWT.encode(payload.merge(exp: expiry), signing_key)
|
|
5
5
|
# Store the created token into the DB for later checks if is invalid
|
|
6
6
|
# In a public environment management, without login, it has no interest, so I don't pollute the DB
|
|
7
7
|
UsedToken.find_or_create_by(token: result, user_id: payload[:user_id]) if ENV["ALLOW_MULTISESSIONS"] == "false"
|
|
8
8
|
result
|
|
9
9
|
end
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
def decode(token)
|
|
12
|
-
# Check if the passed token is present and valid into the UsedToken
|
|
12
|
+
# Check if the passed token is present and valid into the UsedToken
|
|
13
13
|
raise "Token is invalidated by new login" if !UsedToken.exists?(token: token, is_valid: true) && ENV["ALLOW_MULTISESSIONS"] == "false"
|
|
14
|
-
body =
|
|
14
|
+
body = verified_payload(token)
|
|
15
15
|
Rails.logger.debug "JsonWebToken: decode -> body -> #{body}"
|
|
16
16
|
::HashWithIndifferentAccess.new body
|
|
17
17
|
# rescue
|
|
18
18
|
# nil
|
|
19
19
|
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def signing_key
|
|
24
|
+
::Rails.application.credentials.dig(:secret_key_base).presence||ENV["SECRET_KEY_BASE"]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# After a SECRET_KEY_BASE rotation, a token signed with the previous key is still accepted until
|
|
28
|
+
# SECRET_KEY_BASE_PREVIOUS_EXPIRES_AT (ISO 8601), so app users never log in again: every authenticated
|
|
29
|
+
# response renews the token with the current key. The previous key may be public, so it is never
|
|
30
|
+
# trusted without an expiry, and only a bad signature falls back to it (an expired token stays expired).
|
|
31
|
+
def verified_payload(token)
|
|
32
|
+
::JWT.decode(token, signing_key)[0]
|
|
33
|
+
rescue ::JWT::VerificationError
|
|
34
|
+
previous = previous_signing_key or raise
|
|
35
|
+
::JWT.decode(token, previous)[0]
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def previous_signing_key
|
|
39
|
+
key = ENV["SECRET_KEY_BASE_PREVIOUS"].presence or return
|
|
40
|
+
expires_at = Time.iso8601(ENV["SECRET_KEY_BASE_PREVIOUS_EXPIRES_AT"].to_s) rescue nil
|
|
41
|
+
key if expires_at && Time.current < expires_at
|
|
42
|
+
end
|
|
20
43
|
end
|
|
21
|
-
end
|
|
44
|
+
end
|