X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=docs%2Fafb-application-writing.md;h=0434c5014b9a682d6201d9184b6aba2f581eba01;hb=6f13ad1989875b5a0ce50b24211fd1fba093735f;hp=cc513b4834b11488b7d6f6ceb494ec0bb805f818;hpb=f6bc48698587758fb764bae66302002fe148e978;p=src%2Fapp-framework-binder.git diff --git a/docs/afb-application-writing.md b/docs/afb-application-writing.md index cc513b48..0434c501 100644 --- a/docs/afb-application-writing.md +++ b/docs/afb-application-writing.md @@ -1,8 +1,6 @@ -How to write an application on top of AGL FRAMEWORK -==================================================== +# How to write an application on top of AGL FRAMEWORK -Programming Languages for Applications ------------------------------------------ +## Programming Languages for Applications ### Writing an HTML5 application @@ -11,7 +9,8 @@ applications for AGL framework using their preferred HTML5 framework. Developers may also take advantage of powerful server side bindings to improve -application behavior. Server side bindings return an application/json mine-type +application behavior. +Server side bindings return an application/json mine-type and can be accessed though either HTTP or Websockets. In a near future, JSON-RPC protocol should be added to complete the current @@ -25,14 +24,15 @@ Two examples of HTML5 applications are given: ### Writing a Qt application -Writing Qt applications is also supported. Qt offers standard API to send -request through HTTP or WebSockets. +Writing Qt applications is also supported. +Qt offers standard API to send request through HTTP or WebSockets. -It is also possible to write QML applications. A sample QML application -[token-websock] is available: +It is also possible to write QML applications. +A sample QML application [token-websock] is available: - [token-websock](https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/app-framework-binder.git;a=blob;f=test/token-websock.qml) -a simple "hello world" application in QML + +A simple "hello world" application in QML ### Writing a "C" application @@ -41,31 +41,31 @@ C applications can use afb-daemon binder through a websocket connection. The library **libafbwsc** is provided for C clients that need to connect with an afb-daemon binder. -The program **afb-client-demo** is the C example that use -**libafbwsc** library. +The program **afb-client-demo** is the C example that uses the +**libafbwsc** library. Source code is available here [src/afb-client-demo.c](https://gerrit.automotivelinux.org/gerrit/gitweb?p=src/app-framework-binder.git;a=blob;f=src/afb-client-demo.c). -Current implementation relies on libsystemd and file descriptors. -This model might be review in the future to support secure sockets +Current implementation relies on libsystemd and file descriptors. +This model may be reviewed in the future to support secure sockets and get rid of libsystemd dependency. -Handling sessions within applications -------------------------------------- +### Handling sessions within applications Applications should understand sessions and token management when interacting with afb-daemon binder. -Applications communicate with their private binder(afb-daemon) using -a network connection or potentially any other connection channel. While the -current version does not yet implement Unix socket, this feature might be added -in the near future. Developers need to be warn that HTTP protocol is a none +Applications communicate with their private binder (afb-daemon) using +a network connection or any other potential connection channel. +While the current version does not yet implement Unix socket, +this feature might be added in the near future. +Developers need to be warn that HTTP protocol is a none connected protocol and that using HTTP socket connection to authenticate clients is not supported. For this reason, the binder should authenticate the application -by using a shared secret. The secret is named "token" and the identification -of client is named "session". +by using a shared secret. +The secret is named "token" and the identification of client is named "session.” The examples **token-websock.qml** and **afb-client** are demonstrating how authentication and sessions are managed. @@ -73,24 +73,27 @@ how authentication and sessions are managed. ### Handling sessions Bindings and other binder features need to keep track of client -instances. This is especially important for bindings running as services +instances. +This is especially important for bindings running as services as they may typically have to keep each client's data separated. -For HTML5 applications, the web runtime handles the cookie of session +For HTML5 applications, the web runtime handles the cookie of the session that the binder afb-daemon automatically sets. Session identifier can be set using the parameter **uuid** or **x-afb-uuid** in -URI requests. Within current version of the framework session UUID is supported +URI requests. +Within current version of the framework session UUID is supported by both HTTP requests and websocket negotiation. ### Exchanging tokens At application start, AGL framework communicates a shared secret to both binder -and client application. This initial secret is called the "**initial token**". +and client application. +This initial secret is called the "**initial token**". For each of its client application, the binder manages a current active -token for session management. This authentication token can be use to restrict -the access to some binding's methods. +token for session management. +This authentication token can be use to restrict the access to some binding's methods. The token must be included in URI request on HTTP or during websockets connection using parameter **token** or **x-afb-token**. @@ -102,7 +105,9 @@ To ensure security, tokens must be refreshed periodically. In following examples, we suppose that **afb-daemon** is launched with something equivalent to: - $ afb-daemon --port=1234 --token=123456 [...] +```bash +afb-daemon --port=1234 --token=123456 [...] +``` making the expectation that **AuthLogin** binding is requested as default. @@ -110,102 +115,117 @@ making the expectation that **AuthLogin** binding is requested as default. First, connects with the initial token, 123456: - $ curl http://localhost:1234/api/auth/connect?token=123456 - { - "jtype": "afb-reply", - "request": { - "status": "success", - "token": "0aef6841-2ddd-436d-b961-ae78da3b5c5f", - "uuid": "850c4594-1be1-4e9b-9fcc-38cc3e6ff015" - }, - "response": {"token": "A New Token and Session Context Was Created"} - } +```bash +$ curl http://localhost:1234/api/auth/connect?token=123456 +{ + "jtype": "afb-reply", + "request": { + "status": "success", + "token": "0aef6841-2ddd-436d-b961-ae78da3b5c5f", + "uuid": "850c4594-1be1-4e9b-9fcc-38cc3e6ff015" + }, + "response": {"token": "A New Token and Session Context Was Created"} +} +``` It returns an answer containing session UUID, 850c4594-1be1-4e9b-9fcc-38cc3e6ff015, and a refreshed token, 850c4594-1be1-4e9b-9fcc-38cc3e6ff015. Check if session and token is valid: - $ curl http://localhost:1234/api/auth/check?token=0aef6841-2ddd-436d-b961-ae78da3b5c5f\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015 - { - "jtype": "afb-reply", - "request": {"status":"success"}, - "response": {"isvalid":true} - } +```bash +$ curl http://localhost:1234/api/auth/check?token=0aef6841-2ddd-436d-b961-ae78da3b5c5f\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015 +{ + "jtype": "afb-reply", + "request": {"status":"success"}, + "response": {"isvalid":true} +} +``` Refresh the token: - $ curl http://localhost:1234/api/auth/refresh?token=0aef6841-2ddd-436d-b961-ae78da3b5c5f\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015 - { - "jtype": "afb-reply", - "request": { - "status":"success", - "token":"b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9" - }, - "response": {"token":"Token was refreshed"} - } +```bash +$ curl http://localhost:1234/api/auth/refresh?token=0aef6841-2ddd-436d-b961-ae78da3b5c5f\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015 +{ + "jtype": "afb-reply", + "request": { + "status":"success", + "token":"b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9" + }, + "response": {"token":"Token was refreshed"} +} +``` Close the session: - curl http://localhost:1234/api/auth/logout?token=b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015 - { - "jtype": "afb-reply", - "request": {"status": "success"}, - "response": {"info":"Token and all resources are released"} - } +```bash +$ curl http://localhost:1234/api/auth/logout?token=b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015 +{ + "jtype": "afb-reply", + "request": {"status": "success"}, + "response": {"info":"Token and all resources are released"} +} +``` Checking on closed session for uuid should be refused: - curl http://localhost:1234/api/auth/check?token=b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015 - { - "jtype": "afb-reply", - "request": { - "status": "failed", - "info": "invalid token's identity" - } - } +```bash +$ curl http://localhost:1234/api/auth/check?token=b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015 +{ + "jtype": "afb-reply", + "request": { + "status": "failed", + "info": "invalid token's identity" + } +} +``` #### Using afb-client-demo -> The program is packaged within AGL in the rpm **libafbwsc-dev** +- The program is packaged within AGL in the rpm **libafbwsc-dev** Here is an example of exchange using **afb-client-demo**: - $ afb-client-demo ws://localhost:1234/api?token=123456 - auth connect - ON-REPLY 1:auth/connect: {"jtype":"afb-reply","request":{"status":"success", - "token":"63f71a29-8b52-4f9b-829f-b3028ba46b68","uuid":"5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1"}, - "response":{"token":"A New Token and Session Context Was Created"}} - auth check - ON-REPLY 2:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}} - auth refresh - ON-REPLY 4:auth/refresh: {"jtype":"afb-reply","request":{"status":"success", - "token":"8b8ba8f4-1b0c-48fa-962d-4a00a8c9157e"},"response":{"token":"Token was refreshed"}} - auth check - ON-REPLY 5:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}} - auth refresh - ON-REPLY 6:auth/refresh: {"jtype":"afb-reply","request":{"status":"success", - "token":"e83b36f8-d945-463d-b983-5d8ed73ba529"},"response":{"token":"Token was refreshed"}} +```bash +$ afb-client-demo ws://localhost:1234/api?token=123456 +auth connect +ON-REPLY 1:auth/connect: {"jtype":"afb-reply","request":{"status":"success", + "token":"63f71a29-8b52-4f9b-829f-b3028ba46b68","uuid":"5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1"}, + "response":{"token":"A New Token and Session Context Was Created"}} +auth check +ON-REPLY 2:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}} +auth refresh +ON-REPLY 4:auth/refresh: {"jtype":"afb-reply","request":{"status":"success", + "token":"8b8ba8f4-1b0c-48fa-962d-4a00a8c9157e"},"response":{"token":"Token was refreshed"}} +auth check +ON-REPLY 5:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}} +auth refresh +ON-REPLY 6:auth/refresh: {"jtype":"afb-reply","request":{"status":"success", + "token":"e83b36f8-d945-463d-b983-5d8ed73ba529"},"response":{"token":"Token was refreshed"}} +``` After closing connection, reconnect as here after: - $ afb-client-demo ws://localhost:1234/api?token=e83b36f8-d945-463d-b983-5d8ed73ba529\&uuid=5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1 auth check - ON-REPLY 1:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}} +```bash +$ afb-client-demo ws://localhost:1234/api?token=e83b36f8-d945-463d-b983-5d8ed73ba529\&uuid=5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1 auth check +ON-REPLY 1:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}} +``` Same connection check using **curl**: - $ curl http://localhost:1234/api/auth/check?token=e83b36f8-d945-463d-b983-5d8ed73ba529\&uuid=5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1 - {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}} +```bash +$ curl http://localhost:1234/api/auth/check?token=e83b36f8-d945-463d-b983-5d8ed73ba529\&uuid=5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1 +{"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}} +``` -Format of replies ------------------ +### Format of replies Replies use javascript object returned as serialized JSON. This object contains at least 2 mandatory fields of name **jtype** and **request** and one optional field of name **response**. -### Template +#### Template of replies This is a template of replies: @@ -223,55 +243,54 @@ This is a template of replies: } ``` -### Field jtype +#### Field jtype of replies The field **jtype** must have a value of type string equal to **"afb-reply"**. -### Field request +#### Field request of replies -The field **request** must have a value of type object. This request object -has at least one field named **status** and four optional fields named -**info**, **token**, **uuid**, **reqid**. +The field **request** must have a value of type object. +This request object has at least one field named **status** +and four optional fields named **info**, **token**, **uuid**, **reqid**. -#### Subfield request.status +##### Subfield request.status **status** must have a value of type string. This string is equal to **"success"** only in case of success. -#### Subfield request.info +##### Subfield request.info **info** is of type string and represent optional information added to the reply. -#### Subfield request.token +##### Subfield request.token **token** is of type string. It is sent either at session creation or when the token is refreshed. -#### Subfield request.uuid +##### Subfield request.uuid **uuid** is of type string. It is sent at session creation. -#### Subfield request.reqid +##### Subfield request.reqid **reqid** is of type string. It is sent in response to HTTP requests that added a parameter of name **reqid** or **x-afb-reqid** at request time. Value returns in the reply has the exact same value as the one received in the request. -### Field response +#### Field response of replies This field response optionally contains an object returned when request succeeded. -Format of events ----------------- +### Format of events Events are javascript object serialized as JSON. This object contains at least 2 mandatory fields of name **jtype** and **event** and one optional field of name **data**. -### Template +#### Template of event Here is a template of event: @@ -283,11 +302,11 @@ Here is a template of event: } ``` -### Field jtype +#### Field jtype of event The field **jtype** must have a value of type string equal to **"afb-event"**. -### Field event +#### Field event of event The field **event** carries the event's name. @@ -295,7 +314,6 @@ The name of the event is made of two parts separated by a slash: the name of the name of the API that generated the event and the name of event within the API. -### Field data +#### Field data of event This field data if present holds the data carried by the event. -