OpenConext / OpenConext-attribute-aggregation

OpenConext attribute aggregation
Apache License 2.0
1 stars 2 forks source link

OpenConext-attribute-aggregation

Build Status codecov.io

OpenConext Attribute Aggregation

Getting started

System Requirements

If you have yarn installed, it will be used in the build by 3rd party libs. Ensure you are on version 1.1.0, otherwise the sass node will break.

Create database

Connect to your local mysql database: mysql -uroot

Execute the following:

CREATE DATABASE aaserver;
grant all on aaserver.* to 'root'@'localhost';

Building and running

The aa-server

This project uses Spring Boot and Maven. To run locally, type:

cd aa-server

mvn spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=dev"

When developing, it's convenient to just execute the applications main-method, which is in Application. Don't forget to set the active profile to dev.

The aa-gui

The client is build with react.js and to get initially started:

cd aa-gui

To run locally:

npm run local

Browse to the application homepage.

When new npm dependencies are added:

npm install

Miscellaneous

Testing

When manually testing the aggregations in the Playground you have to provide input attributes for retrieving values from the attribute authorities.

cUrl

To mimic the behaviour of attribute aggregation for an internal client - e.g. EngineBlock - we need to post form data:

curl -X POST -H "Content-Type: application/json" --data-binary @./aa-server/src/test/resources/json/eb/request.json -u eb:secret https://aa.test2.surfconext.nl/aa/api/internal/attribute/aggregation

if you want to test all of the above curl commands against your locally running AttributeAggregation application then replace https://aa.test2.surfconext.nl with http://localhost:8080.

There is also an API for trusted clients to obtain account information based on the urn of the person:

curl -u eb:secret https://aa.test2.surfconext.nl/aa/api/internal/accounts/urn:collab:person:example.com:admin

And the API offers a end-point to delete accounts:

curl -u eb:secret -X "DELETE" "https://aa.test2.surfconext.nl/aa/api/internal/disconnect/${account_id}"

Which will return Json {"status": "OK"} on success.

Orcid

You can locally test the account linking with ORCID. You will need a valid orcid client id and secret. Copy & paste the application.yml to application.local.yml and fill in the properties orcid.client_id and orcid.secret. Then use this condiguration to start the server application:

mvn spring-boot:run -Drun.jvmArguments="-Dspring.profiles.active=dev" -Dspring.config.name=application.dev

If you go to the connected page you can link the dummy institutional user provided by the MockShibbolethFilter with an ORCID account.

If you don't specify a redirectUrl, then you will be redirected to the information page.

New Attribute Authority

New Attribute Authorities first must be added and configured in attributeAuthoritiesProductionTemplate.yml. Then add the new authority implementation to AttributeAggregatorConfiguration#attributeAggregatorById.

To actually use the new authority in the test/acc/prod environment it also needs to be configured in OpenConext-deploy attributeAuthorities.yml.j2.

REST attribute aggregator

This reusable aggregator can be used for retrieving data from a REST endpoint and supports various options for configuring a HTTP request to that endpoint e.g. an API key. Using this type does not require adding an authority implementation.

New entries are added in attributeAuthorities.yml.

Below is an example of the full configuration with explanations for the options:

- {
    id: "<id>",
    description: "<description>",
    endpoint: "<endpoint>",
    type: "rest",
    // Username for basic authentication
    user: "",
    // Password for basic authentication
    password: "",
    // Headers to add in the HTTP request
    headers: [
        {
          "key": "<key>",
          "value": "<value>",
        }
    ],
    // Path parameters to use in the value for 'endpoint'
    // Wildcards can be added with %s e.g. https://endpoint/%s/subpath/%s...
    // The index below will correspond to the order in which the wildcards are replaced
    // sourceAttribute refers to the attribute received from EngineBlock to use as the substitute
    pathParams: [
    {
        "index": 0,
        "sourceAttribute": "urn:mace:terena.org:attribute-def:schacHomeOrganization"
    },
    {
        "index": 1,
        "sourceAttribute": "urn:mace:dir:attribute-def:uid"
    }
    ],
    // Options are 'GET', 'POST', 'PUT', 'DELETE', default is 'GET'
    requestMethod: 'GET',
    // Request parameters to use in the HTTP request, will be appended as ?name=value&...
    // sourceAttribute refers to the attribute received from EngineBlock to use as the substitute
    requestParams: [
        {
            "name": "<name>",
            "sourceAttribute": "urn:mace:terena.org:attribute-def:schacHomeOrganization"
        }
    ],
    // Optional: specify node from API response for which to apply mapping for, by default the root node is used.
    // Nesting is possible using dot notation e.g field.nestedField1[0].nestedField2 etc. Any paths navigations
    // are possible from GPath
    rootListName: "<node name>",
    // Mapping to apply to the response received from the HTTP request
    // responseKey corresponds to the field in the response object of which to retrieve the value
    // targetAttribute corresponds to the attribute to send the value as in the result of aggregation
    mappings: [
    {
        "responseKey": "myResponseKey",
        "targetAttribute": "myTargetAttribute"
        // Optional: filter to search for specific node relative to the node used as root 
        // (after applying rootListName if present). Useful in case of searching for value 
        // where other field equals another value. 
        "filter": {
            "key": "<key>",
            "value": "<value>"
        }
    }
    ],
    timeOut: 15000,
    attributes: [],
    requiredInputAttributes: [
        {
            name: "urn:mace:terena.org:attribute-def:schacHomeOrganization",
        }
    ],
    validationRegExp: "[a-zA-Z0-9]*",
    // Optional: specify caching which will be used in case an error occurs when retrieving data.
    // Cache endpoint is configured separately but should return the same response structure as the primary endpoint.
    cache: {
        enabled: true,
        endpoint: "<endpoint>",
        headers: [
            {
              "key": "<key>",
              "value": "<value>",
            }
        ],
        // Specify path to relevant record. Caution: if an entire list is retrieved then it is advised to 
        // define a filter to the relevant record e.g. findAll{record->record.%s == \"%s\"}[0]. In this example
        // attributes are used from the 'filters' section so that it is possible to filter by properties. Filters
        // are optional. Path navigations and filter are possible from GPath
        rootListName: "<node name>", 
        filters: {
            index: 0,
            key: "<key>",
            sourceAttribute: "<attribute name>"
        },
        requestMethod: 'GET',
        // Specify frequency at which data is retrieved from the cache endpoint
        refreshCron: "* * * * * *"
    }
}

Configuration and deployment

On its classpath, the application has an application.yml file that contains configuration defaults that are convenient when developing.

When the application actually gets deployed to a meaningful platform, it is pre-provisioned with ansible and the application.yml depends on environment specific properties in the group_vars. See the project OpenConext-deploy and the role aa for more information.

For details, see the Spring Boot manual.

When you want to run Attribute-Aggregator in a non-OpenConext environment you can use the aa script to stop / restart and start the application.

LifeCycle Deprovisioning

There is a LifeCycle API to deprovision users. The preview endpoint:

curl -u life:secret http://localhost:8080/aa/api/deprovision/saml2_user.com | jq

And the actual Deprovisioning of the user:

curl -X DELETE -u life:secret http://localhost:8080/deprovision/aa/api/saml2_user.com | jq