X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=doc%2Fafb-application-writing.md;h=ee5834798b108c5fae8d6e1f9f385f4932a8cc2e;hb=917b85d762e00662460da5e74b89d43d3355f2ef;hp=a7099a86e8c2bf61c0fb2a69f72b980ad95688d2;hpb=f5c013e32d1c8ee931bec45cee7bc04c5d536d50;p=src%2Fapp-framework-binder.git diff --git a/doc/afb-application-writing.md b/doc/afb-application-writing.md index a7099a86..ee583479 100644 --- a/doc/afb-application-writing.md +++ b/doc/afb-application-writing.md @@ -1,27 +1,258 @@ HOWTO WRITE an APPLICATION above AGL FRAMEWORK ============================================== version: 1 - Date: 29 mai 2016 + Date: 30 mai 2016 Author: José Bollo TABLE-OF-CONTENT-HERE +Programmation Languages for Applications +----------------------------------------- -Writing a C application ------------------------ +### Writing an HTML5 application -C applications can use the binder afb-daemon through a websocket connection. +Developers of HTML5 applications (client side) can easily create +applications for AGL framework using their preferred +HTML5 framework. -The library **libafbwsc** is made for C clients that want -to connect to the afb-daemon binder. +Developers may also take advantage of powerful server side plugins to improve +application behavior. Server side plugins return an application/json mine-type +and can be accessed though either HTTP or Websockets. -The program **afb-client-demo** is the C program that use -the provided library **libafbwsc**. -Its source code is here +In a near future, JSON-RPC protocol should be added to complete current x-afb-json1 protocol. + +Two examples of HTML5 applications are given: + +- [afb-client](https://github.com/iotbzh/afb-client) a simple "hello world" application template + +- [afm-client](https://github.com/iotbzh/afm-client) a simple "Home screen" application template + +### Writing a Qt application + +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 avaliable.. + +- [token-websock](https://github.com/iotbzh/afb-daemon/blob/master/test/token-websock.qml) +a simple "hello world" application in QML + +### Writing "C" application + +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. +Source code is available here [src/afb-client-demo.c](https://github.com/iotbzh/afb-daemon/blob/master/src/afb-client-demo.c). -The current implementation use libsystemd and file descriptors. -This may be changed in the future to also support secure sockets -and being less dependant of libsystemd. +Current implementation relies on libsystemd and file descriptors. +This model might be review in the future to support secure sockets +and free the dependency with libsystemd. + +Handling sessions within applications +------------------------------------- + +Applications should understand sessions and tokens management when interacting with afb-daemon binder. + +Applications are communicating with their private binder(afb-daemon) using +a network connection or potentially any other connection channel. While current version +does not yet implement unix domain this feature might be added in a near future. +Developers need to be warn that HTTP protocol is a none connected protocol. This prevents +from using HTTP socket connection to authenticate clients. + +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". + +The examples **token-websock.qml** and **afb-client** are demonstrating +how authentication and sessions are managed. + +### Handling sessions + +Plugins and other binder feature need to keep track of client +instances. This is especially important for plugins 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 +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 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". + +For each of its client application, the binder manages a current active +token for session management. This authentication token can be use to restrict +access to some plugin's methods. + +The token must be included in URI request on HTTP or during websockets +connection using parameter **token** or **x-afb-token**. + +To ensure security, tokens must be refreshed periodically. + +### Example of session management + +In following examples, we suppose that **afb-daemon** is launched with something equivalent to: + + $ afb-daemon --port=1234 --token=123456 [...] + +making the expectation that **AuthLogin** plugin is requested as default. + +#### Using curl + +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"} + } + +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} + } + +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"} + } + +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"} + } + +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" + } + } + +#### Using afb-client-demo + +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"}} + +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}} + +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}} + +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**. + +### Field jtype + +The field **jtype** must have a value of type string equal to **"afb-reply"**. + +### Field request + +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 + +**status** must have a value of type string. This string is equal to **"success"** +only in case of success. + +#### Subfield request.info + +**info** is of type string and represent optional information added to the reply. + +#### Subfield request.token + +**token** is of type string. It is sent either at session creation +or when the token is refreshed. + +#### Subfield request.uuid + +**uuid** is of type string. It is sent at session creation. + +#### 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 + +This field response optionally contains an object returned when request succeeded. + +### Template + +This is a template of replies: + { + "jtype": "afb-reply", + "request": { + "status": "success", + "info": "informationnal text", + "token": "e83b36f8-d945-463d-b983-5d8ed73ba52", + "uuid": "5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1", + "reqid": "application-generated-id-23456" + }, + "response": ....any response object.... + }