model_driven_api 2.3.13 → 2.3.15

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: a5497bdb2727e103fa3727595ca62bbaf065b9135dd9bfbc8674f21506929dd0
4
- data.tar.gz: ad09cdae9730b0f5c7983eb478c660ef8cc1c13d1d2c1cb13cd9a143b67f4029
3
+ metadata.gz: 3c73a32dcfadaf698e4d904a110a4ab140a235699d6d71b1f064127624dc4832
4
+ data.tar.gz: f99c45c100d53fc494bdfef2f886dbb1385951caebfbf5754d6a496f019f1fe3
5
5
  SHA512:
6
- metadata.gz: 719fcf3175dced8eaea5e238551d7d143edc185e9131c44ae9bf5358509de252da07491c27c16f485644c782f73c8f351379744c60f20bc803b074f024ecdbb8
7
- data.tar.gz: ad157de69fbd575e5a9197594901b811a0cb1e74f25eb49146c011fbec9d32ebd6874e8712f2ef8edff4799d9e46cd04e2040c5cbe7c48b3a04e7f428917ab5a
6
+ metadata.gz: 1642e0c66e19c6ea3c8a383d3000329d5bba051803c026c40767e05ebadce23bff75e0983fc4a720a3681b28566d41d3d3e0d2f61f2a23f602b89ada4b078681
7
+ data.tar.gz: 0b31e00c37e1a7511c35b6add9c91428791f8e0c13976f83044d5e52dcb43ef0a70071a04828fdd472e5d783239f7eaeb63669a61b6d3258026e83b47057a050
@@ -6,26 +6,42 @@ class AuthenticateUser
6
6
  end
7
7
  prepend SimpleCommand
8
8
 
9
- def initialize(email, password)
10
- @email = email
11
- @password = password
9
+ def initialize(*args)
10
+ if !args.email.blank? && !args.password.blank?
11
+ @email = args.email
12
+ @password = args.password
13
+ elsif !args.access_token.blank?
14
+ @access_token = args.access_token
15
+ end
12
16
  end
13
17
 
14
18
  def call
15
- JsonWebToken.encode(user_id: api_user.id) if api_user
19
+ if !api_user.blank? && result = JsonWebToken.encode(user_id: api_user.id)
20
+ # The token is created and the api_user exists => Invalidating all the previous tokens
21
+ # Since this is a new login and I don't care from where it comes, new logins always
22
+ # Invalidate older tokens
23
+ UsedToken.where(user_id: api_user.id).update(valid: false)
24
+ return result
25
+ end
26
+ nil
16
27
  end
17
28
 
18
29
  private
19
30
 
20
- attr_accessor :email, :password
31
+ attr_accessor :email, :password, :access_token
21
32
 
22
33
  def api_user
23
- user = User.find_by_email(email)
34
+ if !email.blank? && !password.blank?
35
+ user = User.find_by(email: email)
36
+
37
+ # Verify the password. You can create a blank method for now.
38
+ raise AccessDenied if user.blank? && user.authenticate(password).blank?
39
+ elsif !access_token.blank?
40
+ user = User.find_by(access_token: access_token)
41
+ end
42
+
24
43
  raise AccessDenied unless user.present?
25
44
 
26
- # Verify the password. You can create a blank method for now.
27
- raise AccessDenied if user.authenticate(password).blank?
28
-
29
45
  return user
30
46
  end
31
47
 
@@ -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
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
@@ -0,0 +1,7 @@
1
+ class UsedToken < ApplicationRecord
2
+ belongs_to :user, inverse_of: :used_tokens
3
+
4
+ rails_admin do
5
+ visible false
6
+ end
7
+ end
@@ -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).
@@ -1,14 +1,19 @@
1
1
  class JsonWebToken
2
- class << self
3
- def encode(payload, expiry = 15.minutes.from_now.to_i)
4
- ::JWT.encode(payload.merge(exp: expiry), ::Rails.application.credentials.dig(:secret_key_base).presence||ENV["SECRET_KEY_BASE"])
5
- end
6
-
7
- def decode(token)
8
- body = ::JWT.decode(token, ::Rails.application.credentials.dig(:secret_key_base).presence||ENV["SECRET_KEY_BASE"])[0]
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
+ UsedToken.create(token: result, user_id: payload[:user_id])
7
+ result
13
8
  end
14
- end
9
+
10
+ def decode(token)
11
+ # Check if the passed token is present and valid into the UsedToken
12
+ raise "Token is invalidated by new login" unless UsedToken.exists?(token: token, valid: true)
13
+ body = ::JWT.decode(token, ::Rails.application.credentials.dig(:secret_key_base).presence||ENV["SECRET_KEY_BASE"])[0]
14
+ ::HashWithIndifferentAccess.new body
15
+ rescue
16
+ nil
17
+ end
18
+ end
19
+ 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.13
4
+ version: 2.3.15
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-04-12 00:00:00.000000000 Z
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,14 @@ 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
148
150
  - lib/concerns/api_exception_management.rb
149
151
  - lib/concerns/model_driven_api_role.rb
150
152
  - lib/concerns/model_driven_api_user.rb
@@ -173,7 +175,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
175
  - !ruby/object:Gem::Version
174
176
  version: '0'
175
177
  requirements: []
176
- rubygems_version: 3.0.3
178
+ rubygems_version: 3.0.3.1
177
179
  signing_key:
178
180
  specification_version: 4
179
181
  summary: Convention based RoR engine which uses DB schema introspection to create