Add the access token logic, light version

This commit is contained in:
François Turbelin
2020-04-28 12:12:04 +02:00
parent a8fb059482
commit c1d173d601
6 changed files with 175 additions and 33 deletions

View File

@@ -56,16 +56,18 @@ GIT
rails-i18n
spree_core (>= 1.1)
PATH
remote: engines/dfc_provider
specs:
dfc_provider (0.0.1)
PATH
remote: engines/catalog
specs:
catalog (0.0.1)
PATH
remote: engines/dfc_provider
specs:
dfc_provider (0.0.1)
jwt (~> 2.2)
rspec (~> 3.9)
PATH
remote: engines/order_management
specs:

View File

@@ -3,11 +3,24 @@
# Controller used to provide the API products for the DFC application
module DfcProvider
module Api
class ProductsController < ::Api::BaseController
skip_before_filter :authenticate_user
before_filter :set_enterprise
before_filter :authenticate_user
skip_authorization_check
class ProductsController < ::ActionController::Metal
include ActionController::Head
include AbstractController::Rendering
include ActionController::Rendering
include ActionController::Renderers::All
include ActionController::MimeResponds
include ActionController::ImplicitRender
include AbstractController::Callbacks
# To access 'base_url' helper
include ActionController::UrlFor
include Rails.application.routes.url_helpers
before_filter :check_authorization,
:check_enterprise,
:check_user,
:check_accessibility
respond_to :json
def index
products = @enterprise.
@@ -23,17 +36,45 @@ module DfcProvider
private
def authenticate_user
@current_api_user = @enterprise.owner
def check_enterprise
@enterprise = ::Enterprise.where(id: params[:enterprise_id]).first
return if @enterprise.present?
head :not_found
end
def set_enterprise
@enterprise = ::Enterprise.find(params[:enterprise_id])
def check_authorization
return if access_token.present?
head :unauthorized
end
def check_user
@user = authorization_control.process
return if @user.present?
head :unprocessable_entity
end
def check_accessibility
return if @enterprise.owner == @user
head :forbidden
end
def base_url
"#{root_url}api/dfc_provider"
end
def access_token
request.headers['Authorization'].to_s.split(' ').last
end
def authorization_control
DfcProvider::AuthorizationControl.new(access_token)
end
end
end
end

View File

@@ -0,0 +1,31 @@
# frozen_string_literal: true
# Service used to authorize the user on DCF Provider API
# It controls an OICD Access token and an enterprise.
module DfcProvider
class AuthorizationControl
def initialize(access_token)
@access_token = access_token
end
def process
decode_token
find_ofn_user
end
def decode_token
data = JWT.decode(
@access_token,
nil,
false
)
@header = data.last
@payload = data.first
end
def find_ofn_user
Spree::User.where(email: @payload['email']).first
end
end
end

View File

@@ -6,13 +6,17 @@ $LOAD_PATH.push File.expand_path('lib', __dir__)
require "dfc_provider/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = 'dfc_provider'
s.version = DfcProvider::VERSION
s.authors = ['Admin OFF']
s.email = ['admin@openfoodfrance.org']
s.summary = 'Provides an API stack implementing DFC semantic specifications'
Gem::Specification.new do |spec|
spec.name = 'dfc_provider'
spec.version = DfcProvider::VERSION
spec.authors = ['Admin OFF']
spec.email = ['admin@openfoodfrance.org']
spec.summary = 'Provides an API stack implementing DFC semantic ' \
'specifications'
s.files = Dir["{app,config,db,lib}/**/*"] + ['README.rdoc']
s.test_files = Dir['test/**/*']
spec.files = Dir["{app,config,lib}/**/*"] + ['README.md']
spec.test_files = Dir['spec/**/*']
spec.add_dependency 'jwt', '~> 2.2'
spec.add_dependency 'rspec', '~> 3.9'
end

View File

@@ -1,3 +1,5 @@
# frozen_string_literal: true
require 'spec_helper'
describe DfcProvider::Api::ProductsController, type: :controller do
@@ -13,22 +15,82 @@ describe DfcProvider::Api::ProductsController, type: :controller do
variant: product.variants.first,
visible: true)
end
let(:user) { enterprise.owner }
describe('.index') do
before do
allow(controller)
.to receive(:spree_current_user) { enterprise.owner }
context 'with authorization token' do
before do
request.env['Authorization'] = 'Bearer 123456.abcdef.123456'
end
get :index, enterprise_id: enterprise.id
context 'with an enterprise' do
context 'with a linked user' do
before do
allow_any_instance_of(DfcProvider::AuthorizationControl)
.to receive(:process)
.and_return(user)
end
context 'with valid accessibility' do
before do
get :index, enterprise_id: enterprise.id
end
it 'is successful' do
expect(response.status).to eq 200
end
it 'renders the related product' do
expect(response.body)
.to include("\"DFC:description\":\"#{product.variants.first.name}\"")
end
end
context 'without valid accessibility' do
before do
get :index, enterprise_id: create(:enterprise).id
end
it 'returns unauthorized head' do
expect(response.status).to eq 403
end
end
end
context 'without a linked user' do
before do
allow_any_instance_of(DfcProvider::AuthorizationControl)
.to receive(:process)
.and_return(nil)
end
before do
get :index, enterprise_id: enterprise.id
end
it 'returns unprocessable_entity head' do
expect(response.status).to eq 422
end
end
end
context 'without a recorded enterprise' do
before do
get :index, enterprise_id: '123456'
end
it 'returns not_found head' do
expect(response.status).to eq 404
end
end
end
it 'is successful' do
expect(response.status).to eq 200
end
context 'without an authorization token' do
before { get :index, enterprise_id: enterprise.id }
it 'renders the related product' do
expect(response.body)
.to include("\"DFC:description\":\"#{product.variants.first.name}\"")
it 'returns unauthorized head' do
expect(response.status).to eq 401
end
end
end
end

View File

@@ -1,3 +1,5 @@
# frozen_string_literal: true
require "../../spec/spec_helper.rb"
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }