Skip to content

Commit

Permalink
feat: add authentication controller
Browse files Browse the repository at this point in the history
  • Loading branch information
LucDelmon committed Aug 23, 2022
1 parent 6a7a027 commit 960fea0
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
26 changes: 26 additions & 0 deletions app/controllers/authentication_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

class AuthenticationController < ApplicationController
skip_before_action :authorize_request, only: :login

# POST /auth/login
# @return [JSON, nil]
def login
@user = User.find_by(email: params[:email])
if @user&.authenticate(params[:password])
exp = 24.hours.from_now

token = JsonWebToken.encode(user_id: @user.id, exp: exp.to_i)
render json: { token: token, exp: exp.strftime('%m-%d-%Y %H:%M') }, status: :ok
else
render json: { error: 'unauthorized' }, status: :unauthorized
end
end

private

# @return [ActionController::Parameters]
def login_params
params.permit(:email, :password)
end
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Rails.application.routes.draw do
mount Sidekiq::Web => '/sidekiq'
resources :users
post '/auth/login', to: 'authentication#login'
resources :authors
resources :books
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
Expand Down
48 changes: 48 additions & 0 deletions spec/requests/authentication_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'Authentications', type: :request do
describe 'POST auth/login' do
let!(:user) { User.create(email: '[email protected]', password: 'password') }
let(:request_type) { :post }
let(:request_url) { auth_login_url }
let(:freeze_time) { Time.current }

before do
allow(JsonWebToken).to receive(:encode).and_return('token')
end

context 'with valid params' do
before { @params = { email: user.email, password: 'password' } }

it 'authenticates the user and return a jwt token for the user' do
Timecop.freeze(freeze_time) { request }
expect(JsonWebToken).to have_received(:encode).with(user_id: user.id, exp: (freeze_time + 24.hours).to_i)
expect(JSON.parse(response.body)).to eq(
{ 'token' => 'token', 'exp' => (freeze_time + 24.hours).strftime('%m-%d-%Y %H:%M') }
)
end
end

shared_examples_for 'a request returning unauthorized' do
it 'returns an unauthorized error' do
request
expect(response).to have_http_status(:unauthorized)
expect(JSON.parse(response.body)).to eq({ 'error' => 'unauthorized' })
end
end

context 'when user does not exist' do
before { @params = { email: '[email protected]', password: 'password' } }

it_behaves_like 'a request returning unauthorized'
end

context 'when password is invalid' do
before { @params = { email: user.email, password: 'error' } }

it_behaves_like 'a request returning unauthorized'
end
end
end

0 comments on commit 960fea0

Please sign in to comment.