diff --git a/app/controllers/api/application_controller.rb b/app/controllers/api/application_controller.rb index aa14369..9c82c96 100644 --- a/app/controllers/api/application_controller.rb +++ b/app/controllers/api/application_controller.rb @@ -29,10 +29,17 @@ module API end def ping - render json: { pong: true } + ping_response + end + + def ping_auth + ping_response end def authenticate! + if key = authenticate_with_http_token { |t| Key.authenticate(t) } + self.current_user = key.user + end head :unauthorized if current_user.nil? end @@ -43,5 +50,12 @@ module API head :not_acceptable, content_type: 'application/json' end end + + + private + + def ping_response + render json: { pong: true } + end end end diff --git a/app/models/key.rb b/app/models/key.rb index 80ffe5f..76da4dd 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -4,4 +4,10 @@ class Key < ActiveRecord::Base has_secure_token :token validates :name, presence: true + + class << self + def authenticate token + find_by_token token + end + end end diff --git a/config/routes.rb b/config/routes.rb index 864093d..c098212 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,6 +3,7 @@ Rails.application.routes.draw do namespace :api do get '/ping', to: 'application#ping' + get '/ping/auth', to: 'application#ping_auth' match '*all', to: 'application#cor_preflight', via: :options resources :playlists, only: %i[index show create update destroy] resources :sessions, only: :create diff --git a/spec/integration/api/application_spec.rb b/spec/integration/api/application_spec.rb index 5db1d4f..a6ad821 100644 --- a/spec/integration/api/application_spec.rb +++ b/spec/integration/api/application_spec.rb @@ -7,6 +7,33 @@ describe 'API application' do end end + describe 'authenticated ping endpoint' do + let(:headers) { {} } + subject { response } + + before { get api_ping_auth_path, { format: :json }, headers } + + it 'requests authentication' do + expect(response).to have_http_status 401 + end + + context 'when session is authenticated' do + before { api_sign_in } + + it { is_expected.to have_http_status 200 } + end + + context 'when requests has a valid authentication token' do + let(:key) { create :key } + let(:headers) do { + 'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Token + .encode_credentials(key.token) + } end + + it { is_expected.to have_http_status 200 } + end + end + describe 'formats handling' do before { api_sign_in } diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb index 0f0cfbf..05775e7 100644 --- a/spec/models/key_spec.rb +++ b/spec/models/key_spec.rb @@ -9,4 +9,20 @@ describe Key do key.save expect(key.token).to match /\A[\w\d]{24,}\z/ end + + describe '.authenticate' do + context 'when given token belong to existing key' do + before { key.save } + + it 'returns the key' do + expect(described_class.authenticate key.token).to eq key + end + end + + context 'when given token is unknown' do + it 'returns nil' do + expect(described_class.authenticate key.token).to be nil + end + end + end end