Strictly HTTPS
The API is accessible at https://api.fairphone.software/hiccup/api/v1/
There are two ways to authenticate:
When registering a device, a UUID and a token are generated and returned in the response.
The token can be used for authentication when uploading report for that particular device. This is achieved by setting the Authorization
header:
Authorization: Token ${TOKEN}
Register a device:
$ curl http://localhost:8000/hiccup/api/v1/devices/register/ \ -H "Content-Type: application/json" \ -d '{"board_date": "2018-01-01T10:10:10Z", "chipset": "foo bar"}' {"token":"a728354c460c4fd75c482839f0424a38630928ca","uuid":"7b8fb3fa-2ceb-4e8f-bfbe-8115b63148ff"}
Use the token to authenticate (e.g. for sending a heartbeat report):
$ curl http://localhost:8000/hiccup/api/v1/heartbeats/ \ -H "Authorization: Token a728354c460c4fd75c482839f0424a38630928ca" \ -H "Content-Type: application/json" \ -d '{"uuid": "7b8fb3fa-2ceb-4e8f-bfbe-8115b63148ff", "uptime": "1 hour", "build_fingerprint": "bar baz", "date": "2018-01-01T10:10:10Z", "app_version": 1, "radio_version": "x"}' {"id":-1,"uuid":"7b8fb3fa-2ceb-4e8f-bfbe-8115b63148ff","device_local_id":1,"app_version":1,"uptime":"1 hour","build_fingerprint":"bar baz","radio_version":"x","date":"2018-01-01T10:10:10Z","created_at":"2018-03-05T13:35:47.765748Z"}
Notice that the UUID in the request body needs to match the UUID registered with the token.
Users can also access the API if they are logged in to the admin backend (https://api.fairphone.software/hiccup/admin/login/
).
Authentication is handled with a CSRF token and session ID stored in a cookie.
Use curl
with a cookie file to store the CSRF token and session ID.
First get the token:
$ curl http://localhost:8000/hiccup/admin/login/ -c django_cookies.txt -s -o /dev/null $ cat django_cookies.txt # Netscape HTTP Cookie File # http://curl.haxx.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. localhost FALSE / FALSE 1551707771 csrftoken 5eRLfzQSU2I6vXTmiQcYOrK3rUGRvW3VcMMaZ6Ha9pBjzb0ajdeMe0CvEZ8PX95l
The token is returned in the Set-Cookie
header and stored in the cookie file django_cookies.txt
.
Use that file for all further requests.
To login, set the login page as a referrer and specify CSRF token, username, and password in the request parameters:
$ curl http://localhost:8000/hiccup/admin/login/ \ -c django_cookies.txt -b django_cookies.txt \ -e http://localhost:8000/hiccup/admin/login \ -d 'csrfmiddlewaretoken=5eRLfzQSU2I6vXTmiQcYOrK3rUGRvW3VcMMaZ6Ha9pBjzb0ajdeMe0CvEZ8PX95l&username=admin&password=hiccuphiccup' \ -s -o /dev/null
Login is complete and further requests with the cookie file are authenticated:
$ curl http://localhost:8000/hiccup/api/v1/devices/7b8fb3fa-2ceb-4e8f-bfbe-8115b63148ff/ -c django_cookies.txt -b django_cookies.txt {"id":4,"uuid":"7b8fb3fa-2ceb-4e8f-bfbe-8115b63148ff","imei":null,"board_date":"2018-01-01T10:10:10Z","chipset":"foo bar","last_heartbeat":null,"token":"a728354c460c4fd75c482839f0424a38630928ca","next_per_crashreport_key":1,"next_per_heartbeat_key":2,"user":6}
Care should be taken to not discard a device UUID lightly. As an UUID is obtained with anonymous data, a device can be theoretically registered over and over. The server will always return a new UUID (until the UUID pool runs out).
Endpoint: /hiccup/api/v1/devices/register/
Method: POST
Authentication: Not required
Content-Type: application/json
A JSON object.
Mandatory fields
board_date:str
: Manufacturing date of the device main board
"board_date": "2018-01-01 15:46:13"
chipset:str
: The chipset powering the device
"chipset": "Qualcomm MSM8974PRO-AA"
200 OK
token:str
: Authentication tokenuuid:str
: New universally unique identifier (UUID) of the device400 Bad Request
token:list(str)
: [Optional] List of error descriptionsuuid:list(str)
: [Optional] List of error descriptionscurl -i http://localhost:8000/hiccup/api/v1/devices/register/ \ -H "Content-Type: application/json" \ -d '{"board_date": "2018-01-01T10:10:10Z", "chipset": "foo bar"}' HTTP/1.0 200 OK Date: Mon, 05 Mar 2018 14:33:08 GMT Server: WSGIServer/0.1 Python/2.7.12 Vary: Accept, Cookie X-Frame-Options: SAMEORIGIN Content-Type: application/json Allow: POST, OPTIONS {"token":"27acf5bbe96acd038c1be739c7fac039a534ac95","uuid":"f3f6317d-666c-4b3f-af71-16a5645bc654"}
The Hiccup client can cache heartbeat reports and upload them at a later stage.
Endpoint: /hiccup/api/v1/heartbeats/
Method: POST
Authentication: Device (UUID
, token
)
Content-Type: application/json
Authorization: Token <token>
A JSON object.
Mandatory fields
app_version:int
: Version of the Hiccup client
"app_version": 10404
build_fingerprint:str
: Fingerprint of the device operating system
"build_fingerprint": "Fairphone/FP2/FP2:6.0.1/FP2-gms-18.03.1/FP2-gms-18.03.1:user/release-keys"
date:str
: Timestamp of when the heartbeat was generated (local to the device)
"date": "2018-01-01 15:46:13"
uptime:str
: Uptime of the device
"uptime": "up time: 01:39:49, idle time: 01:40:00, sleep time: 00:00:00"
uuid:str
: UUID of the device matching the authorization token
regex:^[:alnum:]{8}-([:alnum:]{4}-){3}[:alnum:]{12}$
)"uuid": "7b8fb3fa-2ceb-4e8f-bfbe-8115b63148ff"
Optional fields
radio_version:str
: Version of the device radio firmware"radio_version": "4437.1-FP2-0-08"
201 Created
id:int
: -1device_local_id:int
: Heartbeat identifier local to this device.created_at:str
: Timestamp at which the report was created server-side...
: And all the (mandatory and optional) fields described in the request body400 Bad Request
app_version:list(str)
: [Optional] List of error descriptionsbuild_fingerprint:list(str)
: [Optional] List of error descriptionsdate:list(str)
: [Optional] List of error descriptionsuptime:list(str)
: [Optional] List of error descriptionsuuid:list(str)
: [Optional] List of error descriptions401 Unauthenticated
detail:str
: Error description403 Forbidden
detail:str
: Error descriptioncurl -i http://localhost:8000/hiccup/api/v1/heartbeats/ \ -H "Authorization: Token a728354c460c4fd75c482839f0424a38630928ca" \ -H "Content-Type: application/json" \ -d '{"uuid": "7b8fb3fa-2ceb-4e8f-bfbe-8115b63148ff", "uptime": "1 hour", "build_fingerprint": "bar baz", "date": "2018-01-01T10:10:10Z", "app_version": 1, "radio_version": "x"}' HTTP/1.0 201 Created Date: Mon, 05 Mar 2018 14:06:30 GMT Server: WSGIServer/0.1 Python/2.7.12 Vary: Accept, Cookie X-Frame-Options: SAMEORIGIN Content-Type: application/json Allow: GET, POST, HEAD, OPTIONS {"id":-1,"uuid":"7b8fb3fa-2ceb-4e8f-bfbe-8115b63148ff","device_local_id":3,"app_version":1,"uptime":"1 hour","build_fingerprint":"bar baz","radio_version":"x","date":"2018-01-01T10:10:10Z","created_at":"2018-03-05T14:06:30.131540Z"}