3 <link rel="stylesheet" type="text/css" href="doc.css">
7 <a name="HOWTO.WRITE.an.APPLICATION.above.AGL.FRAMEWORK"></a>
8 <h1>HOWTO WRITE an APPLICATION above AGL FRAMEWORK</h1>
16 <li><a href="#HOWTO.WRITE.an.APPLICATION.above.AGL.FRAMEWORK">HOWTO WRITE an APPLICATION above AGL FRAMEWORK</a>
18 <li><a href="#Languages.for.writing.Applications">Languages for writing Applications</a>
20 <li><a href="#Writing.an.HTML5.application">Writing an HTML5 application</a></li>
21 <li><a href="#Writing.a.Qt.application">Writing a Qt application</a></li>
22 <li><a href="#Writing.a.C.application">Writing a C application</a></li>
25 <li><a href="#Handling.sessions.within.applications">Handling sessions within applications</a>
27 <li><a href="#Handling.sessions">Handling sessions</a></li>
28 <li><a href="#Exchanging.tokens">Exchanging tokens</a></li>
29 <li><a href="#Example.of.session.management">Example of session management</a>
31 <li><a href="#Using.curl">Using curl</a></li>
32 <li><a href="#Using.afb-client-demo">Using afb-client-demo</a>
38 <li><a href="#Format.of.replies">Format of replies</a>
40 <li><a href="#Field.jtype">Field jtype</a></li>
41 <li><a href="#Field.request">Field request</a>
43 <li><a href="#Subfield.request.status">Subfield request.status</a></li>
44 <li><a href="#Subfield.request.info">Subfield request.info</a></li>
45 <li><a href="#Subfield.request.token">Subfield request.token</a></li>
46 <li><a href="#Subfield.request.uuid">Subfield request.uuid</a></li>
47 <li><a href="#Subfield.request.reqid">Subfield request.reqid</a></li>
50 <li><a href="#Field.response">Field response</a></li>
51 <li><a href="#Template">Template</a></li>
58 <a name="Languages.for.writing.Applications"></a>
59 <h2>Languages for writing Applications</h2>
61 <a name="Writing.an.HTML5.application"></a>
62 <h3>Writing an HTML5 application</h3>
64 <p>Developpers of HTML5 applications (client side) can easyly create
65 applications for AGL framework using their prefered
68 <p>Developpers can also create powerful server side plugins to improve
69 their application. This server side plugin should return the mime-type
70 application/json and can be accessed either by HTTP or by Websockets.</p>
72 <p>In a near future, the JSON-RPC protocol will be available together
73 with the current x-afb-json1 protocol.</p>
75 <p>Two examples of HTML5 applications are given:</p>
78 <li><p><a href="https://github.com/iotbzh/afb-client">afb-client</a> a simple “hello world” application</p></li>
79 <li><p><a href="https://github.com/iotbzh/afm-client">afm-client</a> a simple “Home screen” application</p></li>
83 <a name="Writing.a.Qt.application"></a>
84 <h3>Writing a Qt application</h3>
86 <p>Writing Qt applications is also possible because Qt offers APIs to
87 make HTTP queries and to connect using WebSockets.</p>
89 <p>It is even possible to write a QML application.
90 It is demontrated by the sample application token-websock:</p>
93 <li><a href="https://github.com/iotbzh/afb-daemon/blob/master/test/token-websock.qml">token-websock</a>
94 a simple “hello world” application in QML</li>
98 <a name="Writing.a.C.application"></a>
99 <h3>Writing a C application</h3>
101 <p>C applications can use the binder afb-daemon through a websocket connection.</p>
103 <p>The library <strong>libafbwsc</strong> is made for C clients that want
104 to connect to the afb-daemon binder.</p>
106 <p>The program <strong>afb-client-demo</strong> is the C program that use
107 the provided library <strong>libafbwsc</strong>.
108 Its source code is here
109 <a href="https://github.com/iotbzh/afb-daemon/blob/master/src/afb-client-demo.c">src/afb-client-demo.c</a>.</p>
111 <p>The current implementation use libsystemd and file descriptors.
112 This may be changed in the future to also support secure sockets
113 and being less dependant of libsystemd.</p>
115 <a name="Handling.sessions.within.applications"></a>
116 <h2>Handling sessions within applications</h2>
118 <p>Applications must be aware of the the features session and token
119 when they interact with the binder afb-daemon.</p>
121 <p>Applications are communicating with their binder afb-daemon using
122 a network connection or a kind of network connection (unix domain
123 socket isn’t currently implemented but could be used in near future).
124 Also, HTTP protocol is not a connected protocol. It means that
125 the socket connection can not be used to authenticate a client.</p>
127 <p>For this reason, the binder should authenticate the application
128 by using a commonly shared secret named token and the identification
129 of the client named session.</p>
131 <p>The examples <strong>token-websock.qml</strong> and <strong>afb-client</strong> are demonstrating
132 how authentication and sessions are managed.</p>
134 <a name="Handling.sessions"></a>
135 <h3>Handling sessions</h3>
137 <p>Plugins and features of the binder need to keep track of the client
138 instances. This of importance for plugins running as service
139 because they may have to separate the data of each client.</p>
141 <p>For HTML5 applications, the web runtime handles the cookie of session
142 that the binder afb-daemon automatically sets.</p>
144 <p>In any case, the session identifier can be set using the parameters
145 <strong>uuid</strong> or <strong>x-afb-uuid</strong> in the request uri. That is understood
146 by HTTP requests and by the negociation of websockets.</p>
148 <a name="Exchanging.tokens"></a>
149 <h3>Exchanging tokens</h3>
151 <p>At start, the framework communicates a common secret to both the binder
152 and its client: the application. This initial secret is the
155 <p>For each of its client application, the binder manages a current active
156 token for the session. This authentication token can be a requirement for
157 accessing some methods.</p>
159 <p>The token must be passed in the request uri on HTTP or at connecting
160 websockets using the parameter <strong>token</strong> or <strong>x-afb-token</strong>.</p>
162 <p>To ensure security, tokens must be refreshed periodically.</p>
164 <a name="Example.of.session.management"></a>
165 <h3>Example of session management</h3>
167 <p>For the following exmples, we suppose that you launched <strong>afb-daemon</strong> like that or similar:</p>
169 <pre><code>$ afb-daemon --port=1234 --token=123456 [...]
172 <p>with the expectation that the plugin <strong>AuthLogin</strong> is loaded.</p>
174 <a name="Using.curl"></a>
177 <p>First, connects with the initial token, 123456:</p>
179 <pre><code>$ curl http://localhost:1234/api/auth/connect?token=123456
181 "jtype": "afb-reply",
184 "token": "0aef6841-2ddd-436d-b961-ae78da3b5c5f",
185 "uuid": "850c4594-1be1-4e9b-9fcc-38cc3e6ff015"
187 "response": {"token": "A New Token and Session Context Was Created"}
191 <p>It returns an answer containing the uuid of the session, 850c4594-1be1-4e9b-9fcc-38cc3e6ff015,
192 and the refreshed token, 850c4594-1be1-4e9b-9fcc-38cc3e6ff015.</p>
194 <p>Let check that it is available:</p>
196 <pre><code>$ curl http://localhost:1234/api/auth/check?token=0aef6841-2ddd-436d-b961-ae78da3b5c5f&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
198 "jtype": "afb-reply",
199 "request": {"status":"success"},
200 "response": {"isvalid":true}
204 <p>It works! So try now to refresh the token:</p>
206 <pre><code>$ curl http://localhost:1234/api/auth/refresh?token=0aef6841-2ddd-436d-b961-ae78da3b5c5f&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
208 "jtype": "afb-reply",
211 "token":"b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9"
213 "response": {"token":"Token was refreshed"}
217 <p>Let now close the session:</p>
219 <pre><code>curl http://localhost:1234/api/auth/logout?token=b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
221 "jtype": "afb-reply",
222 "request": {"status": "success"},
223 "response": {"info":"Token and all resources are released"}
227 <p>So now, checking for the uuid will be refused:</p>
229 <pre><code>curl http://localhost:1234/api/auth/check?token=b8ec3ec3-6ffe-448c-9a6c-efda69ad7bd9&uuid=850c4594-1be1-4e9b-9fcc-38cc3e6ff015
231 "jtype": "afb-reply",
234 "info": "invalid token's identity"
239 <a name="Using.afb-client-demo"></a>
240 <h4>Using afb-client-demo</h4>
242 <p>Here is an example of exchange using <strong>afb-client-demo</strong>:</p>
244 <pre><code>$ afb-client-demo ws://localhost:1234/api?token=123456
246 ON-REPLY 1:auth/connect: {"jtype":"afb-reply","request":{"status":"success",
247 "token":"63f71a29-8b52-4f9b-829f-b3028ba46b68","uuid":"5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1"},
248 "response":{"token":"A New Token and Session Context Was Created"}}
250 ON-REPLY 2:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}}
252 ON-REPLY 4:auth/refresh: {"jtype":"afb-reply","request":{"status":"success",
253 "token":"8b8ba8f4-1b0c-48fa-962d-4a00a8c9157e"},"response":{"token":"Token was refreshed"}}
255 ON-REPLY 5:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}}
257 ON-REPLY 6:auth/refresh: {"jtype":"afb-reply","request":{"status":"success",
258 "token":"e83b36f8-d945-463d-b983-5d8ed73ba529"},"response":{"token":"Token was refreshed"}}
261 <p>Then you leave. And can reconnect as below:</p>
263 <pre><code>$ afb-client-demo ws://localhost:1234/api?token=e83b36f8-d945-463d-b983-5d8ed73ba529&uuid=5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1 auth check
264 ON-REPLY 1:auth/check: {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}}
267 <p>The same can be continued using <strong>curl</strong>:</p>
269 <pre><code>$ curl http://localhost:1234/api/auth/check?token=e83b36f8-d945-463d-b983-5d8ed73ba529&uuid=5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1
270 {"jtype":"afb-reply","request":{"status":"success"},"response":{"isvalid":true}}
273 <a name="Format.of.replies"></a>
274 <h2>Format of replies</h2>
276 <p>The replies are made of one javascript object returned using JSON serialization.</p>
278 <p>This object containts at least 2 mandatory fields of name <strong>jtype</strong> and <strong>request</strong>
279 and an optionnal field of name <strong>response</strong>.</p>
281 <a name="Field.jtype"></a>
284 <p>The field <strong>jtype</strong> must have a value of type string equel to <strong>“afb-reply”</strong>.</p>
286 <a name="Field.request"></a>
287 <h3>Field request</h3>
289 <p>The field <strong>request</strong> must have a value of type object. This request object
290 has at least one field named <strong>status</strong> and four optionnal fields of name
291 <strong>info</strong>, <strong>token</strong>, <strong>uuid</strong>, <strong>reqid</strong>.</p>
293 <a name="Subfield.request.status"></a>
294 <h4>Subfield request.status</h4>
296 <p><strong>status</strong> must have a value of type string. This string is equal to <strong>“success”</strong>
297 only in case of success.</p>
299 <a name="Subfield.request.info"></a>
300 <h4>Subfield request.info</h4>
302 <p><strong>info</strong> is of type string and represent optionnal the information added to the reply.</p>
304 <a name="Subfield.request.token"></a>
305 <h4>Subfield request.token</h4>
307 <p><strong>token</strong> is of type string. It is sent either on the creation of the
308 session or when the token is refreshed.</p>
310 <a name="Subfield.request.uuid"></a>
311 <h4>Subfield request.uuid</h4>
313 <p><strong>uuid</strong> is of type string. It is sent on the creation of the session.</p>
315 <a name="Subfield.request.reqid"></a>
316 <h4>Subfield request.reqid</h4>
318 <p><strong>reqid</strong> is of type string. It is sent in response of HTTP requests
319 that added a parameter of name <strong>reqid</strong> or <strong>x-afb-reqid</strong>. The value
320 sent in the reply is the exact value received on the request.</p>
322 <a name="Field.response"></a>
323 <h3>Field response</h3>
325 <p>This field response optionnaly containts the object returned with successful replies.</p>
327 <a name="Template"></a>
330 <p>This is a template of replies:</p>
333 "jtype": "afb-reply",
336 "info": "informationnal text",
337 "token": "e83b36f8-d945-463d-b983-5d8ed73ba52",
338 "uuid": "5fcc3f3d-4b84-4fc7-ba66-2d8bd34ae7d1",
339 "reqid": "application-generated-id-23456"
341 "response": ....any response object....