diff --git a/app/views/admin/enterprises/form/_dfc_permissions.html.haml b/app/views/admin/enterprises/form/_dfc_permissions.html.haml index 6521ad003d..5592badf68 100644 --- a/app/views/admin/enterprises/form/_dfc_permissions.html.haml +++ b/app/views/admin/enterprises/form/_dfc_permissions.html.haml @@ -20,7 +20,6 @@ :plain { id: "https://api.proxy-dev.cqcm.startinblox.com/profile", + webhook: "/djangoldp-dfc/webhook/", tokens: "https://kc.cqcm.startinblox.com/realms/startinblox/protocol/openid-connect/token", }, 'cqcm-stg' => { id: "https://api.proxy-stg.cqcm.startinblox.com/profile", + webhook: "/djangoldp-dfc/webhook/", tokens: "https://kc.cqcm.startinblox.com/realms/startinblox/protocol/openid-connect/token", }, 'cqcm' => { id: "https://carte.cqcm.coop/profile", + webhook: "/djangoldp-dfc/webhook/", tokens: "https://authentification.cqcm.coop/realms/cqcm/protocol/openid-connect/token", }, 'lf-dev' => { id: "https://www.litefarm.org/profile", + webhook: "/djangoldp-dfc/webhook/", tokens: "https://login.fooddatacollaboration.org.uk/realms/dev/protocol/openid-connect/token", }, 'mo-dev' => { id: "https://market.organic/profile", + webhook: "/api/webhooks/ofn", tokens: "https://login.fooddatacollaboration.org.uk/realms/dev/protocol/openid-connect/token", }, @@ -31,6 +36,14 @@ class ApiUser PLATFORMS.dig(platform, :id) end + def self.webhook_url(platform) + platform_url = ApiUser.platform_url(platform) + + URI.parse(platform_url).tap do |url| + url.path = PLATFORMS.dig(platform, :webhook) + end + end + def self.token_endpoint(platform) PLATFORMS.dig(platform, :tokens) end diff --git a/engines/dfc_provider/app/services/proxy_notifier.rb b/engines/dfc_provider/app/services/proxy_notifier.rb index 908398f897..55092dc32f 100644 --- a/engines/dfc_provider/app/services/proxy_notifier.rb +++ b/engines/dfc_provider/app/services/proxy_notifier.rb @@ -25,7 +25,7 @@ class ProxyNotifier grant_type: "client_credentials", client_id: ENV.fetch("OPENID_APP_ID", nil), client_secret: ENV.fetch("OPENID_APP_SECRET", nil), - scope: "WriteEnterprise", + scope: "ReadEnterprise", } response = connection.post(url, data) response.body["access_token"] @@ -49,13 +49,6 @@ class ProxyNotifier f.response :json f.response :raise_error end - connection.post(webhook_url(platform), data) - end - - def webhook_url(platform) - platform_url = ApiUser.platform_url(platform) - URI.parse(platform_url).tap do |url| - url.path = "/djangoldp-dfc/webhook/" - end + connection.post(ApiUser.webhook_url(platform), data) end end diff --git a/engines/dfc_provider/spec/services/proxy_notifier_spec.rb b/engines/dfc_provider/spec/services/proxy_notifier_spec.rb index f3a8b0e5ba..aa86b8de2a 100644 --- a/engines/dfc_provider/spec/services/proxy_notifier_spec.rb +++ b/engines/dfc_provider/spec/services/proxy_notifier_spec.rb @@ -25,4 +25,9 @@ RSpec.describe ProxyNotifier do subject.refresh(platform, enterprise_url) }.to raise_error Faraday::ServerError end + + # Requires OIDC client secret for FDC dev realm. + it "notifies Market Organic", :vcr do + subject.refresh("mo-dev", enterprise_url) + end end diff --git a/lib/open_food_network/feature_toggle.rb b/lib/open_food_network/feature_toggle.rb index 3c5b5ed9d0..56b000372a 100644 --- a/lib/open_food_network/feature_toggle.rb +++ b/lib/open_food_network/feature_toggle.rb @@ -70,6 +70,9 @@ module OpenFoodNetwork "cqcm" => <<~DESC, Show DFC Permissions interface to share data with CQCM. DESC + "mo-dev" => <<~DESC, + Show DFC Permissions interface to share data with Market.Organic. + DESC }.merge(conditional_features).freeze; # Features you would like to be enabled to start with. diff --git a/spec/fixtures/vcr_cassettes/ProxyNotifier/notifies_Market_Organic.yml b/spec/fixtures/vcr_cassettes/ProxyNotifier/notifies_Market_Organic.yml new file mode 100644 index 0000000000..32896f5406 --- /dev/null +++ b/spec/fixtures/vcr_cassettes/ProxyNotifier/notifies_Market_Organic.yml @@ -0,0 +1,94 @@ +--- +http_interactions: +- request: + method: post + uri: https://login.fooddatacollaboration.org.uk/realms/dev/protocol/openid-connect/token + body: + encoding: UTF-8 + string: client_id=&client_secret=&grant_type=client_credentials&scope=ReadEnterprise + headers: + User-Agent: + - Faraday v2.9.0 + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Cache-Control: + - no-store + Content-Length: + - '1588' + Content-Type: + - application/json + Pragma: + - no-cache + Referrer-Policy: + - no-referrer + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - SAMEORIGIN + Date: + - Fri, 21 Nov 2025 03:06:09 GMT + body: + encoding: UTF-8 + string: '{"access_token":"","expires_in":300,"refresh_expires_in":0,"token_type":"Bearer","not-before-policy":0,"scope":"ReadEnterprise + profile email"}' + recorded_at: Fri, 21 Nov 2025 03:06:09 GMT +- request: + method: post + uri: https://market.organic/api/webhooks/ofn + body: + encoding: UTF-8 + string: '{"eventType":"refresh","enterpriseUrlid":"http://ofn.example.net/api/dfc/enterprises/10000","scope":"ReadEnterprise"}' + headers: + Authorization: + - "" + User-Agent: + - Faraday v2.9.0 + Content-Type: + - application/json + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx/1.29.1 + Date: + - Fri, 21 Nov 2025 03:06:10 GMT + Content-Type: + - application/json; charset=utf-8 + Content-Length: + - '95' + Connection: + - keep-alive + X-Powered-By: + - Express + Access-Control-Allow-Origin: + - "*" + Access-Control-Allow-Methods: + - GET, POST, OPTIONS, HEAD + Access-Control-Allow-Headers: + - Content-Type, Authorization, Cache-Control, Accept, Accept-Language + Access-Control-Expose-Headers: + - Content-Type, Content-Length + Etag: + - W/"5f-ip4J0TL+XJqsW6UbwFDqOBqtUAQ" + body: + encoding: UTF-8 + string: '{"success":true,"message":"Webhook received and stored","timestamp":"2025-11-21T03:06:10.659Z"}' + recorded_at: Fri, 21 Nov 2025 03:06:10 GMT +recorded_with: VCR 6.2.0