App implementation
We will explain some basic Personium APIs while going through the implementation of the following sample app.
The dummy Cell URLs used in this sample app are listed below.
Cell type | URL |
---|---|
Data Subject Cell | https://alice.example/ |
App Cell | https://app-personium-trails.example/ |
Simplified relevant information of the HTTP communications are described for easy understanding.
OAuth 2.0 authorization code flow
If you want to use OAuth 2.0 authorization code flow with Personium, use the following engine script [1] and Personium API.
- Engine script
- Personium Cell Level API
Detailed sequence diagram available here.
In order to start the sample app, access the engine script endpoint (https://app-personium-trails.example/__/front/app
) from the web browser. Then, the following screen will prompt you to enter the data subject Cell URL.
Enter the data subject Cell URL https://alice.example/
to start the asynchronous communication that executes the engine script endpoint (start_oauth2).
# request
POST https://app-personium-trails.example/__/auth/start_oauth2
cellUrl=https://alice.example/
# Response
Status Code: 303
Location: https://alice.example/__authz
?response_type=code
&client_id=https://app-personium-trails.example/
&redirect_uri=https://app-personium-trails.example/__/front/app?cellUrl=https://alice.example/
&state=15933********-per
On the server side, this endpoint generates the state parameter used for CSRF (Cross-Site Request Forgery) prevention and then redirects the request to the authorization endpoint. In the parameter redirect_uri, the URL of the application that receives the authorization code is specified. In the sample app, the engine script endpoint (https://app-personium-trails.example/__/front/app
) is specified.
The HTTP communication to OAuth 2.0 authorization endpoint is as shown below.
# request
GET https://alice.example/__authz
response_type=code
client_id=https://app-personium-trails.example/
redirect_uri=https://app-personium-trails.example/__/front/app?cellUrl=https://alice.example/
state=15933********-per
# Response
Status Code: 200
Content-Type: text/html;charset=UTF-8
The above response is rendered as an authentication form.
Enter UserID and Password and click the login button. The following HTTP communication to Accept POST at OAuth2.0 authorization endpoint is performed.
# request
POST https://alice.example/__authz
response_type=code
client_id=https://app-personium-trails.example/
redirect_uri=https://app-personium-trails.example/__/front/app?cellUrl=https://alice.example/
state=15933********-per
username=me
password=mypassword
# Response
Status Code: 303
Location: https://app-personium-trails.example/__/front/app
?cellUrl=https://alice.example/
&last_authenticated=1592968464695
&code=GC~EPET********-9ws
&failed_count=0
&state=15933********-per
The authorization code (code) and state parameters are included and further redirected to the engine script endpoint (https://app-personium-trails.example/__/front/app
) that launches the sample app with necessary information.
# request
GET https://app-personium-trails.example/__/front/app
?cellUrl=https://alice.example/
&last_authenticated=1592968464695
&code=GC~EPET********-9ws
&failed_count=0
&state=15933********-per
# Response
Status Code: 200
Content-Type: text/html;charset=UTF-8
HTTP communication is performed after adding code (authorization code) and state to receive_redirect of engine script by asynchronous communication by Fetch from HTML of sample application.
# request
POST https://app-personium-trails.example/__/auth/receive_redirect
cellUrl=https://alice.example/
code=GC~EPET********-9ws
failed_count=0
state=15933********-per
After verifying the state with the process on receive_redirect of the engine script, access OAuth 2.0 token endpoint of Personium. HTTP communication is performed as follows.
# request
POST https://alice.example/__token
grant_type=authorization_code
code=GC~EPET********-9ws
client_id=https://app-personium-trails.example/
client_secret=
# Response
{
"access_token": "AR~omWD********IPo",
"refresh_token_expires_in": 86400,
"refresh_token": "RR~KR9********hbs",
"p_target": "https://alice.example/",
"scope": "root",
"token_type": "Bearer",
"expires_in": 3600
}
The response of the token endpoint is returned as it is as the response of receive_redirect. After that, API operations that require authorization are executed by giving the value of access_token
obtained here as HTTP header Authorization: Bearer <access_token>
.
Box installation
If the authorization is successful, the Box installation screen will be displayed.
Click the "Start Install" button to execute the Box Installation API.
# request
MKCOL https://alice.example/app-personium-trails
(bar file of app-personium-trails)
# Response
Status Code: 202
Check the progress of Box installation by accessing Get Box Metadata API.
# request
GET https://alice.example/app-personium-trails
# Response
Status Code: 200
{
"cell": {
"name": "alice",
"url": "https://alice.example/"
},
"box": {
"schema": "https://app-personium-trails.example/",
"name": "app-personium-trails",
"started_at": "2020-06-28T14:30:41.119Z",
"progress": "25%",
"url": "https://alice.example/app-personium-trails/",
"status": "installation in progress"
},
"unit": {
"path_based_cellurl_enabled": false,
"url": "https://example/"
}
}
When the status value is ready
, Box installation is complete.
Access the Box URL acquisition API when getting the Box URL from the access token with Box installed.
# request
GET https://alice.example/__box
# Response
Status Code: 200
{
"Url": "https://alice.example/app-personium-trails/"
}
The following screen will be displayed when Box installation is completed.
From this screen, you can select the location history data (eg 2020_MAY.json) which you have to obtain from Google Takeout and upload to Personium in advance. Please follow the instructions in Personium Trails.
Relational data (OData)
In the following screen, a list of location histories from a specific period is retrieved and displayed.
OData is suitable for searching through location histories. The following is an example of using Entity list acquisition API of OData collection to get a list of locations for a specific period.
# request
GET https://alice.example/app-personium-trails/index/Stay
?$filter=startTime ge 1589554800000 and startTime lt 1589641199999
&format=json
# Response
Status Code: 200
{
"d": {
"results": [
{
"__metadata": {
"uri": "https://alice.example/app-personium-trails/index/Stay(15fa4db6e57f43a5a39b3e61eff767c0)",
"etag": "W/\"1-1593356562389\"",
"type": "UserData.Stay"
},
"__id": "15fa4db6e57f43a5a39b3e61eff767c0",
"__published": "/Date(1593356562389)/",
"__updated": "/Date(1593356562389)/",
"endTime": "/Date(1589596800521)/",
"latitudeE7": 3752*****,
"longitudeE7": 13961*****,
"name": "Wakaba Store",
"placeId": "ChI********hBI",
"startTime": "/Date(1589594150000)/"
},
file (WebDAV)
Each location or movement information is saved as JSON format file. The detail screen uses the Get File API of the WebDAV collection to retrieve and display the file content.
HTTP communication is as follows.
# request
GET https://alice.example/app-personium-trails/locations/2020/0516/s_1589592400000.json
# Response
Status Code: 200
(Contents of JSON file)
Data sharing
In Personium, you can share data with others by setting the ACL (access control list) of resources. In the sample app, by clicking the toggle button to "pubic", anyone can view it without authentication.
An example of Box Level Access Control Settings API is as shown below.
# request
ACL https://alice.example/app-personium-trails/locations/2020/0516/s_1589592400000.json
<?xml version="1.0" encoding="utf-8" ?>
<acl xmlns="DAV:" xmlns:p="urn:x-personium:xmlns">
<ace xmlns="DAV:" xmlns:p="urn:x-personium:xmlns">
<principal>
<all/>
</principal>
<grant>
<privilege>
<read/>
</privilege>
</grant>
</ace>
</acl>
# Response
Status Code: 200
ACL settings can be confirmed by Get file settings API.
# request
PROPFIND https://alice.example/app-personium-trails/locations/2020/0516/s_1589592400000.json
# Response
Status Code: 207
<multistatus xmlns="DAV:">
<response>
<href>https://alice.example/app-personium-trails/locations/2020/0516/s_1589592400000.json</href>
<propstat>
<prop>
<creationdate>2020-06-29T00:02:41.816+0900</creationdate>
<getcontentlength>2623</getcontentlength>
<getcontenttype>application/json</getcontenttype>
<getlastmodified>Sun, 28 Jun 2020 15:02:41 GMT</getlastmodified>
<resourcetype/>
<acl xml:base="https://alice.example/__role/app-personium-trails/" xmlns:p="urn:x-personium:xmlns">
<ace>
<principal>
<all/>
</principal>
<grant>
<privilege>
<D:read xmlns:D="DAV:"/>
</privilege>
</grant>
</ace>
</acl>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
The engine script executes simple server-side logic on Personium. See Personium Engine for details. The template app (personium-blank-app) allows you to use two engine scripts, start_oauth2.js and receive_redirect.js, for use in the OAuth 2.0 authorization code flow. ↩