mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-03-01 02:03:22 +00:00
Merge pull request #13475 from mkllnk/dfc-sib-tokens
Accept tokens from Startin'Blox OIDC server
This commit is contained in:
11
.simplecov
11
.simplecov
@@ -2,10 +2,17 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
SimpleCov.start 'rails' do
|
||||
# The rails profile contains some filters already:
|
||||
#
|
||||
# - "/test/"
|
||||
# - "/features/"
|
||||
# - "/spec/"
|
||||
# - "/autotest/"
|
||||
# - /^\/config\//
|
||||
# - /^\/db\//
|
||||
add_filter '/bin/'
|
||||
add_filter '/config/'
|
||||
add_filter '/config/' # to include engine config
|
||||
add_filter '/script'
|
||||
add_filter '/db'
|
||||
|
||||
formatter SimpleCov::Formatter::SimpleFormatter
|
||||
end
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
#!/bin/env ruby
|
||||
# frozen_string_literal: true
|
||||
|
||||
-c master
|
||||
--compare master
|
||||
|
||||
# This shouldn't be needed in undercover > 0.7.4
|
||||
#
|
||||
# * https://github.com/grodowski/undercover/issues/233
|
||||
--exclude-files "bin/*,db/*,config/*,spec/*,engines/*/config/*,engines/*/spec/*"
|
||||
|
||||
@@ -75,6 +75,7 @@ class Enterprise < ApplicationRecord
|
||||
has_one :stripe_account, dependent: :destroy
|
||||
has_many :vouchers, dependent: :restrict_with_exception
|
||||
has_many :connected_apps, dependent: :destroy
|
||||
has_many :dfc_permissions, dependent: :destroy
|
||||
has_one :custom_tab, dependent: :destroy
|
||||
|
||||
delegate :latitude, :longitude, :city, :state_name, to: :address
|
||||
|
||||
@@ -30,8 +30,7 @@ module DfcProvider
|
||||
# - Spree::Shipment
|
||||
# - Subscription
|
||||
def authorized(address)
|
||||
current_user.ship_address_id == address.id ||
|
||||
current_user.bill_address_id == address.id ||
|
||||
user_address(address) ||
|
||||
[
|
||||
customer_address(address),
|
||||
public_enterprise_group_address(address),
|
||||
@@ -40,6 +39,13 @@ module DfcProvider
|
||||
].any?(&:exists?)
|
||||
end
|
||||
|
||||
def user_address(address)
|
||||
return false if current_user.is_a? ApiUser
|
||||
|
||||
current_user.ship_address_id == address.id ||
|
||||
current_user.bill_address_id == address.id
|
||||
end
|
||||
|
||||
def customer_address(address)
|
||||
current_user.customers.where(bill_address: address).or(
|
||||
current_user.customers.where(ship_address: address)
|
||||
|
||||
@@ -3,12 +3,15 @@
|
||||
# Controller used to provide the API products for the DFC application
|
||||
module DfcProvider
|
||||
class ApplicationController < ActionController::Base
|
||||
class Unauthorized < StandardError; end
|
||||
|
||||
include ActiveStorage::SetCurrent
|
||||
|
||||
protect_from_forgery with: :null_session
|
||||
|
||||
rescue_from ActiveRecord::RecordNotFound, with: :not_found
|
||||
rescue_from CanCan::AccessDenied, with: :unauthorized
|
||||
rescue_from Unauthorized, with: :unauthorized
|
||||
|
||||
before_action :check_authorization
|
||||
|
||||
@@ -16,6 +19,13 @@ module DfcProvider
|
||||
|
||||
private
|
||||
|
||||
def require_permission(scope)
|
||||
return if current_user.is_a? Spree::User
|
||||
return if current_user.permissions(scope).where(enterprise: current_enterprise).exists?
|
||||
|
||||
raise Unauthorized
|
||||
end
|
||||
|
||||
def check_authorization
|
||||
unauthorized if current_user.nil?
|
||||
end
|
||||
|
||||
@@ -7,6 +7,8 @@ module DfcProvider
|
||||
before_action :check_enterprise
|
||||
|
||||
def index
|
||||
require_permission "ReadProducts"
|
||||
|
||||
enterprises = current_user.enterprises.map do |enterprise|
|
||||
EnterpriseBuilder.enterprise(enterprise)
|
||||
end
|
||||
|
||||
36
engines/dfc_provider/app/services/api_user.rb
Normal file
36
engines/dfc_provider/app/services/api_user.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Authorised user or client using the API
|
||||
class ApiUser
|
||||
CLIENT_MAP = {
|
||||
"https://waterlooregionfood.ca/portal/profile" => "cqcm-dev",
|
||||
}.freeze
|
||||
|
||||
def self.from_client_id(client_id)
|
||||
id = CLIENT_MAP[client_id]
|
||||
|
||||
new(id) if id
|
||||
end
|
||||
|
||||
attr_reader :id
|
||||
|
||||
def initialize(id)
|
||||
@id = id
|
||||
end
|
||||
|
||||
def admin?
|
||||
false
|
||||
end
|
||||
|
||||
def customers
|
||||
Customer.none
|
||||
end
|
||||
|
||||
def enterprises
|
||||
Enterprise.where(dfc_permissions: permissions("ReadEnterprise"))
|
||||
end
|
||||
|
||||
def permissions(scope)
|
||||
DfcPermission.where(grantee: id, scope:)
|
||||
end
|
||||
end
|
||||
@@ -1,17 +1,29 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Service used to authorize the user on DCF Provider API
|
||||
# Authorize the user on the DFC API
|
||||
#
|
||||
# It controls an OICD Access token and an enterprise.
|
||||
class AuthorizationControl
|
||||
# Copied from: https://login.lescommuns.org/auth/realms/data-food-consortium/
|
||||
LES_COMMUNES_PUBLIC_KEY = <<~KEY
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl68JGqAILFzoi/1+6siXXp2vylu+7mPjYKjKelTtHFYXWVkbmVptCsamHlY3jRhqSQYe6M1SKfw8D+uXrrWsWficYvpdlV44Vm7uETZOr1/XBOjpWOi1vLmBVtX6jFeqN1BxfE1PxLROAiGn+MeMg90AJKShD2c5RoNv26e20dgPhshRVFPUGru+0T1RoKyIa64z/qcTcTVD2V7KX+ANMweRODdoPAzQFGGjTnL1uUqIdUwSfHSpXYnKxXOsnPC3Mowkv8UIGWWDxS/yzhWc7sOk1NmC7pb+Cg7G8NKj+Pp9qQZnXF39Dg95ZsxJrl6fyPFvTo3zf9CPG/fUM1CkkwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
KEY
|
||||
PUBLIC_KEYS = {
|
||||
# Copied from: https://login.lescommuns.org/auth/realms/data-food-consortium/
|
||||
"https://login.lescommuns.org/auth/realms/data-food-consortium" => <<~KEY,
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl68JGqAILFzoi/1+6siXXp2vylu+7mPjYKjKelTtHFYXWVkbmVptCsamHlY3jRhqSQYe6M1SKfw8D+uXrrWsWficYvpdlV44Vm7uETZOr1/XBOjpWOi1vLmBVtX6jFeqN1BxfE1PxLROAiGn+MeMg90AJKShD2c5RoNv26e20dgPhshRVFPUGru+0T1RoKyIa64z/qcTcTVD2V7KX+ANMweRODdoPAzQFGGjTnL1uUqIdUwSfHSpXYnKxXOsnPC3Mowkv8UIGWWDxS/yzhWc7sOk1NmC7pb+Cg7G8NKj+Pp9qQZnXF39Dg95ZsxJrl6fyPFvTo3zf9CPG/fUM1CkkwIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
KEY
|
||||
|
||||
def self.public_key
|
||||
OpenSSL::PKey::RSA.new(LES_COMMUNES_PUBLIC_KEY)
|
||||
# Copied from: https://kc.cqcm.startinblox.com/realms/startinblox
|
||||
"https://kc.cqcm.startinblox.com/realms/startinblox" => <<~KEY,
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqtvdb3BdHoLnNeMLaWd7nugPwdRAJJpdSySTtttEQY2/v1Q3byJ/kReSNGrUNkPVkOeDN3milgN5Apz+sNCwbtzOCulyFMmvuIOZFBqz5tcgwjZinSwpGBXpn6ehXyCET2LlcfLYAPA9axtaNg9wBLIHoxIPWpa2LcZstogyZY/yKUZXQTDqM5B5TyUkPN89xHFdq8SQuXPasbpYl7mGhZHkTDHiKZ9VK7K5tqsEZTD9dCuTGMKsthbOrlDnc9bAJ3PyKLRdib21Y1GGlTozo4Y/1q448E/DFp5rVC6jG6JFnsEnP0WVn+6qz7yxI7IfUU2YSAGgtGYaQkWtEfED0QIDAQAB
|
||||
-----END PUBLIC KEY-----
|
||||
KEY
|
||||
}.freeze
|
||||
|
||||
def self.public_key(token)
|
||||
unverified_payload = JWT.decode(token, nil, false, { algorithm: "RS256" }).first
|
||||
key = PUBLIC_KEYS[unverified_payload["iss"]]
|
||||
OpenSSL::PKey::RSA.new(key)
|
||||
end
|
||||
|
||||
def initialize(request)
|
||||
@@ -27,7 +39,11 @@ class AuthorizationControl
|
||||
private
|
||||
|
||||
def oidc_user
|
||||
find_ofn_user(decode_token) if access_token
|
||||
return unless access_token
|
||||
|
||||
payload = decode_token
|
||||
|
||||
find_ofn_user(payload) || client_user(payload)
|
||||
end
|
||||
|
||||
def ofn_api_user
|
||||
@@ -41,7 +57,7 @@ class AuthorizationControl
|
||||
def decode_token
|
||||
JWT.decode(
|
||||
access_token,
|
||||
self.class.public_key,
|
||||
self.class.public_key(access_token),
|
||||
true, { algorithm: "RS256" }
|
||||
).first
|
||||
end
|
||||
@@ -59,4 +75,8 @@ class AuthorizationControl
|
||||
|
||||
OidcAccount.find_by(uid: payload["email"])&.user
|
||||
end
|
||||
|
||||
def client_user(payload)
|
||||
ApiUser.from_client_id(payload["client_id"])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
require_relative "../swagger_helper"
|
||||
|
||||
RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
|
||||
let(:Authorization) { nil }
|
||||
let(:user) { create(:oidc_user, id: 12_345) }
|
||||
let(:enterprise) {
|
||||
create(
|
||||
@@ -35,8 +36,15 @@ RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
|
||||
|
||||
get "List CatalogItems" do
|
||||
produces "application/json"
|
||||
security [oidc_token: []]
|
||||
|
||||
response "404", "not found" do
|
||||
context "as platform user" do
|
||||
include_context "authenticated as platform"
|
||||
let(:enterprise_id) { 10_000 }
|
||||
run_test!
|
||||
end
|
||||
|
||||
context "without enterprises" do
|
||||
let(:enterprise_id) { "default" }
|
||||
|
||||
@@ -53,6 +61,25 @@ RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
|
||||
response "200", "success" do
|
||||
before { product }
|
||||
|
||||
context "as platform user" do
|
||||
include_context "authenticated as platform"
|
||||
|
||||
let(:enterprise_id) { 10_000 }
|
||||
|
||||
before {
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id:,
|
||||
scope: "ReadEnterprise", grantee: "cqcm-dev",
|
||||
)
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id:,
|
||||
scope: "ReadProducts", grantee: "cqcm-dev",
|
||||
)
|
||||
}
|
||||
|
||||
run_test!
|
||||
end
|
||||
|
||||
context "with default enterprise id" do
|
||||
let(:enterprise_id) { "default" }
|
||||
|
||||
@@ -75,11 +102,31 @@ RSpec.describe "CatalogItems", swagger_doc: "dfc.yaml" do
|
||||
end
|
||||
|
||||
response "401", "unauthorized" do
|
||||
let(:enterprise_id) { "default" }
|
||||
context "as platform user" do
|
||||
include_context "authenticated as platform"
|
||||
|
||||
before { login_as nil }
|
||||
let(:enterprise_id) { 10_000 }
|
||||
|
||||
run_test!
|
||||
before {
|
||||
product
|
||||
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id:,
|
||||
scope: "ReadEnterprise", grantee: "cqcm-dev",
|
||||
)
|
||||
# But no ReadProducts permission.
|
||||
}
|
||||
|
||||
run_test!
|
||||
end
|
||||
|
||||
context "without authorisation" do
|
||||
let(:enterprise_id) { "default" }
|
||||
|
||||
before { login_as nil }
|
||||
|
||||
run_test!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
require_relative "../swagger_helper"
|
||||
|
||||
RSpec.describe "Enterprises", swagger_doc: "dfc.yaml" do
|
||||
let(:Authorization) { nil }
|
||||
let!(:user) { create(:oidc_user) }
|
||||
let!(:enterprise) do
|
||||
create(
|
||||
@@ -51,6 +52,21 @@ RSpec.describe "Enterprises", swagger_doc: "dfc.yaml" do
|
||||
produces "application/json"
|
||||
|
||||
response "200", "successful" do
|
||||
context "as platform user" do
|
||||
include_context "authenticated as platform"
|
||||
|
||||
let(:id) { 10_000 }
|
||||
|
||||
before {
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id: id,
|
||||
scope: "ReadEnterprise", grantee: "cqcm-dev",
|
||||
)
|
||||
}
|
||||
|
||||
run_test!
|
||||
end
|
||||
|
||||
context "without enterprise id" do
|
||||
let(:id) { "default" }
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ RSpec.describe "ProductGroups", swagger_doc: "dfc.yaml" do
|
||||
variants: [variant]
|
||||
)
|
||||
}
|
||||
let(:Authorization) { nil }
|
||||
let(:variant) {
|
||||
build(:base_variant, id: 10_001, unit_value: 1, primary_taxon: taxon, supplier: enterprise)
|
||||
}
|
||||
@@ -34,10 +35,28 @@ RSpec.describe "ProductGroups", swagger_doc: "dfc.yaml" do
|
||||
|
||||
get "Show ProductGroup" do
|
||||
produces "application/json"
|
||||
security [oidc_token: []]
|
||||
|
||||
response "200", "success" do
|
||||
let(:id) { product.id }
|
||||
|
||||
context "as platform user" do
|
||||
include_context "authenticated as platform"
|
||||
|
||||
before {
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id:,
|
||||
scope: "ReadEnterprise", grantee: "cqcm-dev",
|
||||
)
|
||||
DfcPermission.create!(
|
||||
user:, enterprise_id:,
|
||||
scope: "ReadProducts", grantee: "cqcm-dev",
|
||||
)
|
||||
}
|
||||
|
||||
run_test!
|
||||
end
|
||||
|
||||
run_test! do
|
||||
expect(json_response["@id"]).to eq "http://test.host/api/dfc/product_groups/90000"
|
||||
|
||||
|
||||
13
engines/dfc_provider/spec/services/api_user_spec.rb
Normal file
13
engines/dfc_provider/spec/services/api_user_spec.rb
Normal file
@@ -0,0 +1,13 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../spec_helper"
|
||||
|
||||
RSpec.describe ApiUser do
|
||||
subject(:user) { described_class.new("cqcm-dev") }
|
||||
|
||||
describe "#customers" do
|
||||
it "returns nothing" do
|
||||
expect(user.customers).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -8,6 +8,23 @@ RSpec.describe AuthorizationControl do
|
||||
let(:user) { create(:oidc_user) }
|
||||
|
||||
describe "with OIDC token" do
|
||||
it "accepts a token from Les Communs" do
|
||||
user.oidc_account.update!(uid: "testdfc@protonmail.com")
|
||||
lc_token = file_fixture("les_communs_access_token.jwt").read
|
||||
|
||||
Timecop.travel(Date.parse("2025-06-13")) do
|
||||
expect(auth(oidc_token: lc_token).user).to eq user
|
||||
end
|
||||
end
|
||||
|
||||
it "accepts a token from Startin'Blox" do
|
||||
sib_token = file_fixture("startinblox_access_token.jwt").read
|
||||
|
||||
Timecop.travel(Date.parse("2025-06-13")) do
|
||||
expect(auth(oidc_token: sib_token).user.id).to eq "cqcm-dev"
|
||||
end
|
||||
end
|
||||
|
||||
it "finds the right user" do
|
||||
create(:oidc_user) # another user
|
||||
token = allow_token_for(email: user.email)
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Authenticate via Authoriztion token
|
||||
RSpec.shared_context "authenticated as platform" do
|
||||
let(:Authorization) {
|
||||
"Bearer #{file_fixture('startinblox_access_token.jwt').read}"
|
||||
}
|
||||
|
||||
around do |example|
|
||||
# Once upon a time when the access token hadn't expired yet...
|
||||
Timecop.travel(Date.parse("2025-06-13")) { example.run }
|
||||
end
|
||||
|
||||
# Reset any login via session cookie.
|
||||
before { login_as nil }
|
||||
end
|
||||
@@ -113,7 +113,9 @@ module OpenFoodNetwork
|
||||
end
|
||||
|
||||
def managed_enterprises
|
||||
@managed_enterprises ||= Enterprise.managed_by(@user)
|
||||
return Enterprise.all if admin?
|
||||
|
||||
@user.enterprises
|
||||
end
|
||||
|
||||
def coordinated_order_cycles
|
||||
|
||||
@@ -142,7 +142,7 @@ RSpec.describe Admin::OrderCyclesController do
|
||||
select: {
|
||||
enterprise_fees: 3,
|
||||
enterprise_groups: 1,
|
||||
enterprises: 22,
|
||||
enterprises: 19,
|
||||
exchanges: 7,
|
||||
order_cycles: 6,
|
||||
proxy_orders: 1,
|
||||
|
||||
1
spec/fixtures/files/les_communs_access_token.jwt
vendored
Normal file
1
spec/fixtures/files/les_communs_access_token.jwt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJKVjg1bVRtUmh1MGtSeGNNb0FGUFl5azJMbS1WTExYV25HOG9HbUxNUkowIn0.eyJleHAiOjE3NDk3ODkyMzYsImlhdCI6MTc0OTc4NzQzNiwiYXV0aF90aW1lIjoxNzQ5Nzg3NDMzLCJqdGkiOiJmM2Q2ZGNmMi1lNGMwLTQyNzItODQzNC00NWFhZDczOTllYzUiLCJpc3MiOiJodHRwczovL2xvZ2luLmxlc2NvbW11bnMub3JnL2F1dGgvcmVhbG1zL2RhdGEtZm9vZC1jb25zb3J0aXVtIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6IjVmZjNhZjc4LTk0YTItNGI1Yi04ZGFkLWE3YzFkZWE4ODE2YSIsInR5cCI6IkJlYXJlciIsImF6cCI6ImNvb3BjaXJjdWl0cyIsIm5vbmNlIjoiMTZkNmM3OGZkNTcwOWRkMjVkNzNkYzYwMmViNDBiZGYiLCJzZXNzaW9uX3N0YXRlIjoiYmE4Y2M0ZWYtMDJmMC00ZjVmLWFiMWEtMDUyNGRiNGViNzI5IiwiYWxsb3dlZC1vcmlnaW5zIjpbIiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwgb2ZmbGluZV9hY2Nlc3MiLCJzaWQiOiJiYThjYzRlZi0wMmYwLTRmNWYtYWIxYS0wNTI0ZGI0ZWI3MjkiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiJ0ZXN0IGRmYyIsInByZWZlcnJlZF91c2VybmFtZSI6InRlc3RkZmNAcHJvdG9ubWFpbC5jb20iLCJsb2NhbGUiOiJlbiIsImdpdmVuX25hbWUiOiJ0ZXN0IiwiZmFtaWx5X25hbWUiOiJkZmMiLCJlbWFpbCI6InRlc3RkZmNAcHJvdG9ubWFpbC5jb20ifQ.NTuzVgy8es0GHKqGPmHgVaV8Kzz9uuFAiWgixLubfh8fl2OccFDxccNKyiTczj4wHD4jItdHPIxz-x9ZX2Ao7lwMFLno69KWjAK2eLpA8Fnu4stftlswfHqD0W-wzG0Cx24H6jXZbsM5tm1FYgQYwrlZ-uqwQOabN_cA_cTrwHmMTNVCjwCisScq7Np7r1me-4YEABmTGR362_eJVn2bRppG_7s12yjEAH_mcTyALXqlXNaF0XihDCxjmK8ybJiGy6_QwhEJci6EWqJ-w9H6ckheq94xTM5WpanQ4-ZHEm2TZlq2MOfMBVsknhwnGI0b-GbtSJrs7urWsopQyWSuhw
|
||||
1
spec/fixtures/files/startinblox_access_token.jwt
vendored
Normal file
1
spec/fixtures/files/startinblox_access_token.jwt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJRRlJES1daQ2hzMllQYnRqYl9yQUtwQzNzMFo0T2FCMEtFQ056NnlxWHQ0In0.eyJleHAiOjE3NDk3ODk3MDcsImlhdCI6MTc0OTc4OTQwNywianRpIjoiOWE4ODU4NDAtODhjNy00OTliLWIyOGUtMmE5ZmViM2EyNmU0IiwiaXNzIjoiaHR0cHM6Ly9rYy5jcWNtLnN0YXJ0aW5ibG94LmNvbS9yZWFsbXMvc3RhcnRpbmJsb3giLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiNWZlM2MyNmMtMjczNi00OGE0LWI2Y2YtYTllM2JjZmNkZjAwIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiaHR0cHM6Ly93YXRlcmxvb3JlZ2lvbmZvb2QuY2EvcG9ydGFsL3Byb2ZpbGUiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiIsImRlZmF1bHQtcm9sZXMtc3RhcnRpbmJsb3giXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6IlJlYWRFbnRlcnByaXNlIFJlYWRQcm9kdWN0cyIsImNsaWVudEhvc3QiOiIxNzIuMTguMC4xIiwiY2xpZW50QWRkcmVzcyI6IjE3Mi4xOC4wLjEiLCJjbGllbnRfaWQiOiJodHRwczovL3dhdGVybG9vcmVnaW9uZm9vZC5jYS9wb3J0YWwvcHJvZmlsZSJ9.Ln7wY0_ptRAza7M8w3yXU02TvluH028uaoJ5VHiN9-PnakokzHve7SCuSd1hvVikYAivWFIBRP97vwfpb_DW-d9Afk_XcQqcA0L36ynUIZ69X5uQ2zakEW0kB6pwqd8AL8tlWVUg2PixBXJ6daJcgWNF7RlKXg6wgy4JYL_VxD3VJjST911-z4_TMuQ2OC-3SJNwNv3BspSmUXm7F6y8xGFN7wuCPjU90WIiZ_vxTbVdM0zNtBM0uMJFeFv2_ZzoJIIiNHYLWtD3LrKcXePLSejpo-DPVWR_lGdDdM7BmzOHPKZ9KMaV-oa3lYNYC5shhJOpoB3vHngtdYdv8jq7Cg
|
||||
@@ -137,6 +137,8 @@ paths:
|
||||
type: string
|
||||
get:
|
||||
summary: List CatalogItems
|
||||
security:
|
||||
- oidc_token: []
|
||||
tags:
|
||||
- CatalogItems
|
||||
responses:
|
||||
@@ -578,13 +580,7 @@ paths:
|
||||
"@id": http://test.host/api/dfc/enterprises/10000/platforms
|
||||
dfc-t:platforms:
|
||||
"@type": rdf:List
|
||||
"@list":
|
||||
- "@type": dfc-t:Platform
|
||||
"@id": https://api.proxy-dev.cqcm.startinblox.com/profile
|
||||
localId: cqcm-dev
|
||||
dfc-t:hasAssignedScopes:
|
||||
"@type": rdf:List
|
||||
"@list": []
|
||||
"@list": []
|
||||
"/api/dfc/enterprises/{enterprise_id}/platforms/{platform_id}":
|
||||
parameters:
|
||||
- name: enterprise_id
|
||||
@@ -634,24 +630,18 @@ paths:
|
||||
dfc-t:hasAssignedScopes:
|
||||
"@type": rdf:List
|
||||
"@list":
|
||||
- "@id": https://example.com/scopes/ReadEnterprise
|
||||
- "@id": https://github.com/datafoodconsortium/taxonomies/releases/latest/download/scopes.rdf#ReadEnterprise
|
||||
"@type": dfc-t:Scope
|
||||
dfc-t:scope: ReadEnterprise
|
||||
- "@id": https://example.com/scopes/WriteEnterprise
|
||||
- "@id": https://github.com/datafoodconsortium/taxonomies/releases/latest/download/scopes.rdf#WriteEnterprise
|
||||
"@type": dfc-t:Scope
|
||||
dfc-t:scope: WriteEnterprise
|
||||
- "@id": https://example.com/scopes/ReadProducts
|
||||
- "@id": https://github.com/datafoodconsortium/taxonomies/releases/latest/download/scopes.rdf#ReadProducts
|
||||
"@type": dfc-t:Scope
|
||||
dfc-t:scope: ReadProducts
|
||||
- "@id": https://example.com/scopes/WriteProducts
|
||||
- "@id": https://github.com/datafoodconsortium/taxonomies/releases/latest/download/scopes.rdf#WriteProducts
|
||||
"@type": dfc-t:Scope
|
||||
dfc-t:scope: WriteProducts
|
||||
- "@id": https://example.com/scopes/ReadOrders
|
||||
- "@id": https://github.com/datafoodconsortium/taxonomies/releases/latest/download/scopes.rdf#ReadOrders
|
||||
"@type": dfc-t:Scope
|
||||
dfc-t:scope: ReadOrders
|
||||
- "@id": https://example.com/scopes/WriteOrders
|
||||
- "@id": https://github.com/datafoodconsortium/taxonomies/releases/latest/download/scopes.rdf#WriteOrders
|
||||
"@type": dfc-t:Scope
|
||||
dfc-t:scope: WriteOrders
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
@@ -688,6 +678,8 @@ paths:
|
||||
type: string
|
||||
get:
|
||||
summary: Show ProductGroup
|
||||
security:
|
||||
- oidc_token: []
|
||||
tags:
|
||||
- ProductGroups
|
||||
responses:
|
||||
|
||||
Reference in New Issue
Block a user