Skip to content
Okke Harsta edited this page Sep 22, 2017 · 35 revisions

Manage API's

Manage has two API's:

  • Client API for the Manage JavaScript GUI application which is secured using federative authentication (using shibboleth)
  • Internal READ / WRITE API for other applications secured by basic authentication and scopes (using ansible)

Client API

The first API is self-explaining and only interesting for Manage developers.

READ API

The read API is very simple. It has one endpoint and you can specify which fields you want to fetch with the REQUESTED_ATTRIBUTES key and optionally which fields to search. Example:

curl -H 'Content-Type: application/json' -u pdp:secret  -X POST -d \
'{"metaDataFields.AssertionConsumerService:0:Location":".*","metaDataFields.coin:policy_enforcement_decision_required":"1","REQUESTED_ATTRIBUTES":["metaDataFields.AssertionConsumerService:0:Location","metaDataFields.coin:policy_enforcement_decision_required"]}' \
'http://localhost:8080/manage/api/internal/search/saml20_sp'

Or against a deployed application on a test environment:

curl -H 'Content-Type: application/json' -u pdp:secret  -X POST -d '{"metaDataFields.AssertionConsumerService:0:Location":".*","REQUESTED_ATTRIBUTES":["entityid"]}' 'https://manage.test2.surfconext.nl/manage/api/internal/search/saml20_sp'

The query will AND the different inputs. Wildcards like .*surf.* are translated to a regular expression search. Specify booleans with 0 or 1 and leave the value empty for a does not exists query. The result will always - depending on the type of Metadata specified as a path variable - return some defaults fields. For SP / IdP Metadata the default fields are:

  • entityid
  • state
  • metaDataFields.name:en
  • metaDataFields.name:nl

The following example will return the default fields and the ARP for the SP with the specified entityid:

curl -H 'Content-Type: application/json' -u pdp:secret  -X POST -d \
'{"entityid":"https://dmsonline.uvt.nl/nl/home","REQUESTED_ATTRIBUTES":["arp"]}' \
'http://localhost:8080/manage/api/internal/search/saml20_sp'

And will return the following JSON:

[{
	"_id": "362c928f-e80c-4318-a04e-c7dc072c131c",
	"data": {
		"entityid": "https://dmsonline.uvt.nl/nl/home",
		"state": "testaccepted",
		"arp": {
			"attributes": {
				"urn:mace:dir:attribute-def:displayName": [{
					"source": "idp",
					"value": "*"
				}],
				"urn:mace:dir:attribute-def:eduPersonAffiliation": [{
					"source": "idp",
					"value": "*"
				}],
				"urn:mace:dir:attribute-def:cn": [{
					"source": "idp",
					"value": "*"
				}],
				"urn:mace:dir:attribute-def:eduPersonPrincipalName": [{
					"source": "idp",
					"value": "*"
				}],
				"urn:mace:dir:attribute-def:mail": [{
					"source": "idp",
					"value": "*"
				}],
				"urn:mace:terena.org:attribute-def:schacHomeOrganization": [{
					"source": "idp",
					"value": "*"
				}]
			},
			"enabled": true
		},
		"metaDataFields": {
			"name:en": "DMS | Delcomkje",
			"name:nl": "DMS | Delcomkje"
		}
	}
}]

WRITE API

The Write API is based on a merge principle. You specify the exact path of the values and the actually new values of the fields you want to update. The following example adds an IdP to the array of allowedEntities of the specified SP, sets the top-level attribute allowedall to false and finally updates or adds the metadata field description:en. Note that the id of the Metadata you want to update must already be retrieved by a search query:

curl -H 'Content-Type: application/json' -u sp-portal:secret \
-X PUT -d '{"id": "bac56ecd-29aa-449f-81ff-109cff1f90c4", "type": "saml20_sp","pathUpdates": { "allowedall": false, "allowedEntities": [{ "name": "https://allow-me" }], "metaDataFields.description:en": "New description" }}' \
'http://localhost:8080/manage/api/internal/metadata'

The entire updated document is send back in response to the update:

{
	"id": "fa4fd71d-b9d1-4da7-95c2-3be6bbeaf1f0",
	"version": 9,
	"type": "saml20_sp",
	"revision": {
		"number": 22,
		"created": 1504195745.015000000,
		"parentId": null,
		"updatedBy": "sp-portal"
	},
	"data": {
		"id": 281,
		"eid": 1,
		"entityid": "https://engine.test.surfconext.nl/authentication/sp/metadata",
		"revisionid": 13,
		"state": "prodaccepted",
		"type": "saml20-sp",
		"metadataurl": "https://metatdataurl",
		"allowedall": false,
		"manipulation": null,
		"user": "urn:collab:person:example.com:admin",
		"created": "2015-12-16T17:11:17+01:00",
		"ip": "145.100.191.122",
		"revisionnote": "No revision note",
		"active": true,
		"arp": {
			"attributes": {},
			"enabled": false
		},
		"notes": null,
		"metaDataFields": {
			"displayName:nl": "OpenConext Engine",
			"NameIDFormats:0": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
			"url:en": "https://engine.test.surfconext.nl",
			"description:en": "OpenConext SSO Proxy",
			"contacts:2:givenName": "Support",
			"contacts:1:surName": "OpenConext",
			"contacts:2:surName": "OpenConext",
			"contacts:2:emailAddress": "[email protected]",
			"description:nl": "OpenConext SSO Proxy",
			"logo:0:width": "96",
			"logo:0:url": "https://static.test.surfconext.nl/media/conext_logo.png",
			"name:en": "OpenConext Engine",
			"contacts:0:givenName": "Support",
			"contacts:0:surName": "OpenConext Engine",
			"contacts:1:emailAddress": "[email protected]",
			"contacts:0:emailAddress": "[email protected]",
			"AssertionConsumerService:0:Location": "https://engine.test.surfconext.nl/authentication/sp/consume-assertion",
			"contacts:0:contactType": "technical",
			"contacts:2:contactType": "administrative",
			"logo:0:height": "96",
			"contacts:1:contactType": "technical",
			"contacts:1:givenName": "Support",
			"name:nl": "OpenConext Engine",
			"NameIDFormat": "urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified",
			"AssertionConsumerService:0:Binding": "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST",
			"url:nl": "https://engine.test.surfconext.nl",
			"displayName:en": "OpenConext Engine"
		},
		"allowedEntities": []
	}
}

If an invalid request results in errors because of schema validations then a BAD_REQUEST is returned with the validation errors. The invalid request - invalid enum for NameIDFormat -:

curl -H 'Content-Type: application/json' -u sp-portal:secret  -X PUT \ 
-d '{"id": "fa4fd71d-b9d1-4da7-95c2-3be6bbeaf1f0","type": "saml20_sp","pathUpdates": {"metaDataFields.NameIDFormats:0": "bogus"}}' \ 
'http://localhost:8080/manage/api/internal/metadata'

And the result:

{
	"timestamp": 1506060789246,
	"status": 400,
	"error": "org.everit.json.schema.ValidationException",
	"exception": "org.everit.json.schema.ValidationException",
	"message": "#/metaDataFields/NameIDFormats:0: bogus is not a valid enum value",
	"path": "/manage/api/internal/metadata",
	"validations": "#/metaDataFields/NameIDFormats:0: bogus is not a valid enum value"
}

Ansible authentication & authorization configuration

In the Manage application configuration you specify - or override using ansible - the location of the Manage api user configuration. This YML file contains all the internal API users, passwords and scopes. Example:

apiUsers:
  - {
      name: "attribute-aggregator",
      password: "secret",
      scopes: [READ]
    }
  - {
      name: "pdp",
      password: "secret",
      scopes: [READ]
    }
  - {
      name: "sp-portal",
      password: "secret",
      scopes: [READ, WRITE, PUSH]
    }
Clone this wiki locally