From 43293f00df974df6441bb4fecb3d124dda9beb6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Turbelin?= Date: Sat, 2 May 2020 18:30:01 +0200 Subject: [PATCH] Make the endpoint unrelated to enterprise id Better to avoid to have endpoint specific to an enterprise as we don't know the enterprise id yet on DFC side --- engines/dfc_provider/README.md | 8 +- .../dfc_provider/api/products_controller.rb | 17 ++-- .../dfc_provider/product_serializer.rb | 5 +- engines/dfc_provider/config/routes.rb | 2 +- engines/dfc_provider/dfc_provider.gemspec | 2 +- .../api/products_controller_spec.rb | 80 ++++++++----------- 6 files changed, 46 insertions(+), 68 deletions(-) diff --git a/engines/dfc_provider/README.md b/engines/dfc_provider/README.md index dda1304a56..8e73633c46 100644 --- a/engines/dfc_provider/README.md +++ b/engines/dfc_provider/README.md @@ -3,6 +3,8 @@ This engine is implementing the Data Food Consortium specifications in order to serve semantic data. You can find more details about this on https://github.com/datafoodconsortium. -Basically, it allows an OFN user: -* to retrieve an Access token from DFC Authorization server (using OIDC implemntation) -* to serve his Products Catalog through a dedicated API using JSON-LD format, structured by the DFC Ontology. +Basically, it allows an OFN user linked to an enterprise: +* to serve his Products Catalog through a dedicated API using JSON-LD format, structured by the DFC Ontology +* to be authenticated thanks to an Access Token from DFC Authorization server (using an OIDC implementation) + +The API endpoint for the catalog is `/api/dfc_provider/enterprise/prodcuts.json` and you need to pass the token inside an authentication header (`Authentication: Bearer 123mytoken456`). diff --git a/engines/dfc_provider/app/controllers/dfc_provider/api/products_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/api/products_controller.rb index ce33ba1c72..d31aa65b75 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/api/products_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/api/products_controller.rb @@ -16,9 +16,8 @@ module DfcProvider include Rails.application.routes.url_helpers before_filter :check_authorization, - :check_enterprise, :check_user, - :check_accessibility + :check_enterprise respond_to :json @@ -28,7 +27,7 @@ module DfcProvider includes(:product, :inventory_items) products_json = ::DfcProvider::ProductSerializer. - new(@enterprise, products, base_url). + new(products, base_url). serialized_json render json: products_json @@ -37,7 +36,7 @@ module DfcProvider private def check_enterprise - @enterprise = ::Enterprise.where(id: params[:enterprise_id]).first + @enterprise = @user.enterprises.first return if @enterprise.present? @@ -47,7 +46,7 @@ module DfcProvider def check_authorization return if access_token.present? - head :unauthorized + head :unprocessable_entity end def check_user @@ -55,13 +54,7 @@ module DfcProvider return if @user.present? - head :unprocessable_entity - end - - def check_accessibility - return if @enterprise.owner == @user - - head :forbidden + head :unauthorized end def base_url diff --git a/engines/dfc_provider/app/serializers/dfc_provider/product_serializer.rb b/engines/dfc_provider/app/serializers/dfc_provider/product_serializer.rb index 8bd33abed6..35a840c6e1 100644 --- a/engines/dfc_provider/app/serializers/dfc_provider/product_serializer.rb +++ b/engines/dfc_provider/app/serializers/dfc_provider/product_serializer.rb @@ -4,8 +4,7 @@ # into JSON-LD format based on DFC ontology module DfcProvider class ProductSerializer - def initialize(enterprise, products, base_url) - @enterprise = enterprise + def initialize(products, base_url) @products = products @base_url = base_url end @@ -17,7 +16,7 @@ module DfcProvider "DFC" => "http://datafoodconsortium.org/ontologies/DFC_FullModel.owl#", "@base" => @base_url }, - "@id" => "/enterprises/#{@enterprise.id}/products", + "@id" => "/enterprise/products", "DFC:supplies" => serialized_products }.to_json end diff --git a/engines/dfc_provider/config/routes.rb b/engines/dfc_provider/config/routes.rb index d716c6100d..c9579cd4d1 100644 --- a/engines/dfc_provider/config/routes.rb +++ b/engines/dfc_provider/config/routes.rb @@ -3,7 +3,7 @@ DfcProvider::Engine.routes.draw do namespace :api do scope :dfc_provider, as: :dfc_provider, path: '/dfc_provider' do - resources :enterprises, only: :none do + resource :enterprise, only: :none do resources :products, only: %i[index] end end diff --git a/engines/dfc_provider/dfc_provider.gemspec b/engines/dfc_provider/dfc_provider.gemspec index 4a44fede6b..4684aaaa18 100644 --- a/engines/dfc_provider/dfc_provider.gemspec +++ b/engines/dfc_provider/dfc_provider.gemspec @@ -11,7 +11,7 @@ Gem::Specification.new do |spec| spec.version = DfcProvider::VERSION spec.authors = ["developers@ofn"] spec.summary = 'Provides an API stack implementing DFC semantic ' \ - 'specifications' + 'specifications' spec.files = Dir["{app,config,lib}/**/*"] + ['README.md'] spec.test_files = Dir['spec/**/*'] diff --git a/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb b/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb index 754b81fd94..c12ef26bc1 100644 --- a/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb +++ b/engines/dfc_provider/spec/controllers/dfc_provider/api/products_controller_spec.rb @@ -5,7 +5,8 @@ require 'spec_helper' describe DfcProvider::Api::ProductsController, type: :controller do render_views - let(:enterprise) { create(:distributor_enterprise) } + let(:user) { create(:user) } + let(:enterprise) { create(:distributor_enterprise, owner: user) } let(:product) do create(:simple_product, supplier: enterprise ) end @@ -15,7 +16,6 @@ describe DfcProvider::Api::ProductsController, type: :controller do variant: product.variants.first, visible: true) end - let(:user) { enterprise.owner } describe('.index') do context 'with authorization token' do @@ -23,64 +23,48 @@ describe DfcProvider::Api::ProductsController, type: :controller do request.env['Authorization'] = 'Bearer 123456.abcdef.123456' end - 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) + context 'with an authenticated user' do + before do + allow_any_instance_of(DfcProvider::AuthorizationControl) + .to receive(:process) + .and_return(user) + end + + context 'with an enterprise' do + before { get :index } + + it 'is successful' do + expect(response.status).to eq 200 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 + it 'renders the related product' do + expect(response.body) + .to include("\"DFC:description\":\"#{product.variants.first.name}\"") end end - context 'without a linked user' do - before do - allow_any_instance_of(DfcProvider::AuthorizationControl) - .to receive(:process) - .and_return(nil) - end + context 'without a recorded enterprise' do + let(:enterprise) { create(:enterprise) } - before do - get :index, enterprise_id: enterprise.id - end + before { get :index } - it 'returns unprocessable_entity head' do - expect(response.status).to eq 422 + it 'returns not_found head' do + expect(response.status).to eq 404 end end end - context 'without a recorded enterprise' do + context 'without an authenticated user' do before do - get :index, enterprise_id: '123456' + allow_any_instance_of(DfcProvider::AuthorizationControl) + .to receive(:process) + .and_return(nil) end - it 'returns not_found head' do - expect(response.status).to eq 404 + before { get :index } + + it 'returns unauthorized head' do + expect(response.status).to eq 401 end end end @@ -88,8 +72,8 @@ describe DfcProvider::Api::ProductsController, type: :controller do context 'without an authorization token' do before { get :index, enterprise_id: enterprise.id } - it 'returns unauthorized head' do - expect(response.status).to eq 401 + it 'returns unprocessable_entity head' do + expect(response.status).to eq 422 end end end