model_driven_api 2.3.13 → 2.3.19
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/commands/authenticate_user.rb +26 -9
- data/app/controllers/api/v2/authentication_controller.rb +1 -1
- data/app/controllers/api/v2/info_controller.rb +7 -0
- data/app/models/used_token.rb +3 -0
- data/config/routes.rb +1 -0
- data/db/migrate/20210519145438_create_used_tokens.rb +12 -0
- data/db/migrate/20210528111450_rename_valid_to_is_valid_in_used_token.rb +7 -0
- data/lib/concerns/model_driven_api_user.rb +1 -1
- data/lib/json_web_token.rb +18 -12
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d38e64a791f7147bdc145e1767814ac885fcf75ff5031cf30743b96d8717fb32
|
4
|
+
data.tar.gz: 213dc7345b1061bca3a93826ac9c52b63e97bee20891aca0569f0e14ce11f565
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5d435ae0c87967fcdfb1517cf1f353588635efb1df3a657b555f9d622bd7aff36c684c8c8cfaf764926edaf93109ddabc813867dbb62000a7b92d220c1d1a93e
|
7
|
+
data.tar.gz: 609644b3be46a961b594e95fc601bc48393095a6bf090679094d5227427856ced680c83d0fb44d489589d3e2433d145473bc080a90a8574040c77cfbb59ab47f
|
@@ -6,26 +6,43 @@ class AuthenticateUser
|
|
6
6
|
end
|
7
7
|
prepend SimpleCommand
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
|
11
|
-
|
9
|
+
def initialize(*args)
|
10
|
+
first_arg = args.first
|
11
|
+
if !first_arg[:email].blank? && !first_arg[:password].blank?
|
12
|
+
@email = first_arg[:email]
|
13
|
+
@password = first_arg[:password]
|
14
|
+
elsif !first_arg[:access_token].blank?
|
15
|
+
@access_token = first_arg[:access_token]
|
16
|
+
end
|
12
17
|
end
|
13
18
|
|
14
19
|
def call
|
15
|
-
|
20
|
+
current_u = api_user
|
21
|
+
if !current_u.blank? && result = JsonWebToken.encode(user_id: current_u.id)
|
22
|
+
# The token is created and the api_user exists => Invalidating all the previous tokens
|
23
|
+
# Since this is a new login and I don't care from where it comes, new logins always
|
24
|
+
# Invalidate older tokens
|
25
|
+
UsedToken.where(user_id: api_user.id).update(is_valid: false) if ENV["ALLOW_MULTISESSIONS"] == "false"
|
26
|
+
return result
|
27
|
+
end
|
28
|
+
nil
|
16
29
|
end
|
17
30
|
|
18
31
|
private
|
19
32
|
|
20
|
-
attr_accessor :email, :password
|
33
|
+
attr_accessor :email, :password, :access_token
|
21
34
|
|
22
35
|
def api_user
|
23
|
-
|
36
|
+
if !email.blank? && !password.blank?
|
37
|
+
user = User.find_by(email: email)
|
38
|
+
# Verify the password.
|
39
|
+
raise AccessDenied if user.blank? && user.authenticate(password).blank?
|
40
|
+
elsif !access_token.blank?
|
41
|
+
user = User.find_by(access_token: access_token)
|
42
|
+
end
|
43
|
+
|
24
44
|
raise AccessDenied unless user.present?
|
25
45
|
|
26
|
-
# Verify the password. You can create a blank method for now.
|
27
|
-
raise AccessDenied if user.authenticate(password).blank?
|
28
|
-
|
29
46
|
return user
|
30
47
|
end
|
31
48
|
|
@@ -2,7 +2,7 @@ class Api::V2::AuthenticationController < ActionController::API
|
|
2
2
|
include ::ApiExceptionManagement
|
3
3
|
|
4
4
|
def authenticate
|
5
|
-
command = AuthenticateUser.call(params[:auth][:email], params[:auth][:password])
|
5
|
+
command = !params[:atoken].blank? && User.column_names.include?("access_token") ? AuthenticateUser.call(access_token: params[:atoken]) : AuthenticateUser.call(email: params[:auth][:email], password: params[:auth][:password])
|
6
6
|
|
7
7
|
if command.success?
|
8
8
|
response.headers['Token'] = command.result
|
@@ -15,6 +15,13 @@ class Api::V2::InfoController < Api::V2::ApplicationController
|
|
15
15
|
render json: ::Role.all.to_json, status: 200
|
16
16
|
end
|
17
17
|
|
18
|
+
|
19
|
+
# api :GET, '/api/v2/info/heartbeat'
|
20
|
+
# Just keeps the session alive by returning a new token
|
21
|
+
def heartbeat
|
22
|
+
head :ok
|
23
|
+
end
|
24
|
+
|
18
25
|
# GET '/api/v2/info/translations'
|
19
26
|
def translations
|
20
27
|
render json: I18n.t(".", locale: (params[:locale].presence || :it)).to_json, status: 200
|
data/config/routes.rb
CHANGED
@@ -0,0 +1,12 @@
|
|
1
|
+
class CreateUsedTokens < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :used_tokens do |t|
|
4
|
+
t.string :token
|
5
|
+
t.references :user, null: false, foreign_key: true
|
6
|
+
t.boolean :valid, default: true
|
7
|
+
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
add_index :used_tokens, :token, unique: true
|
11
|
+
end
|
12
|
+
end
|
@@ -2,7 +2,7 @@ module ModelDrivenApiUser
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
|
4
4
|
included do
|
5
|
-
|
5
|
+
has_many :used_tokens, inverse_of: :user, dependent: :destroy
|
6
6
|
## DSL (AKA what to show in the returned JSON)
|
7
7
|
# Use @@json_attrs to drive json rendering for
|
8
8
|
# API model responses (index, show and update ones).
|
data/lib/json_web_token.rb
CHANGED
@@ -1,14 +1,20 @@
|
|
1
1
|
class JsonWebToken
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
::HashWithIndifferentAccess.new body
|
10
|
-
rescue
|
11
|
-
nil
|
12
|
-
end
|
2
|
+
class << self
|
3
|
+
def encode(payload, expiry = 15.minutes.from_now.to_i)
|
4
|
+
result = ::JWT.encode(payload.merge(exp: expiry), ::Rails.application.credentials.dig(:secret_key_base).presence||ENV["SECRET_KEY_BASE"])
|
5
|
+
# Store the created token into the DB for later checks if is invalid
|
6
|
+
# In a public environment management, without login, it has no interest, so I don't pollute the DB
|
7
|
+
UsedToken.find_or_create_by(token: result, user_id: payload[:user_id]) if ENV["ALLOW_MULTISESSIONS"] == "false"
|
8
|
+
result
|
13
9
|
end
|
14
|
-
|
10
|
+
|
11
|
+
def decode(token)
|
12
|
+
# Check if the passed token is present and valid into the UsedToken
|
13
|
+
raise "Token is invalidated by new login" unless UsedToken.exists?(token: token, is_valid: true) if ENV["ALLOW_MULTISESSIONS"] == "false"
|
14
|
+
body = ::JWT.decode(token, ::Rails.application.credentials.dig(:secret_key_base).presence||ENV["SECRET_KEY_BASE"])[0]
|
15
|
+
::HashWithIndifferentAccess.new body
|
16
|
+
rescue
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: model_driven_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.3.
|
4
|
+
version: 2.3.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriele Tassoni
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thecore_backend_commons
|
@@ -139,12 +139,15 @@ files:
|
|
139
139
|
- app/controllers/api/v2/authentication_controller.rb
|
140
140
|
- app/controllers/api/v2/info_controller.rb
|
141
141
|
- app/controllers/api/v2/users_controller.rb
|
142
|
+
- app/models/used_token.rb
|
142
143
|
- config/initializers/after_initialize_for_model_driven_api.rb
|
143
144
|
- config/initializers/cors_api_thecore.rb
|
144
145
|
- config/initializers/knock.rb
|
145
146
|
- config/initializers/time_with_zone.rb
|
146
147
|
- config/initializers/wrap_parameters.rb
|
147
148
|
- config/routes.rb
|
149
|
+
- db/migrate/20210519145438_create_used_tokens.rb
|
150
|
+
- db/migrate/20210528111450_rename_valid_to_is_valid_in_used_token.rb
|
148
151
|
- lib/concerns/api_exception_management.rb
|
149
152
|
- lib/concerns/model_driven_api_role.rb
|
150
153
|
- lib/concerns/model_driven_api_user.rb
|
@@ -173,7 +176,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
176
|
- !ruby/object:Gem::Version
|
174
177
|
version: '0'
|
175
178
|
requirements: []
|
176
|
-
rubygems_version: 3.0.3
|
179
|
+
rubygems_version: 3.0.3.1
|
177
180
|
signing_key:
|
178
181
|
specification_version: 4
|
179
182
|
summary: Convention based RoR engine which uses DB schema introspection to create
|