XACML JSON Mandatory categories in request - json

I have a doubt with respect to the 4 categories of the JSON Profile of XACML 3.0.
When I send a request in JSON from the PEP to the PDP, does the PEP always need to send AccessSubject, Resource, Action and Enviroment to the PDP or can the PEP send any category in the JSON request?
This is the diagram JSON request.

A JSON request may contain any number of categories including custom categories. This applies to a XACML request whether it be encoded in JSON or XML (I am the editor of this profile and work for the company, Axiomatics, which implements it).
The JSON profile also defines 8 default categories which can be used. These category names are:
urn:oasis:names:tc:xacml:3.0:attribute-category:resource : Resource
urn:oasis:names:tc:xacml:3.0:attribute-category:action : Action
urn:oasis:names:tc:xacml:3.0:attribute-category:environment : Environment
urn:oasis:names:tc:xacml:1.0:subject-category:access-subject : AccessSubject
urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject : RecipientSubject
urn:oasis:names:tc:xacml:1.0:subject-category:intermediary-subject : IntermediarySubject
urn:oasis:names:tc:xacml:1.0:subject-category:codebase : Codebase
urn:oasis:names:tc:xacml:1.0:subject-category:requesting-machine : RequestingMachine
Here is an example which only uses 3 categories and uses their shorthand notation:
{
"Request": {
"AccessSubject": {
"Attribute": [
{"AttributeId": "com.acme.user.employeeId",
"Value": "Alice"}
]},
"Resource": {
"Attribute": [
{"AttributeId": "com.acme.record.recordId",
"Value": "123"},
{"AttributeId": "com.acme.object.objectType",
"Value": "record"}
]},
"Action": {
"Attribute": [
{"AttributeId": "com.acme.action.actionId",
"Value": "view"}
]}
}
}

Related

FIWARE, NGSI-LD - Understand the #context

I am creating a data model for a particular application and I did not start from any base model; since I did not start from any base model, the context below is sufficient, correct?
"#context": [
"https://schema.lab.fiware.org/ld/context",
"https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.3.jsonld"
]
My data model is not complicated, with just these properties and entity being more "complex":
"address": {
"type": "Property",
"value": {
"streetAddress": "",
"postalCode": "",
"addressLocality": "",
"addressCountry": ""
}
},
"location": {
"type": "Point",
"coordinates": [
,
]
},
{
"id": "urn:ngsi-ld:MeasurementSensor:",
"type": "MeasurementSensor",
"measurementVariable": {
"type": "Property",
"value": "Temperature"
},
"measurementValue": {
"type": "Property",
"value": 32.0,
"unitCode": "ÂșC",
"observedAt": "2022-05-10T11:09:00.000Z"
},
"refX": {
"type": "Relationship",
"object": "urn:ngsi-ld:"
},
"#context": [
"https://schema.lab.fiware.org/ld/context",
"https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.3.jsonld"
]
}
If you are using your own custom vocabulary you should declare your types and properties in your own LD #context. For instance,
{
"#context": [
{
"MeasurementSensor": "https://example.org/my-types/MesaurementSensor"
},
"https://schema.lab.fiware.org/ld/context",
"https://uri.etsi.org/ngsi-ld/v1/ngsi-ld-core-context-v1.3.jsonld"
]
}
it also seems you are not using URNs properly, you should check. unitCode seems to be broken as well, as it must follow the UN/CEFACT unit codes.
Nonetheless, I would not recommend to define your own vocabulary for sensors, given there are existing Vocabularies such as SAREF or W3C SOSA that can and should be reused.
I'm not a data model expert but I do know a thing or two about NGSI-LD and NGSI-LD brokers.
The #context you use is an array of "https://schema.lab.fiware.org/ld/context" and v1.3 of the core context.
"https://schema.lab.fiware.org/ld/context" in its turn is an array of "https://fiware.github.io/data-models/context.jsonld" and v1.1 of the core context ...
And, ""https://fiware.github.io/data-models/context.jsonld" doesn't define any of the three terms you are using, so, no need to give any context for that. The terms will be expanded using the default URL of the core context (the value of the #vocab member of the core context defines the default URL).
An NGSI-LD broker has the core context built-in, you don't need to pass it, so do yourself a favor, and get faster responses by not passing the core context to the broker. No need.
And, if you need a user context, pass it in the HTTP Header "Link" instead.
Host it somewhere (an NGSi-LD broker offers that service), so you don't force the poor broker to parse the #conterxt in each and every request.
Lastly, do follow Jose Manuels recommendations and use standard names for your attributes (and value for unitCode).

FIWARE - Orion Context Broker as Context Provider

I'm having a hard time understanding how context providers work in the Orion Context Broker.
I followed the examples in the step-by-step guide written by Jason Fox. However, I still do not exactly get what happens in the background and how the context broker exactly creates the POST from the registration. Here is what I am trying to do:
I do have a WeatherStation that provides sensor data for a neighborhood.
{
"id": "urn:ngsi-ld:WeatherStation:001",
"type": "Device:WeatherStation",
"temperature": {
"type": "Number",
"value": 20.5,
"metadata": {}
},
"windspeed": {
"type": "Number",
"value": 60.0,
"metadata": {}
}
}
Now I like the WeatherStation to be a context provider for all buildings.
{
"id": "urn:ngsi-ld:building:001",
"type": "Building"
}
Here is the registration that I try to use.
{
"id": null,
"description": "Random Weather Conditions",
"provider": {
"http": {
"url": "http://localhost:1026/v2"
},
"supportedForwardingMode": "all"
},
"dataProvided": {
"entities": [
{
"id": "null",
"idPattern": ".*",
"type": "Building",
"typePattern": null
}
],
"attrs": [
"temperature",
"windspeed"
],
"expression": null
},
"status": "active",
"expires": null,
"forwardingInformation": null
}
The context broker accepts both entities and the registration without any error.
Since I have a multi-tenant setup I use one fiware_service for the complete neighborhood but every building would later have a seperate fiware_servicepath. Hence, the weatherstation has a different servicepath than the building. Although I also tried to put them both on the same path.
For now I used the same headers for all entities.
{
"fiware-service": "filip",
"fiware-servicepath": "/testing"
}
Here is the log of the context broker (version: 3.1.0):
INFO#2021-09-23T19:17:17.944Z logTracing.cpp[212]: Request forwarded (regId: 614cd2b511c25270060d873a): POST http://localhost:1026/v2/op/query, request payload (87 bytes): {"entities":[{"idPattern":".*","type":"Building"}],"attrs":["temperature","windspeed"]}, response payload (2 bytes): [], response code: 200
INFO#2021-09-23T19:17:17.944Z logTracing.cpp[130]: Request received: POST /v2/op/query?options=normalized%2Ccount&limit=1000, request payload (55 bytes): {"entities": [{"idPattern": ".*", "type": "Building"}]}, response code: 200
The log says that it receives the request and forwards it as expected. However, as I understand it this would simply point to the same building entity again. Hence, it is somehow a circular forwarding. I also cannot tell anything about the headers of the request.
I do not understand how the forwarded request from the building can actually query the weather station for information. When I query my building I still only receive the entity with no own properties:
{
"id": "urn:ngsi-ld:building:001",
"type": "Building"
}
I also tried to vary the url of the registration but with no success.
Is this scenario actually possible with the current implementation? It would be very useful
Is there any example for this including also the headers?
I know that I could simply use reference but that would put more work on the user.
Thanks for any help on this.
It is messy, but you could achieve this via a subscription. Hold the weather station as a separate entity in the context broker and poll or push updates into the entity. The subscription would fire whenever the data changes and make two NGSI requests:
Find all entities which have a Relationship servicedBy=WeatherStationX
Run an upsert on all entities to add a Property to each entity:
{
"temperature" : {
"type" : "Property",
"value" : 7,
"unitCode": "CEL",
"observedAt": "XXXXX",
"providedBy": "WeatherStation1"
}
}
Where observedAt comes either from the payload of the weather station or the notification timestamp.
Within the existing IoT Agents, provisioning the link attribute allows a device to propagate measures to a second entity (e.g. this Thermometer entity is measuring temperature for an associated Building entity)
{
"entity_type": "Device",
"resource": "/iot/d",
"protocol": "PDI-IoTA-UltraLight",
..etc
"attributes": [
{"object_id": "l", "name": "temperature", "type":"Float",
"metadata":{
"unitCode":{"type": "Text", "value" :"CEL"}
}
}
],
"static_attributes": [
{
"name": "controlledAsset",
"type": "Relationship",
"value": "urn:ngsi-ld:Building:001",
"link": {
"attributes": ["temperature"],
"name": "providedBy",
"type": "Building"
}
}
]
}
At the moment the logic just links direct one-to-one, but it would be possible to raise a PR to check for an Array and update multiple entities in an upsert - the relevant section of code is here

How to send structured data to a REST endpoint that retrieves objects? Which HTTP verb should be used?

I want to construct a REST endpoint to retrieve objects, but I need to send structured data as query parameters (e.g. a list). I was wondering if those data could be sent as request body (see example below). How should I handle this in order to stick to REST good practices? Which HTTP verb should I use?
URI:
http://localhost:8080/products
Request Body:
{
"name" : "Computer",
"categories" : [
{
"id" : 1
},
{
"id" : 4
}
]
}
Response:
[
{
"id": 2,
"name": "Computer XP 2040",
"price": 800
},
{
"id": 1,
"name": "HP Computer",
"price": 2000
},
{
"id": 7,
"name": "Smart Computer",
"price": 1200
}
]
POST is not correct for this. If you want to stick to RESTful best practices, you must encode the information in the uri.
Note that POST might be better if you don't want to do this, but since this question was about REST best practices (and not http services in general), POST is your go-to.
I would simply encode this as:
GET /products?name=Computer&categories=1,4

How to convert Json (from JIRA's webhook) to Custom Java object

I have some Java REST APIs which will be invoked via JIRA Webhook configuration.
Now, when JIRA webhook is invoking REST API, there are large no. of custom fields (like customfield_17270) which contain useful data.
For example, I have configured "Create Issue" event in JIRA webhook i.e. whenever any issue will be created in JIRA, my REST API will be invoked. While creating issue in JIRA, for example, there is a field named "Issue Title" whose value is "XXX". In JSON payload, ideally key-value pair should be "Issue Title":"XXX" but it is like "Custom_Field109":"XXX".
Now the problem is how to map this dynamic JSON to Java Object.
Is there anyone who has faced similar problem.
Each time you receive the webhook, you'll need to map each custom id (e.g. customfield_10070) to it's name by querying the field JIRA REST API at GET: /rest/api/2/field
...which will give you something like this:
[
{
"id": "issuetype",
"name": "Issue Type",
"custom": false,
"orderable": true,
"navigable": true,
"searchable": true,
"clauseNames": [
"issuetype",
"type"
],
"schema": {
"type": "issuetype",
"system": "issuetype"
}
},
{
"id": "customfield_10070",
"name": "FAQ Necessary?",
"custom": true,
"orderable": true,
"navigable": true,
"searchable": true,
"clauseNames": [
"cf[10070]",
"FAQ Necessary?"
],
"schema": {
"type": "string",
"custom": "com.atlassian.jira.plugin.system.customfieldtypes:radiobuttons",
"customId": 10070
}
},
...
]
You should then easily be able to iterate over the fields from the webhook JSON and map the custom field id to its display name.
I was able to discuss this issue with JIRA internal team and they provided me custom fields mapping to their JIRA display name.
Basically, when we receive Json keys like Custom_field109 then it means 109 is internal database id for this attribute.
Now, based on given mapping, I parsed JSON to get required keys and then through Jackson library, I was able to map JSOn to Java.

vimeo-api remove part of JSON response

Is possible (sending a specific parameter in request) remove part of JSON response?
Like the Youtube API v3 part parameter: The part parameter specifies a comma-separated list of one or more video resource properties that the API response will include.
Thanks,
The Vimeo API supports a fields whitelist, so instead of saying "exclude this", you include a list of everything you want.
There is more documentation here: https://developer.vimeo.com/api/spec#json-filter
But the idea is you add the parameter fields, and a comma separated list of fields. Nested data should be broken up with periods. So the following representation
{
"name": "dashron",
"websites": [{
"name": "facebook"
},{
"name": "twitter"
}],
"metadata": {
"albums": {
"uri": "...",
"options": "...",
"total": "..."
}
}
Is the result of an API call with the following fields parameter
fields=name,websites.name,metadata.albums