This application is an adapter for Pääsuke written in Python Flask. This can be used by a party who keeps mandates on their side and offers a standard web service for Pääsuke for it to query mandates.
The idea is that there is a Postgres database that keeps the data. Into that Postgres database we create view and stored procedures that this app calls.
There is an application that mimics the different parties: https://github.com/e-gov/PH/tree/main/ph-xroad-api-mock The mock does not keep state. This application does.
Use Docker-compose to start up a Postgres database. This database has a few tables to sore information about mandates.
- Open https://app.swaggerhub.com/apis/aasaru/x-road-services-consumed-by-paasuke/0.8.0#/
- Export server stub -> python flask
`python3 -m venv venv`
`source venv/bin/activate`
`pip install -r requirements.txt`
`export PYTHONPATH=$PWD`
Check configuration example in example.cfg.
`cp config/example.cfg config/dev.cfg`
`export APP_SETTINGS=../config/dev.cfg`
`python3 api/app.py`
`docker-compose up -d`
Configure the list of roles in tests/pg_data/02b_view_paasuke_roles_view.sql
Tests are using the Postgres database running on a Docker container (so you need to have docker-compose up postgres
)
Database contains fixture data .
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
export PYTHONPATH=$PWD
export APP_SETTINGS=../config/test.cfg
pytest
`pip install gunicorn`
Point gunicorn to WSGI entrypoint wsgi.py
`gunicorn --bind 127.0.0.1:5001 wsgi:application`
When running locally then access API on http://localhost:8082
Accepts representee identifier as parameter in path
Raises 400
error if identifier is not valid
Returns the list of MandateTriplet
s with status code 200
if representee has valid mandates
Returns empty list if the representee has no valid mandates or the representee is unknown.
Selects data from Postgres view paasuke_mandates_view
Example:
curl --location 'http://localhost:8082/v1/representees/EE44444444/delegates/mandates' \
--header 'X-Road-UserId: test-header-xroad-userid' \
--header 'X-Road-Represented-Party: test-header-xroad-represented-party' \
--header 'X-Road-Id: test-header-xroad-id'
Accepts delegate identifier as parameter in path
Raises 400
error if identifier is not valid
Returns the list of MandateTriplet
s with status code 200
if delegate has valid mandates
Returns an empty list if delegate has no valid mandates or the delegate is unknown.
Selects data from Postgres view paasuke_mandates_view
Example:
curl --location 'http://127.0.0.1:8082/v1/delegates/EE22202222222/representees/mandates' \
--header 'X-Road-UserId: Test User Id'
Get a list of roles
Selects data from Postgres view paasuke_roles_view
Example:
curl --location 'http://localhost:8082/v1/roles'
Accepts repreentee and delegate identifiers as path parameters
Raises 400
error if payload data is not valid or identifiers are not valid
Raises 422
error if Postgres function paasuke_add_mandate
does not validate input data.
Return an empty list with status code 201
in case of success
Example of successful request:
curl --location 'http://127.0.0.1:8082/v1/representees/EE12345678/delegates/EE38302250123/mandates' \
--header 'Content-Type: application/json' \
--header 'X-Road-UserId: LT123456' \
--header 'X-Road-Represented-Party: LV1234566' \
--data ' {
"authorizations": [
{
"hasRole": "BR_REPRIGHT:JUHL_SOLEREP",
"userIdentifier": "EE49028099999"
}
],
"representee": {
"identifier": "EE12345678",
"legalName": "Väikefirma OÜ",
"type": "LEGAL_PERSON"
},
"delegate": {
"firstName": "Jüri",
"identifier": "EE38302250123",
"surname": "Juurikas",
"type": "NATURAL_PERSON"
},
"document": {
"singleDelegate": true,
"uuid": "5b72e01c-fa7f-479c-b014-cc19efe5b732"
},
"mandate": {
"canSubDelegate": true,
"role": "AGENCY_X:MANDATES_MANAGER",
"validityPeriod": {
"from": "2028-01-01",
"through": "2030-12-31"
}
}
}'
Accepts representeeId
, delegateId
, mandateId
as parameters in the path.
Raises 404
error if the mandate does not exist
Raises 422
error if Postgres function paasuke_add_mandate_subdelegate
does not validate input data.
Returns empty list with status code 200
in success case
Example of successful request:
curl --location 'http://127.0.0.1:8082/v1/representees/100004/delegates/100005/mandates/150003/subdelegates' \
--header 'Content-Type: application/json' \
--header 'X-Road-UserId: EE23232323' \
--header 'X-Road-Represented-Party: EE2323224444' \
--data '{
"authorizations": [
{
"hasRole": "BR_REPRIGHT:PROK_SOLEREP",
"userIdentifier": "EE39912310123"
}
],
"document": {
"singleDelegate": true,
"uuid": "5b72e01c-fa7f-479c-b014-cc19efe5b732"
},
"subDelegate": {
"firstName": "Jüri",
"identifier": "EE38302250123",
"surname": "Juurikas",
"type": "NATURAL_PERSON"
},
"validityPeriod": {
"from": "2028-01-01",
"through": "2030-12-31"
}
}'
Accepts representeeId
, delegateId
, mandateId
as parameters in the path.
Raises 404
error if the mandate does not exist
Raises 422
error if Postgres function paasuke_delete_mandate
does not validate input data.
Returns empty list with status code 200
if mandates has been marked deleted successfully
Example of successful request:
curl --location --request PUT 'http://127.0.0.1:8082/v1/representees/100001/delegates/100003/mandates/150002' \
--header 'Content-Type: application/json' \
--data '{
"action": "DELETE",
"authorizations": [
{
"userIdentifier": "EE39912310123",
"hasRole": "BR_REPRIGHT:SOLEREP"
}
],
"document": {
"uuid": "5b72e01c-fa7f-479c-b014-cc19efe5b732",
"singleDelegate": true
}
}'