Update and list scopes for real

This commit is contained in:
Maikel Linke
2025-06-12 16:33:53 +10:00
parent 7032b3f463
commit 52aeec5ac4
5 changed files with 202 additions and 65 deletions

View File

@@ -19,7 +19,7 @@
:plain
<solid-permissioning
data-src="#{DfcProvider::Engine.routes.url_helpers.enterprise_platforms_path(@enterprise.id)}"
data-src="#{DfcProvider::Engine.routes.url_helpers.enterprise_platforms_url(@enterprise.id)}"
scopes-uri="https://cdn.startinblox.com/owl/dfc/taxonomies/scopes.jsonld"
noRouter>
</solid-permissioning>

View File

@@ -2,6 +2,12 @@
module DfcProvider
class PlatformsController < DfcProvider::ApplicationController
# List of platform identifiers.
# local ID => semantic ID
PLATFORM_IDS = {
'cqcm-dev' => "https://api.proxy-dev.cqcm.startinblox.com/profile",
}.freeze
# DANGER!
# This endpoint is open to CSRF attacks.
# This is a temporary measure until the DFC Permissions module accesses
@@ -11,15 +17,86 @@ module DfcProvider
before_action :check_enterprise
def index
render json: <<~JSON
{"@context":"https://cdn.startinblox.com/owl/context-bis.jsonld","@id":"https://mydataserver.com/enterprises/1/platforms","dfc-t:platforms":{"@list":[{"@id":"https://waterlooregionfood.ca/portal/profile","@type":"dfc-t:Platform","_id":{"$oid":"682afcc4966dbb3aa7464d56"},"description":"A super duper portal for the waterloo region","dfc-t:hasAssignedScopes":{"@list":[{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadEnterprise","@type":"dfc-t:Scope","dfc-t:scope":"ReadEnterprise"},{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteEnterprise","@type":"dfc-t:Scope","dfc-t:scope":"WriteEnterprise"},{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadProducts","@type":"dfc-t:Scope","dfc-t:scope":"ReadProducts"},{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteProducts","@type":"dfc-t:Scope","dfc-t:scope":"WriteProducts"},{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadOrders","@type":"dfc-t:Scope","dfc-t:scope":"ReadOrders"},{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteOrders","@type":"dfc-t:Scope","dfc-t:scope":"WriteOrders"}],"@type":"rdf:List"},"termsandconditions":"https://waterlooregionfood.ca/terms-and-conditions","title":"Waterloo Region Food Portal"},{"@id":"https://anotherplatform.ca/portal/profile","@type":"dfc-t:Platform","_id":{"$oid":"682b2e2b031c28f69cda1645"},"description":"A super duper portal for the waterloo region","dfc-t:hasAssignedScopes":{"@list":[],"@type":"rdf:List"},"termsandconditions":"https://anotherplatform.ca/terms-and-conditions","title":"anotherplatform Portal"}],"@type":"rdf:List"}}
JSON
render json: platforms
end
def show
render json: platform(params[:id])
end
def update
render json: <<~JSON
{"@id":"https://anotherplatform.ca/portal/profile","@type":"dfc-t:Platform","description":"A super duper portal for the waterloo region","dfc-t:hasAssignedScopes":{"@list":[{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadEnterprise","@type":"dfc-t:Scope","dfc-t:scope":"ReadEnterprise"},{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteEnterprise","@type":"dfc-t:Scope","dfc-t:scope":"WriteEnterprise"},{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadProducts","@type":"dfc-t:Scope","dfc-t:scope":"ReadProducts"},{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteProducts","@type":"dfc-t:Scope","dfc-t:scope":"WriteProducts"},{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadOrders","@type":"dfc-t:Scope","dfc-t:scope":"ReadOrders"},{"@id":"https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteOrders","@type":"dfc-t:Scope","dfc-t:scope":"WriteOrders"}],"@type":"rdf:List"},"termsandconditions":"https://anotherplatform.ca/terms-and-conditions","title":"anotherplatform Portal"}
JSON
key = params[:id]
requested_platform = JSON.parse(request.body.read)
requested_scopes = requested_platform
.dig("dfc-t:hasAssignedScopes", "@list")
.pluck("@id")
.map { |uri| uri[/[a-zA-Z]+$/] } # return last part like ReadEnterprise
current_scopes = granted_scopes(key)
scopes_to_delete = current_scopes - requested_scopes
scopes_to_create = requested_scopes - current_scopes
DfcPermission.where(
user: current_user,
enterprise: current_enterprise,
scope: scopes_to_delete,
grantee: key,
).delete_all
scopes_to_create.each do |scope|
DfcPermission.create!(
user: current_user,
enterprise: current_enterprise,
scope:,
grantee: key,
)
end
render json: platform(key)
end
private
def platforms
id = DfcProvider::Engine.routes.url_helpers.enterprise_platforms_url(current_enterprise.id)
platforms = PLATFORM_IDS.keys.map(&method(:platform))
{
'@context': "https://cdn.startinblox.com/owl/context-bis.jsonld",
'@id': id,
'dfc-t:platforms': {
'@type': "rdf:List",
'@list': platforms,
}
}
end
def platform(key)
{
'@type': "dfc-t:Platform",
'@id': PLATFORM_IDS[key],
localId: key,
'dfc-t:hasAssignedScopes': {
'@type': "rdf:List",
'@list': scopes(key),
}
}
end
def scopes(platform_id)
granted_scopes(platform_id).map do |scope|
{
'@id': "https://example.com/scopes/#{scope}",
'@type': "dfc-t:Scope",
'dfc-t:scope': scope,
}
end
end
def granted_scopes(platform_id)
DfcPermission.where(
user: current_user,
enterprise: current_enterprise,
grantee: platform_id,
).pluck(:scope)
end
end
end

View File

@@ -5,7 +5,7 @@ DfcProvider::Engine.routes.draw do
resources :enterprises, only: [:show] do
resources :catalog_items, only: [:index, :show, :update]
resources :offers, only: [:show, :update]
resources :platforms, only: [:index, :update]
resources :platforms, only: [:index, :show, :update]
resources :supplied_products, only: [:create, :show, :update]
resources :social_medias, only: [:show]
end

View File

@@ -23,7 +23,7 @@ RSpec.describe "Platforms", swagger_doc: "dfc.yaml" do
let(:enterprise_id) { enterprise.id }
run_test! do
expect(json_response["@id"]).to eq "https://mydataserver.com/enterprises/1/platforms"
expect(json_response["@id"]).to eq "http://test.host/api/dfc/enterprises/10000/platforms"
end
end
end
@@ -33,15 +33,68 @@ RSpec.describe "Platforms", swagger_doc: "dfc.yaml" do
parameter name: :enterprise_id, in: :path, type: :string
parameter name: :platform_id, in: :path, type: :string
put "Update authorized scopes of a platform" do
get "Show platform scopes" do
produces "application/json"
response "200", "successful" do
let(:enterprise_id) { enterprise.id }
let(:platform_id) { "682b2e2b031c28f69cda1645" }
let(:platform_id) { "cqcm-dev" }
run_test! do
expect(json_response["@id"]).to eq "https://anotherplatform.ca/portal/profile"
expect(json_response["@id"]).to eq "https://api.proxy-dev.cqcm.startinblox.com/profile"
end
end
end
put "Update authorized scopes of a platform" do
consumes "application/json"
produces "application/json"
parameter name: :platform, in: :body, schema: {
example: {
'@context': "https://cdn.startinblox.com/owl/context-bis.jsonld",
'@id': "http://localhost:3000/api/dfc/enterprises/3/platforms/cqcm-dev",
'dfc-t:hasAssignedScopes': {
'@list': [
{
'@id': "https://example.com/scopes/ReadEnterprise",
'@type': "dfc-t:Scope"
},
{
'@id': "https://example.com/scopes/WriteEnterprise",
'@type': "dfc-t:Scope"
},
{
'@id': "https://example.com/scopes/ReadProducts",
'@type': "dfc-t:Scope"
},
{
'@id': "https://example.com/scopes/WriteProducts",
'@type': "dfc-t:Scope"
},
{
'@id': "https://example.com/scopes/ReadOrders",
'@type': "dfc-t:Scope"
},
{
'@id': "https://example.com/scopes/WriteOrders",
'@type': "dfc-t:Scope"
}
],
'@type': "rdf:List"
}
}
}
response "200", "successful" do
let(:enterprise_id) { enterprise.id }
let(:platform_id) { "cqcm-dev" }
let(:platform) do |example|
example.metadata[:operation][:parameters].first[:schema][:example]
end
run_test! do
expect(json_response["@id"]).to eq "https://api.proxy-dev.cqcm.startinblox.com/profile"
end
end
end

View File

@@ -578,48 +578,16 @@ paths:
test_example:
value:
"@context": https://cdn.startinblox.com/owl/context-bis.jsonld
"@id": https://mydataserver.com/enterprises/1/platforms
"@id": http://test.host/api/dfc/enterprises/10000/platforms
dfc-t:platforms:
"@list":
- "@id": https://waterlooregionfood.ca/portal/profile
"@type": dfc-t:Platform
_id:
"$oid": 682afcc4966dbb3aa7464d56
description: A super duper portal for the waterloo region
dfc-t:hasAssignedScopes:
"@list":
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadEnterprise
"@type": dfc-t:Scope
dfc-t:scope: ReadEnterprise
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteEnterprise
"@type": dfc-t:Scope
dfc-t:scope: WriteEnterprise
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadProducts
"@type": dfc-t:Scope
dfc-t:scope: ReadProducts
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteProducts
"@type": dfc-t:Scope
dfc-t:scope: WriteProducts
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadOrders
"@type": dfc-t:Scope
dfc-t:scope: ReadOrders
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteOrders
"@type": dfc-t:Scope
dfc-t:scope: WriteOrders
"@type": rdf:List
termsandconditions: https://waterlooregionfood.ca/terms-and-conditions
title: Waterloo Region Food Portal
- "@id": https://anotherplatform.ca/portal/profile
"@type": dfc-t:Platform
_id:
"$oid": 682b2e2b031c28f69cda1645
description: A super duper portal for the waterloo region
dfc-t:hasAssignedScopes:
"@list": []
"@type": rdf:List
termsandconditions: https://anotherplatform.ca/terms-and-conditions
title: anotherplatform Portal
"@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": []
"/api/dfc/enterprises/{enterprise_id}/platforms/{platform_id}":
parameters:
- name: enterprise_id
@@ -632,8 +600,8 @@ paths:
required: true
schema:
type: string
put:
summary: Update authorized scopes of a platform
get:
summary: Show platform scopes
tags:
- Platforms
responses:
@@ -644,32 +612,71 @@ paths:
examples:
test_example:
value:
"@id": https://anotherplatform.ca/portal/profile
"@type": dfc-t:Platform
description: A super duper portal for the waterloo region
"@id": https://api.proxy-dev.cqcm.startinblox.com/profile
localId: cqcm-dev
dfc-t:hasAssignedScopes:
"@type": rdf:List
"@list": []
put:
summary: Update authorized scopes of a platform
parameters: []
tags:
- Platforms
responses:
'200':
description: successful
content:
application/json:
examples:
test_example:
value:
"@type": dfc-t:Platform
"@id": https://api.proxy-dev.cqcm.startinblox.com/profile
localId: cqcm-dev
dfc-t:hasAssignedScopes:
"@type": rdf:List
"@list":
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadEnterprise
- "@id": https://example.com/scopes/ReadEnterprise
"@type": dfc-t:Scope
dfc-t:scope: ReadEnterprise
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteEnterprise
- "@id": https://example.com/scopes/WriteEnterprise
"@type": dfc-t:Scope
dfc-t:scope: WriteEnterprise
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadProducts
- "@id": https://example.com/scopes/ReadProducts
"@type": dfc-t:Scope
dfc-t:scope: ReadProducts
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteProducts
- "@id": https://example.com/scopes/WriteProducts
"@type": dfc-t:Scope
dfc-t:scope: WriteProducts
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/ReadOrders
- "@id": https://example.com/scopes/ReadOrders
"@type": dfc-t:Scope
dfc-t:scope: ReadOrders
- "@id": https://data-server.cqcm.startinblox.com/enterprises/1/platforms/scopes/WriteOrders
- "@id": https://example.com/scopes/WriteOrders
"@type": dfc-t:Scope
dfc-t:scope: WriteOrders
"@type": rdf:List
termsandconditions: https://anotherplatform.ca/terms-and-conditions
title: anotherplatform Portal
requestBody:
content:
application/json:
schema:
example:
"@context": https://cdn.startinblox.com/owl/context-bis.jsonld
"@id": http://localhost:3000/api/dfc/enterprises/3/platforms/cqcm-dev
dfc-t:hasAssignedScopes:
"@list":
- "@id": https://example.com/scopes/ReadEnterprise
"@type": dfc-t:Scope
- "@id": https://example.com/scopes/WriteEnterprise
"@type": dfc-t:Scope
- "@id": https://example.com/scopes/ReadProducts
"@type": dfc-t:Scope
- "@id": https://example.com/scopes/WriteProducts
"@type": dfc-t:Scope
- "@id": https://example.com/scopes/ReadOrders
"@type": dfc-t:Scope
- "@id": https://example.com/scopes/WriteOrders
"@type": dfc-t:Scope
"@type": rdf:List
"/api/dfc/product_groups/{id}":
parameters:
- name: enterprise_id