Sending the first documents

This section walkes you through the steps required to send your first document over datalinker. We will use the API to do so, so start your bash shell and continue reading. We assume that you have completed all steps from the getting_started guide.

Note

The following guide assumes basic knowledge of the bash shell. In order to execute the commands, you need to have jq for parsing JSON installed.

Creating a sender client

We didn’t actually create clients for your linker services in the getting_started guide. Instead, we will automate this by sending a POST request to the datalinker API.

  1. Open your favorite editor and create an empty bash script. Define variables for the URL of the datalinker API, your sender service and the password you would like to use.
#!/usr/bin/env bash

BASE_URL='https://developer.datalinker.io/api'
SERVICE_ID='com.myorg.sender'
PASSWORD='somethingverylongandcomplex'
DOCUMENT_TYPE='com.myorg.my-document-type'
  1. Now we use cURL to send a POST request to the datalinker API. The result will contain a Location header field with the ID of the new client.
CLIENT_ID=$(curl -X POST -s -i --header 'Content-Type: application/json' -d "{\"linkerServiceId\": \""${SERVICE_ID}"\", \"password\": \""${PASSWORD}"\"}" ${BASE_URL}/clients | grep Location)
CLIENT_ID="${CLIENT_ID##*/}"
CLIENT_ID="${CLIENT_ID//$'\r'/}"
echo "clientId:\t\t$CLIENT_ID"

Note

The location returned from the server looks like this:

Location: /api/clients/6dfee194-71a0-43c2-9e5f-66f95b75fe4b

In order to use it in the following commands, we will strip everything before the last / and the trailing \r.

  1. The next step is to login in our new user. As a result, we will receive a Java Web Token (JWT). We will extract it from the returned JSON using jq.
JWT=$(curl -X POST -s --header 'Content-Type: application/json' -d "{\"password\": \""${PASSWORD}"\"}" ${BASE_URL}/clients/${CLIENT_ID}/authenticate)
JWT=$(jq -r '.id_token' <<< $JWT)
echo "jwt:\t\t\t$JWT"

Note

From now on, we can authenticate our requests by adding the JWT to our request headers. The header used looks like this: .. code-block:: bash

“Authorization: Bearer ${JWT}”

This is called bearer authentication as it grants permissions to the bearer (our client) of the token.

Creating a ad-hoc client

  1. Repeat the steps from above in a new file, this time setting the linker service ID to your AD_HOC_RECEIVER service’s ID.
#!/usr/bin/env bash

BASE_URL='https://developer.datalinker.io/api'
SERVICE_ID='com.myorg.ad-hoc'
PASSWORD='somethingverylongandcomplex'
  1. Login to your datalinker account in the datalinker console.
  2. Click on Entities and then on Client.
  3. You should see both of the created clients.
_images/my_two_clients.png

Deleting clients

In case you’ve accidentally created to many clients, you can delete them again either in the datalinker console or via the datalinker API.

curl -X DELETE -s -i --header "Authorization: Bearer ${JWT}" ${BASE_URL}/clients/${CLIENT_ID}

Creating an ad-hoc session

Next we are going to create a session between our clients.

  1. Create a session with the receiver side. Notice that we are not passing any parameters to this new session.
SESSION_ID=$(curl -X POST -s -i --header 'Accept: */*' --header "Authorization: Bearer ${JWT}" --header 'Content-Type: application/json' -d "{\"clientId\": \""${CLIENT_ID}"\"}" ${BASE_URL}/linker-sessions | grep Location)
SESSION_ID="${SESSION_ID##*/}"
SESSION_ID="${SESSION_ID//$'\r'/}"
echo "sessionId:\t\t$SESSION_ID"
  1. Now we need a random AES128 key and initialization vector for encrypting the data on the client.
RANDOM_PASSWORD=$(openssl rand -base64 32)
KEY_IV=$(openssl enc -nosalt -aes-128-cbc -base64 -k ${RANDOM_PASSWORD} -P)
AES_KEY=$(echo $KEY_IV | grep key)
AES_KEY="${AES_KEY##*=}"
IV=$(echo $KEY_IV | grep iv)
IV="${IV##*=}"

Note

First we are generating a random 32 characters password. Then we are generating the key and initialization vector. After that, we are again stripping the output and echoing both values.

  1. Finally we’re nicely packaging this information in a JSON, which could could then be displayed as a QR code.
SESSION_INFO="{\"key\": \""${AES_KEY}"\", \"iv\": \""${IV}"\", \"sessionId\": \""${SESSION_ID}"\"}"
echo "sessionInfo:\t\t${SESSION_INFO}"
  1. Back with our sending client, we’re asking for the session information. This could be done by scanning the QR code, we’re just copying the values from one shell to the other.
echo "Session ID: "
read SESSION_ID
echo "Key: "
read AES_KEY
echo "IV: "
read IV
  1. Now we have everything needed to link our sending service to the created linker session.
  1. At this time it is a good idea to check that everything worked in the datalinker console. In the datalinker console click on Entities and then Linker Session. Select the new linker session by clicking on the session ID. You should see something similar to the image below.
_images/my_ad_hoc_session.png

Creating a document

The document used in this example is very simple. It just contains a random number.

  1. Create a document by generating a random number:
DOCUMENT="{\"number\":$((RANDOM % 1024))}"
echo "document:\t\t:$DOCUMENT"
  1. Encrypt the document using the AES_KEY and IV:
echo $DOCUMENT > document.txt
ENCRYPTED_CONTENT=$(openssl enc -nosalt -aes-128-cbc -in document.txt -base64 -iv ${IV} -K ${AES_KEY})
rm document.txt
  1. Wrap the document as JSON, providing the document type ID and the data. Notice that we are setting two parameters on this document. This will tell the receiver if it received all documents.
DOCUMENT="{\"documentTypeId\": \""${DOCUMENT_TYPE}"\", \"parameters\": {\"documentNumber\": 1, \"numberOfDocuments\": 1}, \"data\": \""${ENCRYPTED_CONTENT}"\"}"
echo "document:\t\t:$DOCUMENT"
  1. All we have to do now is sending the document:
DOCUMENT_ID=$(curl -X POST -s -i --header 'Content-Type: application/json' --header "Authorization: Bearer ${JWT}" -d "${DOCUMENT}"     ${BASE_URL}/linker-sessions/${SESSION_ID}/documents | grep Location)
DOCUMENT_ID="${DOCUMENT_ID##*/}"
DOCUMENT_ID="${DOCUMENT_ID//$'\r'/}"
echo "documentId:\t\t$DOCUMENT_ID"
  1. Again, it is a good time to check everything worked in the datalinker console. You should see something similar to the following screenshot.
_images/my_document.png
  1. Optional: To clean up during development, you may now delete the sending client again.
curl -X DELETE -s -i --header "Authorization: Bearer ${JWT}" ${BASE_URL}/clients/${CLIENT_ID}

Retrieving a document

We’re almost done. We just need to download the document again to make sure we can successfully decrypt it.

  1. Download the documents and convert each document to base64. This is just a method of letting you iterate over the documents in bash.
DOCUMENTS=$(curl -X GET -s --header 'Accept: application/json' --header "Authorization: Bearer ${JWT}" ${BASE_URL}/linker-sessions/${SESSION_ID}/documents)
DOCUMENTS=$(echo $DOCUMENTS | jq -r '.[] | @base64')
  1. The next step is to iterate over all documents, converting them back from base64 to text. We print all the properties of the document, decrypt it and finally delete the document on datalinker.
for DOCUMENT in ${DOCUMENTS}
do
    DOCUMENT=$(echo ${DOCUMENT} | base64 --decode)
        DOCUMENT_ID=$(echo $DOCUMENT | jq -r '.documentId')
        echo "\tdocumentId:\t$DOCUMENT_ID"

        TIMESTAMP=$(echo $DOCUMENT | jq -r '.timestamp')
        echo "\t\ttimestamp:\t\t$TIMESTAMP"

        DOCUMENT_TYPE_ID=$(echo $DOCUMENT | jq -r '.documentTypeId')
        echo "\t\tdocumentTypeId:\t\t$DOCUMENT_TYPE_ID"

        PARAMETERS=$(echo $DOCUMENT | jq -r '.parameters')
        echo "\t\\tparameters:\t\t$PARAMETERS"

        ENCRYPTED_CONTENT=$(echo $DOCUMENT | jq -r '.data' | base64 -D)
        echo -n $ENCRYPTED_CONTENT > document.enc

            CONTENT=$(openssl aes-128-cbc -K ${AES_KEY} -iv ${IV} -d -in document.enc)
            echo "\t\tcontent:\t$CONTENT"

        curl -X DELETE -s --header "Authorization: Bearer ${JWT}" ${BASE_URL}/linker-sessions/${SESSION_ID}/documents/${DOCUMENT_ID}

        rm document.enc
done
  1. To clean up after ourselves, we will now close the session. This will make it and its documents unavailable after an expiration period.
curl -X DELETE -s -i --header "Authorization: Bearer ${JWT}" ${BASE_URL}/linker-sessions/${SESSION_ID}
  1. We might also delete the receiving client as we will create a new one to receive new documents. This is particularly useful if you do this on a website and don’t want to expose your password in the code.
curl -X DELETE -s -i --header "Authorization: Bearer ${JWT}" ${BASE_URL}/clients/${CLIENT_ID}

Sample scripts

The following two scripts implement what we’ve just discussed. They have been improved a bit to send a random number of documents at once. The receiver will now also respect the number of documents query the datalinker API until it received the required number of documents. Afterwards, it will exit.