diff options
-rw-r--r-- | app/controllers/api/authentications_controller.rb | 15 | ||||
-rw-r--r-- | app/controllers/api/authentications_controller/create_logic.rb | 23 | ||||
-rw-r--r-- | app/controllers/api/refresh_tokens_controller.rb | 7 | ||||
-rw-r--r-- | app/controllers/api/user_accounts_controller.rb | 11 | ||||
-rw-r--r-- | app/controllers/api/user_accounts_controller/create_logic.rb | 25 | ||||
-rw-r--r-- | app/controllers/application_controller.rb | 19 | ||||
-rw-r--r-- | app/controllers/authenticated_controller.rb | 17 | ||||
-rw-r--r-- | app/controllers/services/token_generation_service.rb | 13 | ||||
-rw-r--r-- | spec/requests/post_refresh_tokens_spec.rb | 7 |
9 files changed, 56 insertions, 81 deletions
diff --git a/app/controllers/api/authentications_controller.rb b/app/controllers/api/authentications_controller.rb index 3eb52c7..b9a6f08 100644 --- a/app/controllers/api/authentications_controller.rb +++ b/app/controllers/api/authentications_controller.rb @@ -4,20 +4,29 @@ module Api # The controller that handles authentications. class AuthenticationsController < ApplicationController def create - @token = logic(permitted_params).call + @current_user_account = UserAccount.find_by(email: permitted_params[:email]) - render json: @token, status: :ok and return if @token + unless @current_user_account&.authenticate(permitted_params[:password]) + render json: { error_message: 'Credenciales incorrectas' }, status: :unauthorized and return + end - render json: { error_message: 'Credenciales incorrectas' }, status: :unauthorized + render json: generate_token, status: :ok end def destroy current_user_account.session_key = nil current_user_account.save + + render status: :no_content end private + def service_params + { email: @current_user_account.email, + role: @current_user_account.role } + end + def permitted_params params.require(:credentials).permit(:email, :password) end diff --git a/app/controllers/api/authentications_controller/create_logic.rb b/app/controllers/api/authentications_controller/create_logic.rb deleted file mode 100644 index 782c760..0000000 --- a/app/controllers/api/authentications_controller/create_logic.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -module Api - class AuthenticationsController - # The logic for the create method of AuthenticationsController. - class CreateLogic - include TokenGenerationConcern - - def initialize(params) - @email = params[:email] - @password = params[:password] - @user_account = UserAccount.find_by(email: @email) - end - - def call - return unless @user_account&.authenticate(@password) - - generate_user_session_key(@user_account) - generate_token - end - end - end -end diff --git a/app/controllers/api/refresh_tokens_controller.rb b/app/controllers/api/refresh_tokens_controller.rb index 3b0843e..fd16079 100644 --- a/app/controllers/api/refresh_tokens_controller.rb +++ b/app/controllers/api/refresh_tokens_controller.rb @@ -3,16 +3,17 @@ module Api # The controller to generate new tokens. class RefreshTokensController < AuthenticatedController + before_action :validate_jwt + def create @current_user_account.update_attribute(:session_key, SecureRandom.hex(16)) - @token = { token: service.call(DateTime.current + 30), refresh: service.call(authentication_token[0]['exp']) } + @token = service.call(authentication_token[0]['exp']) render json: @token, status: :ok end def service_params - { email: @current_user_account.email, role: @current_user_account.role, - session_key: @current_user_account.session_key } + { email: @current_user_account.email, role: @current_user_account.role } end def service diff --git a/app/controllers/api/user_accounts_controller.rb b/app/controllers/api/user_accounts_controller.rb index 3e03cf9..ca5d93b 100644 --- a/app/controllers/api/user_accounts_controller.rb +++ b/app/controllers/api/user_accounts_controller.rb @@ -10,15 +10,20 @@ module Api end def create - @token = logic(permitted_params).call + @user_account = UserAccount.new(permitted_params) - render json: @token, status: :ok and return if @token + render json: generate_token, status: :ok and return if @user_account.save - render json: { errors: @logic.user_account.errors.full_messages }, status: :unprocessable_entity + render json: @user_account.errors.full_messages, status: :unprocessable_entity end private + def service_params + { email: @user_account.email, + role: @user_account.role } + end + def permitted_params params.require(:user_account).permit(:role, :email, :first_name, :last_name, :password) end diff --git a/app/controllers/api/user_accounts_controller/create_logic.rb b/app/controllers/api/user_accounts_controller/create_logic.rb deleted file mode 100644 index 2e686b3..0000000 --- a/app/controllers/api/user_accounts_controller/create_logic.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true - -module Api - class UserAccountsController - # The UserAccountsController CreateLogic class. - class CreateLogic - attr_reader :user_account - - include TokenGenerationConcern - - def initialize(params) - @params = params - end - - def call - @user_account = UserAccount.new(@params) - - return unless @user_account.save - - generate_user_session_key(@user_account) - generate_token - end - end - end -end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ea108b4..7f803c8 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,22 +6,9 @@ class ApplicationController < ActionController::API @logic = Object.const_get("#{self.class}::#{action_name.camelize}Logic").new(permitted_params) end - protected + private - def current_user_account - return if decoded_token.nil? - - email = decoded_token[0]['data'] - @current_user_account ||= UserAccount.find_by(email:) - end - - def authentication_token - @authentication_token ||= request.headers[:authorization]&.sub(/^Bearer /, '') - end - - def decoded_token - @decoded_token ||= JWT.decode(authentication_token, ENV['HMAC_SECRET_KEY'], true, { algorithm: 'HS512' }) - rescue JWT::ExpiredSignature - @decoded_token = nil + def generate_token + Services::TokenGenerationService.new(service_params).call(DateTime.current + 5.days) end end diff --git a/app/controllers/authenticated_controller.rb b/app/controllers/authenticated_controller.rb index 56be1ad..7098202 100644 --- a/app/controllers/authenticated_controller.rb +++ b/app/controllers/authenticated_controller.rb @@ -6,6 +6,23 @@ class AuthenticatedController < ApplicationController private + def current_user_account + return if decoded_token.nil? + + email = decoded_token[0]['data'] + @current_user_account ||= UserAccount.find_by(email:) + end + + def authentication_token + @authentication_token ||= request.headers[:authorization]&.sub(/^Bearer /, '') + end + + def decoded_token + @decoded_token ||= JWT.decode(authentication_token, ENV['HMAC_SECRET_KEY'], true, { algorithm: 'HS512' }) + rescue JWT::ExpiredSignature + @decoded_token = nil + end + def validate_jwt return if valid_token diff --git a/app/controllers/services/token_generation_service.rb b/app/controllers/services/token_generation_service.rb index 94f9907..8edce9c 100644 --- a/app/controllers/services/token_generation_service.rb +++ b/app/controllers/services/token_generation_service.rb @@ -6,17 +6,22 @@ module Services def initialize(params) @email = params[:email] @role = params[:role] - @session_key = params[:session_key] + @user_account = UserAccount.find_by(email: @email) end - def call(expiration) - JWT.encode(payload.merge({ exp: expiration.to_i }), ENV['HMAC_SECRET_KEY'], 'HS512') + def call(refresh_token_expiration) + @user_account.update_attribute(:session_key, SecureRandom.hex(16)) + { token: generate_token(DateTime.current + 30.minutes), refresh: generate_token(refresh_token_expiration.to_i) } end private + def generate_token(expiration) + JWT.encode(payload.merge({ exp: expiration.to_i }), ENV['HMAC_SECRET_KEY'], 'HS512') + end + def payload - { data: @email, aud: @role, jti: @session_key } + { data: @email, aud: @role, jti: @user_account.session_key } end end end diff --git a/spec/requests/post_refresh_tokens_spec.rb b/spec/requests/post_refresh_tokens_spec.rb index 836e340..5d8f8f0 100644 --- a/spec/requests/post_refresh_tokens_spec.rb +++ b/spec/requests/post_refresh_tokens_spec.rb @@ -15,10 +15,9 @@ RSpec.describe 'POST /api/refresh_tokens', type: :request do context 'with an expired token' do it 'returns an error message' do - user.update_attribute(:session_key, SecureRandom.hex(16)) - service_params = { email: user.email, role: user.role, session_key: user.session_key } - token = Services::TokenGenerationService.new(service_params).call(DateTime.current - 7.days) - headers = { 'CONTENT_TYPE' => 'application/json', 'Authorization' => "Bearer #{token}" } + service_params = { email: user.email, role: user.role } + jwt = Services::TokenGenerationService.new(service_params).call(DateTime.current - 5.days) + headers = { 'CONTENT_TYPE' => 'application/json', 'Authorization' => "Bearer #{jwt[:refresh]}" } post('/api/refresh_tokens', headers:) expect(response).to have_http_status(401) expect(response.body).to include('error_message') |