344377b23808d1c4511ebe8eae5cdb6fe96071ff
[src/app-framework-binder.git] / src / afbs-api.c
1 /*
2  * Copyright (C) 2015 "IoT.bzh"
3  * Author "Fulup Ar Foll"
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #include "local-def.h"
21
22 // Dummy sample of Client Application Context
23 typedef struct {
24   int  something;       
25   void *whateveryouwant;
26 } MyClientApplicationHandle;
27
28
29 // Request Creation of new context if it does not exist
30 STATIC json_object* clientContextCreate (AFB_request *request) {
31     json_object *jresp;
32     int   res;
33     char *token;
34     AFB_clientCtx *client=request->client; // get client context from request
35    
36     // check we do not already have a session
37     if ((client != NULL) && (client->ctx != NULL)) {
38         request->errcode=MHD_HTTP_FORBIDDEN;
39         return (jsonNewMessage(AFB_FAIL, "Token exist use refresh"));
40     }
41         
42     // request a new client context token and check result 
43     if (AFB_UNAUTH == ctxTokenCreate (request)) {
44         request->errcode=MHD_HTTP_UNAUTHORIZED;
45         jresp= jsonNewMessage(AFB_FAIL, "No/Invalid initial token provided [should match --token=xxxx]");
46         return (jresp);
47     }
48     
49     // request a new client context token and check result 
50     if (AFB_SUCCESS != ctxTokenCreate (request)) {
51         request->errcode=MHD_HTTP_UNAUTHORIZED;
52         jresp= jsonNewMessage(AFB_FAIL, "Token Session Not Activated [restart with --token=xxxx]");
53         return (jresp);
54     }
55    
56     // add a client context to session
57     client->ctx = malloc (sizeof (MyClientApplicationHandle));
58     
59     // Send response to UI
60     jresp = json_object_new_object();               
61     json_object_object_add(jresp, "token", json_object_new_string (client->token));
62
63     return (jresp);
64 }
65
66 // Renew an existing context
67 STATIC json_object* clientContextRefresh (AFB_request *request) {
68     json_object *jresp;
69
70     // note: we do not need to parse the old token as clientContextRefresh doit for us
71     if (AFB_SUCCESS != ctxTokenRefresh (request)) {
72         request->errcode=MHD_HTTP_UNAUTHORIZED;
73         jresp= jsonNewMessage(AFB_FAIL, "Token Exchange Broken Refresh Refused");
74     } else {
75         jresp = json_object_new_object();
76         json_object_object_add(jresp, "token", json_object_new_string (request->client->token));              
77     }
78             
79     return (jresp);
80 }
81
82
83 // Verify a context is still valid 
84 STATIC json_object* clientContextCheck (AFB_request *request) {
85     
86     json_object *jresp = json_object_new_object();
87     
88     // add an error code to respond
89     if (AFB_SUCCESS != ctxTokenCheck (request)) {
90         request->errcode=MHD_HTTP_UNAUTHORIZED;
91         json_object_object_add(jresp, "isvalid", json_object_new_boolean (FALSE));
92     } else {
93         json_object_object_add(jresp, "isvalid", json_object_new_boolean (TRUE));       
94     }
95         
96     return (jresp); 
97 }
98
99 // Close and Free context
100 STATIC json_object* clientContextReset (AFB_request *request) {
101     json_object *jresp;
102    
103     // note: we do not need to parse the old token as clientContextRefresh doit for us
104     if (AFB_SUCCESS != ctxTokenReset (request)) {
105         request->errcode=MHD_HTTP_UNAUTHORIZED;
106         jresp= jsonNewMessage(AFB_FAIL, "No Token Client Context [use --token=xxx]");
107     } else {
108         jresp = json_object_new_object();
109         json_object_object_add(jresp, "uuid", json_object_new_string (request->client->uuid));              
110     }
111     
112     return (jresp); 
113 }
114
115 // This function is call when Client Session Context is removed
116 // Note: when freeCtxCB==NULL standard free/malloc is called
117 STATIC void clientContextFree(AFB_clientCtx *client) {
118     fprintf (stderr,"Plugin[%s] Closing Session uuid=[%s]\n", client->plugin->prefix, client->uuid);
119     free (client->ctx);
120 }
121
122 STATIC  AFB_restapi pluginApis[]= {
123   {"ping"          , (AFB_apiCB)apiPingTest         ,"Ping Rest Test Service"},
124   {"token-create"  , (AFB_apiCB)clientContextCreate ,"Request Client Context Creation"},
125   {"token-refresh" , (AFB_apiCB)clientContextRefresh,"Refresh Client Context Token"},
126   {"token-check"   , (AFB_apiCB)clientContextCheck  ,"Check Client Context Token"},
127   {"token-reset"   , (AFB_apiCB)clientContextReset  ,"Close Client Context and Free resources"},
128   {NULL}
129 };
130
131 PUBLIC AFB_plugin *afsvRegister () {
132     AFB_plugin *plugin = malloc (sizeof (AFB_plugin));
133     plugin->type  = AFB_PLUGIN_JSON; 
134     plugin->info  = "Application Framework Binder Service";
135     plugin->prefix= "afbs";  // url base
136     plugin->apis  = pluginApis;
137     plugin->handle= (void*) "What ever you want";
138     plugin->freeCtxCB= (void*) clientContextFree;
139     
140     return (plugin);
141 };