1 HOWTO WRITE an APPLICATION above AGL FRAMEWORK
2 ==============================================
9 Languages for writing Applications
10 ----------------------------------
12 ### Writing an HTML5 application
14 Developpers of HTML5 applications (client side) can easyly create
15 applications for AGL framework using their prefered
18 Developpers can also create powerful server side plugins to improve
19 their application. This server side plugin should return the mime-type
20 application/json and can be accessed either by HTTP or by Websockets.
22 In a near future, the JSON-RPC protocol will be available together
23 with the current x-afb-json1 protocol.
25 Two examples of HTML5 applications are given:
27 - [afb-client](https://github.com/iotbzh/afb-client) a simple "hello world" application
29 - [afm-client](https://github.com/iotbzh/afm-client) a simple "Home screen" application
31 ### Writing a Qt application
33 Writing Qt applications is also possible because Qt offers APIs to
34 make HTTP queries and to connect using WebSockets.
36 It is even possible to write a QML application.
37 It is demontrated by the sample application token-websock:
39 - [token-websock](https://github.com/iotbzh/afb-daemon/blob/master/test/token-websock.qml)
40 a simple "hello world" application in QML
42 ### Writing a C application
44 C applications can use the binder afb-daemon through a websocket connection.
46 The library **libafbwsc** is made for C clients that want
47 to connect to the afb-daemon binder.
49 The program **afb-client-demo** is the C program that use
50 the provided library **libafbwsc**.
51 Its source code is here
52 [src/afb-client-demo.c](https://github.com/iotbzh/afb-daemon/blob/master/src/afb-client-demo.c).
54 The current implementation use libsystemd and file descriptors.
55 This may be changed in the future to also support secure sockets
56 and being less dependant of libsystemd.
58 Handling sessions within applications
59 -------------------------------------
61 Applications must be aware of the the features session and token
62 when they interact with the binder afb-daemon.
64 Applications are communicating with their binder afb-daemon using
65 a network connection or a kind of network connection (unix domain
66 socket isn't currently implemented but could be used in near future).
67 Also, HTTP protocol is not a connected protocol. It means that
68 the socket connection can not be used to authenticate a client.
70 For this reason, the binder should authenticate the application
71 by using a commonly shared secret named token and the identification
72 of the client named session.
74 The examples **token-websock.qml** and **afb-client** are demonstrating
75 how authentication and sessions are managed.
79 Plugins and features of the binder need to keep track of the client
80 instances. This of importance for plugins running as service
81 because they may have to separate the data of each client.
83 For HTML5 applications, the web runtime handles the cookie of session
84 that the binder afb-daemon automatically sets.
86 In any case, the session identifier can be set using the parameters
87 **uuid** or **x-afb-uuid** in the request uri. That is understood
88 by HTTP requests and by the negociation of websockets.
92 At start, the framework communicates a common secret to both the binder
93 and its client: the application. This initial secret is the
96 For each of its client application, the binder manages a current active
97 token for the session. This authentication token can be a requirement for
98 accessing some methods.
100 The token must be passed in the request uri on HTTP or at connecting
101 websockets using the parameter **token** or **x-afb-token**.
103 To ensure security, tokens must be refreshed periodically.
105 ### Example of session management
107 For the following exmples, we suppose that you launched **afb-daemon** like that or similar:
109 $ afb-daemon --port=1234 --token=123456 [...]
111 with the expectation that the plugin **AuthLogin** is loaded.
115 First, connects with the initial token, 123456:
117 $ curl http://localhost:1234/api/auth/connect?token=123456
119 "jtype": "afb-reply",
122 "token": "0aef6841-2ddd-436d-b961-ae78da3b5c5f",
123 "uuid": "850c4594-1be1-4e9b-9fcc-38cc3e6ff015"
125 "response": {"token": "A New Token and Session Context Was Created"}
128 It returns an answer containing the uuid of the session, 850c4594-1be1-4e9b-9fcc-38cc3e6ff015,
129 and the refreshed token, 850c4594-1be1-4e9b-9fcc-38cc3e6ff015.
131 Let check that it is available:
133 $ curl http://localhost:1234/api/auth/check?token=0aef6841-2ddd-436d-b961-ae78da3b5c5f\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
135 "jtype": "afb-reply",
136 "request": {"status":"success"},
137 "response": {"isvalid":true}
140 It works! So try now to refresh the token:
142 $ curl http://localhost:1234/api/auth/refresh?token=0aef6841-2ddd-436d-b961-ae78da3b5c5f\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
144 "jtype": "afb-reply",
147 "token":"b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9"
149 "response": {"token":"Token was refreshed"}
152 Let now close the session:
154 curl http://localhost:1234/api/auth/logout?token=b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
156 "jtype": "afb-reply",
157 "request": {"status": "success"},
158 "response": {"info":"Token and all resources are released"}
161 So now, checking for the uuid will be refused:
163 curl http://localhost:1234/api/auth/check?token=b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9\&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
165 "jtype": "afb-reply",
168 "info": "invalid token's identity"
172 #### Using afb-client-demo
174 Here is an example of exchange using **afb-client-demo**:
176 $ afb-client-demo ws://localhost:1234/api?token=123456
178 ON-REPLY 1:auth/connect: {"jtype":"afb-reply","request":{"status":"success",
179 "token":"63f71a29-8b52-4f9b-829f-b3028ba46b68","uuid":"5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1"},
180 "response":{"token":"A New Token and Session Context Was Created"}}
182 ON-REPLY 2:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}}
184 ON-REPLY 4:auth/refresh: {"jtype":"afb-reply","request":{"status":"success",
185 "token":"8b8ba8f4-1b0c-48fa-962d-4a00a8c9157e"},"response":{"token":"Token was refreshed"}}
187 ON-REPLY 5:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}}
189 ON-REPLY 6:auth/refresh: {"jtype":"afb-reply","request":{"status":"success",
190 "token":"e83b36f8-d945-463d-b983-5d8ed73ba529"},"response":{"token":"Token was refreshed"}}
192 Then you leave. And can reconnect as below:
194 $ afb-client-demo ws://localhost:1234/api?token=e83b36f8-d945-463d-b983-5d8ed73ba529\&uuid=5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1 auth check
195 ON-REPLY 1:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}}
197 The same can be continued using **curl**:
199 $ curl http://localhost:1234/api/auth/check?token=e83b36f8-d945-463d-b983-5d8ed73ba529\&uuid=5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1
200 {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}}
205 The replies are made of one javascript object returned using JSON serialization.
207 This object containts at least 2 mandatory fields of name **jtype** and **request**
208 and an optionnal field of name **response**.
212 The field **jtype** must have a value of type string equel to **"afb-reply"**.
216 The field **request** must have a value of type object. This request object
217 has at least one field named **status** and four optionnal fields of name
218 **info**, **token**, **uuid**, **reqid**.
220 #### Subfield request.status
222 **status** must have a value of type string. This string is equal to **"success"**
223 only in case of success.
225 #### Subfield request.info
227 **info** is of type string and represent optionnal the information added to the reply.
229 #### Subfield request.token
231 **token** is of type string. It is sent either on the creation of the
232 session or when the token is refreshed.
234 #### Subfield request.uuid
236 **uuid** is of type string. It is sent on the creation of the session.
238 #### Subfield request.reqid
240 **reqid** is of type string. It is sent in response of HTTP requests
241 that added a parameter of name **reqid** or **x-afb-reqid**. The value
242 sent in the reply is the exact value received on the request.
246 This field response optionnaly containts the object returned with successful replies.
250 This is a template of replies:
253 "jtype": "afb-reply",
256 "info": "informationnal text",
257 "token": "e83b36f8-d945-463d-b983-5d8ed73ba52",
258 "uuid": "5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1",
259 "reqid": "application-generated-id-23456"
261 "response": ....any response object....