aboutsummaryrefslogtreecommitdiff
path: root/src/jsonapi
diff options
context:
space:
mode:
Diffstat (limited to 'src/jsonapi')
-rw-r--r--src/jsonapi/.gitignore1
-rw-r--r--src/jsonapi/Makefile.am70
-rw-r--r--src/jsonapi/jsonapi.c82
-rw-r--r--src/jsonapi/jsonapi_document.c402
-rw-r--r--src/jsonapi/jsonapi_error.c241
-rw-r--r--src/jsonapi/jsonapi_objects.h162
-rw-r--r--src/jsonapi/jsonapi_relationship.c17
-rw-r--r--src/jsonapi/jsonapi_resource.c367
-rw-r--r--src/jsonapi/plugin_rest_reclaim.c1253
-rw-r--r--src/jsonapi/test_jsonapi.c190
10 files changed, 0 insertions, 2785 deletions
diff --git a/src/jsonapi/.gitignore b/src/jsonapi/.gitignore
deleted file mode 100644
index 077606988..000000000
--- a/src/jsonapi/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
1test_jsonapi
diff --git a/src/jsonapi/Makefile.am b/src/jsonapi/Makefile.am
deleted file mode 100644
index e572ffa9d..000000000
--- a/src/jsonapi/Makefile.am
+++ /dev/null
@@ -1,70 +0,0 @@
1# This Makefile.am is in the public domain
2AM_CPPFLAGS = -I$(top_srcdir)/src/include
3
4plugindir = $(libdir)/gnunet
5
6if USE_COVERAGE
7 AM_CFLAGS = --coverage -O0
8 XLIB = -lgcov
9endif
10
11lib_LTLIBRARIES = \
12 libgnunetjsonapi.la \
13 libgnunetjsonapiutils.la
14
15if HAVE_ABE
16lib_LTLIBRARIES += libgnunet_plugin_rest_reclaim.la
17endif
18
19libgnunet_plugin_rest_reclaim_la_SOURCES = \
20 plugin_rest_reclaim.c
21libgnunet_plugin_rest_reclaim_la_LIBADD = \
22 $(top_builddir)/src/identity/libgnunetidentity.la \
23 $(top_builddir)/src/reclaim/libgnunetreclaim.la \
24 $(top_builddir)/src/rest/libgnunetrest.la \
25 libgnunetjsonapi.la \
26 $(top_builddir)/src/reclaim-attribute/libgnunetreclaimattribute.la \
27 $(top_builddir)/src/namestore/libgnunetnamestore.la \
28 $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \
29 $(LTLIBINTL) -ljansson -lmicrohttpd
30libgnunet_plugin_rest_reclaim_la_LDFLAGS = \
31 i$(GN_PLUGIN_LDFLAGS)
32
33
34libgnunetjsonapiutils_la_LDFLAGS = \
35 -version-info 0:0:0 \
36 -no-undefined
37libgnunetjsonapiutils_la_SOURCES = \
38 jsonapi.c
39libgnunetjsonapiutils_la_LIBADD = \
40 $(top_builddir)/src/util/libgnunetutil.la \
41 $(top_builddir)/src/rest/libgnunetrest.la \
42 $(XLIB)
43
44libgnunetjsonapi_la_LDFLAGS = \
45 -version-info 0:0:0 \
46 -no-undefined
47libgnunetjsonapi_la_SOURCES = \
48 jsonapi_document.c jsonapi_objects.h \
49 jsonapi_resource.c \
50 jsonapi_error.c \
51 jsonapi_relationship.c
52libgnunetjsonapi_la_LIBADD = \
53 $(top_builddir)/src/util/libgnunetutil.la \
54 $(top_builddir)/src/json/libgnunetjson.la \
55 -ljansson \
56 $(XLIB)
57
58check_PROGRAMS = \
59 test_jsonapi
60
61TESTS = \
62 $(check_PROGRAMS)
63
64test_jsonapi_SOURCES = \
65 test_jsonapi.c
66test_jsonapi_LDADD = \
67 libgnunetjsonapi.la \
68 $(top_builddir)/src/json/libgnunetjson.la \
69 $(top_builddir)/src/util/libgnunetutil.la \
70 -ljansson
diff --git a/src/jsonapi/jsonapi.c b/src/jsonapi/jsonapi.c
deleted file mode 100644
index f7fcd972a..000000000
--- a/src/jsonapi/jsonapi.c
+++ /dev/null
@@ -1,82 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18/**
19 * @file jsonapi/jsonapi.c
20 * @brief functions to generate specifciations for JSONAPI parsing
21 * @author Martin Schanzenbach
22 */
23#include "platform.h"
24#include "gnunet_json_lib.h"
25#include "gnunet_rest_lib.h"
26
27/**
28 * TODO move this to jsonapi-utils
29 */
30
31/**
32 * Check rest request for validity
33 *
34 * @param req handle to the request
35 * @return GNUNET_OK if valid
36 */
37int
38GNUNET_JSONAPI_check_request_acceptable (struct GNUNET_REST_RequestHandle *req)
39{
40 //TODO
41 return GNUNET_OK;
42}
43
44/**
45 * Check rest request for validity
46 *
47 * @param req handle to the request
48 * @return GNUNET_OK if valid
49 */
50int
51GNUNET_JSONAPI_check_request_supported (struct GNUNET_REST_RequestHandle *req)
52{
53 //TODO
54 return GNUNET_OK;
55}
56
57/**
58 * Handle jsonapi rest request. Checks request headers for jsonapi compliance
59 *
60 * @param req rest request handle
61 * @param handler rest request handlers
62 * @param cls closure
63 * @return GNUNET_OK if successful
64 */
65int
66GNUNET_JSONAPI_handle_request (struct GNUNET_REST_RequestHandle *handle,
67 const struct GNUNET_REST_RequestHandler *handlers,
68 struct GNUNET_REST_RequestHandlerError *err,
69 void *cls)
70{
71 if (GNUNET_OK != GNUNET_JSONAPI_check_request_acceptable (handle))
72 {
73 err->error_code = MHD_HTTP_NOT_ACCEPTABLE;
74 return GNUNET_SYSERR;
75 }
76 if (GNUNET_OK != GNUNET_JSONAPI_check_request_supported (handle))
77 {
78 err->error_code = MHD_HTTP_UNSUPPORTED_MEDIA_TYPE;
79 return GNUNET_SYSERR;
80 }
81 return GNUNET_REST_handle_request (handle, handlers, err, cls);
82}
diff --git a/src/jsonapi/jsonapi_document.c b/src/jsonapi/jsonapi_document.c
deleted file mode 100644
index 3a60940f6..000000000
--- a/src/jsonapi/jsonapi_document.c
+++ /dev/null
@@ -1,402 +0,0 @@
1
2#include "platform.h"
3#include "gnunet_util_lib.h"
4#include "gnunet_json_lib.h"
5#include "jsonapi_objects.h"
6
7/**
8 * Get a JSON API object resource count
9 *
10 * @param resp the JSON API object
11 * @return the number of resources
12 */
13int
14GNUNET_JSONAPI_document_resource_count (struct GNUNET_JSONAPI_Document *doc)
15{
16 return doc->res_count;
17}
18
19/**
20 * Get a JSON API object resource by index
21 *
22 * @param resp the JSON API object
23 * @param idx index of the resource
24 * @return the resource
25 */
26struct GNUNET_JSONAPI_Resource*
27GNUNET_JSONAPI_document_get_resource (struct GNUNET_JSONAPI_Document *doc,
28 int idx)
29{
30 struct GNUNET_JSONAPI_Resource *res;
31 int i;
32
33 if ((0 == doc->res_count) ||
34 (idx >= doc->res_count))
35 return NULL;
36 res = doc->res_list_head;
37 for (i = 0; i < idx; i++)
38 {
39 res = res->next;
40 }
41 return res;
42}
43
44/**
45 * Delete a JSON API primary data
46 *
47 * @param type the JSON API resource type
48 * @param id the JSON API resource id
49 * @return a new JSON API resource or NULL on error.
50 */
51void
52GNUNET_JSONAPI_document_delete (struct GNUNET_JSONAPI_Document *doc)
53{
54 struct GNUNET_JSONAPI_Resource *res;
55 struct GNUNET_JSONAPI_Resource *res_next;
56 struct GNUNET_JSONAPI_Error *err;
57 struct GNUNET_JSONAPI_Error *err_next;
58
59
60 for (err = doc->err_list_head;
61 err != NULL;)
62 {
63 err_next = err->next;
64 GNUNET_CONTAINER_DLL_remove (doc->err_list_head,
65 doc->err_list_tail,
66 err);
67 GNUNET_JSONAPI_error_delete (err);
68 err = err_next;
69 }
70
71 for (res = doc->res_list_head;
72 res != NULL;)
73 {
74 res_next = res->next;
75 GNUNET_CONTAINER_DLL_remove (doc->res_list_head,
76 doc->res_list_tail,
77 res);
78 GNUNET_JSONAPI_resource_delete (res);
79 res = res_next;
80 }
81
82 if (NULL != doc->meta)
83 json_decref (doc->meta);
84 GNUNET_free (doc);
85 doc = NULL;
86}
87
88/**
89 * Create a JSON API primary data
90 *
91 * @return a new JSON API resource or NULL on error.
92 */
93struct GNUNET_JSONAPI_Document*
94GNUNET_JSONAPI_document_new ()
95{
96 struct GNUNET_JSONAPI_Document *result;
97
98 result = GNUNET_new (struct GNUNET_JSONAPI_Document);
99 result->res_count = 0;
100 result->err_count = 0;
101 result->meta = 0;
102 return result;
103}
104
105/**
106 * Add a JSON API error to document
107 *
108 * @param data The JSON API document to add to
109 * @param res the JSON API error to add
110 * @return the new number of resources
111 */
112void
113GNUNET_JSONAPI_document_error_add (struct GNUNET_JSONAPI_Document *doc,
114 struct GNUNET_JSONAPI_Error *err)
115{
116 GNUNET_CONTAINER_DLL_insert (doc->err_list_head,
117 doc->err_list_tail,
118 err);
119
120 doc->err_count++;
121}
122
123/**
124 * Add a JSON API resource to primary data
125 *
126 * @param data The JSON API data to add to
127 * @param res the JSON API resource to add
128 * @return the new number of resources
129 */
130void
131GNUNET_JSONAPI_document_resource_add (struct GNUNET_JSONAPI_Document *doc,
132 struct GNUNET_JSONAPI_Resource *res)
133{
134 GNUNET_CONTAINER_DLL_insert (doc->res_list_head,
135 doc->res_list_tail,
136 res);
137
138 doc->res_count++;
139}
140
141
142/**
143 * Parse given JSON object to jsonapi document.
144 *
145 * @param cls closure, NULL
146 * @param root the json object representing data
147 * @param[out] spec where to write the data
148 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
149 */
150static int
151parse_jsonapiobject (void *cls,
152 json_t *root,
153 struct GNUNET_JSON_Specification *spec)
154{
155 struct GNUNET_JSONAPI_Document *result;
156 struct GNUNET_JSONAPI_Error *error;
157 struct GNUNET_JSONAPI_Resource *resource;
158 json_t *meta_json;
159 json_t *resource_json;
160 json_t *errors_json;
161 json_t *value;
162 size_t index;
163
164 struct GNUNET_JSON_Specification jsonapispecerrors[] = {
165 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ERRORS, &errors_json),
166 GNUNET_JSON_spec_end()
167 };
168 if (GNUNET_OK !=
169 GNUNET_JSON_parse (root, jsonapispecerrors,
170 NULL, NULL))
171 {
172 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
173 "JSONAPI document does not contain error objects\n");
174 } else if (!json_is_array (errors_json))
175 {
176 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
177 "Error object is not array!\n");
178 GNUNET_JSON_parse_free (jsonapispecerrors);
179 return GNUNET_SYSERR;
180 }
181 struct GNUNET_JSON_Specification jsonapispecmeta[] = {
182 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_META, &meta_json),
183 GNUNET_JSON_spec_end()
184 };
185 if (GNUNET_OK !=
186 GNUNET_JSON_parse (root, jsonapispecmeta,
187 NULL, NULL))
188 {
189 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
190 "JSONAPI document does not contain error objects\n");
191 }
192 struct GNUNET_JSON_Specification jsonapispecresource[] = {
193 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_DATA, &resource_json),
194 GNUNET_JSON_spec_end()
195 };
196 if (GNUNET_OK !=
197 GNUNET_JSON_parse (root, jsonapispecresource,
198 NULL, NULL))
199 {
200 if (NULL == errors_json)
201 {
202 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
203 "JSONAPI document contains neither error nor data!\n");
204 GNUNET_JSON_parse_free (jsonapispecerrors);
205 GNUNET_JSON_parse_free (jsonapispecmeta);
206 return GNUNET_SYSERR;
207 }
208 } else {
209 if (NULL != errors_json)
210 {
211 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
212 "JSONAPI document contains both error and data!\n");
213 GNUNET_JSON_parse_free (jsonapispecerrors);
214 GNUNET_JSON_parse_free (jsonapispecmeta);
215 GNUNET_JSON_parse_free (jsonapispecresource);
216 return GNUNET_SYSERR;
217 }
218 }
219
220 result = GNUNET_new (struct GNUNET_JSONAPI_Document);
221 result->res_count = 0;
222 result->err_count = 0;
223 if (NULL != meta_json)
224 result->meta = json_deep_copy (meta_json);
225 if (NULL != errors_json) {
226 json_array_foreach(errors_json, index, value) {
227 GNUNET_assert (GNUNET_OK ==
228 GNUNET_JSONAPI_json_to_error (value,
229 &error));
230 GNUNET_JSONAPI_document_error_add (result, error);
231 }
232 }
233 if (NULL != resource_json) {
234 if (0 != json_is_array (resource_json))
235 {
236 json_array_foreach(resource_json, index, value) {
237 GNUNET_assert (GNUNET_OK ==
238 GNUNET_JSONAPI_json_to_resource (value,
239 &resource));
240 GNUNET_JSONAPI_document_resource_add (result, resource);
241 }
242 } else {
243 GNUNET_assert (GNUNET_OK ==
244 GNUNET_JSONAPI_json_to_resource (resource_json,
245 &resource));
246 GNUNET_JSONAPI_document_resource_add (result, resource);
247 }
248 }
249 if (NULL != errors_json)
250 GNUNET_JSON_parse_free (jsonapispecerrors);
251 if (NULL != resource)
252 GNUNET_JSON_parse_free (jsonapispecresource);
253 if (NULL != meta_json)
254 GNUNET_JSON_parse_free (jsonapispecmeta);
255 *(struct GNUNET_JSONAPI_Document **) spec->ptr = result;
256 return GNUNET_OK;
257}
258
259
260/**
261 * Cleanup data left from parsing RSA public key.
262 *
263 * @param cls closure, NULL
264 * @param[out] spec where to free the data
265 */
266static void
267clean_jsonapiobject (void *cls,
268 struct GNUNET_JSON_Specification *spec)
269{
270 struct GNUNET_JSONAPI_Document **jsonapi_obj;
271 jsonapi_obj = (struct GNUNET_JSONAPI_Document **) spec->ptr;
272 if (NULL != *jsonapi_obj)
273 {
274 GNUNET_JSONAPI_document_delete (*jsonapi_obj);
275 *jsonapi_obj = NULL;
276 }
277}
278
279/**
280 * Add a JSON API resource to primary data
281 *
282 * @param data The JSON API data to add to
283 * @param res the JSON API resource to add
284 * @return the new number of resources
285 */
286void
287GNUNET_JSONAPI_document_resource_remove (struct GNUNET_JSONAPI_Document *resp,
288 struct GNUNET_JSONAPI_Resource *res)
289{
290 GNUNET_CONTAINER_DLL_remove (resp->res_list_head,
291 resp->res_list_tail,
292 res);
293 resp->res_count--;
294}
295
296
297/**
298 * String serialze jsonapi primary data
299 *
300 * @param data the JSON API primary data
301 * @param result where to store the result
302 * @return GNUNET_SYSERR on error else GNUNET_OK
303 */
304int
305GNUNET_JSONAPI_document_to_json (const struct GNUNET_JSONAPI_Document *doc,
306 json_t **root_json)
307{
308 struct GNUNET_JSONAPI_Resource *res;
309 struct GNUNET_JSONAPI_Error *error;
310 json_t *res_json;
311 json_t *res_json_tmp;
312
313 if ((NULL == doc))
314 return GNUNET_SYSERR;
315
316 *root_json = json_object ();
317
318 //Check for errors first
319 if (doc->err_count != 0)
320 {
321 res_json = json_array ();
322 for (error = doc->err_list_head;
323 error != NULL;
324 error = error->next)
325 {
326 GNUNET_assert (GNUNET_OK ==
327 GNUNET_JSONAPI_error_to_json (error,
328 &res_json_tmp));
329 json_array_append_new (res_json, res_json_tmp);
330 }
331 json_object_set_new (*root_json,
332 GNUNET_JSONAPI_KEY_ERRORS,
333 res_json);
334 } else {
335 if (0 == doc->res_count)
336 {
337 res_json = json_null();
338 } else {
339 res_json = json_array ();
340 for (res = doc->res_list_head;
341 res != NULL;
342 res = res->next)
343 {
344 GNUNET_assert (GNUNET_OK ==
345 GNUNET_JSONAPI_resource_to_json (res,
346 &res_json_tmp));
347 json_array_append_new (res_json, res_json_tmp);
348 }
349 }
350 json_object_set_new (*root_json,
351 GNUNET_JSONAPI_KEY_DATA,
352 res_json);
353 }
354 json_object_set (*root_json,
355 GNUNET_JSONAPI_KEY_META,
356 doc->meta);
357 return GNUNET_OK;
358}
359
360/**
361 * String serialze jsonapi primary data
362 *
363 * @param data the JSON API primary data
364 * @param result where to store the result
365 * @return GNUNET_SYSERR on error else GNUNET_OK
366 */
367int
368GNUNET_JSONAPI_document_serialize (const struct GNUNET_JSONAPI_Document *doc,
369 char **result)
370{
371 json_t *json_doc;
372 if (GNUNET_OK != GNUNET_JSONAPI_document_to_json (doc,
373 &json_doc))
374 return GNUNET_SYSERR;
375
376 *result = json_dumps (json_doc, JSON_INDENT(2));
377 json_decref (json_doc);
378 return GNUNET_OK;
379}
380
381/**
382 * JSON object.
383 *
384 * @param name name of the JSON field
385 * @param[out] jsonp where to store the JSON found under @a name
386 */
387struct GNUNET_JSON_Specification
388GNUNET_JSON_spec_jsonapi_document (struct GNUNET_JSONAPI_Document **jsonapi_object)
389{
390 struct GNUNET_JSON_Specification ret = {
391 .parser = &parse_jsonapiobject,
392 .cleaner = &clean_jsonapiobject,
393 .cls = NULL,
394 .field = NULL,
395 .ptr = jsonapi_object,
396 .ptr_size = 0,
397 .size_ptr = NULL
398 };
399 *jsonapi_object = NULL;
400 return ret;
401}
402
diff --git a/src/jsonapi/jsonapi_error.c b/src/jsonapi/jsonapi_error.c
deleted file mode 100644
index 8ce71d26f..000000000
--- a/src/jsonapi/jsonapi_error.c
+++ /dev/null
@@ -1,241 +0,0 @@
1#include "platform.h"
2#include "gnunet_jsonapi_lib.h"
3#include "jsonapi_objects.h"
4
5/**
6 * Parse json to error object
7 *
8 * @param err_json JSON object
9 * @param[out] err error object
10 * @return GNUNET_OK on success
11 */
12int
13GNUNET_JSONAPI_json_to_error (json_t *err_json,
14 struct GNUNET_JSONAPI_Error **err)
15{
16 struct GNUNET_JSON_Specification jsonapispecerror[] = {
17 GNUNET_JSON_spec_jsonapi_error (err),
18 GNUNET_JSON_spec_end()
19 };
20 return GNUNET_JSON_parse (err_json, jsonapispecerror,
21 NULL, NULL);
22}
23
24/**
25 * Serialze jsonapi errors
26 *
27 * @param data the JSON API errors
28 * @param result where to store the result
29 * @return GNUNET_SYSERR on error else GNUNET_OK
30 */
31int
32GNUNET_JSONAPI_error_to_json (const struct GNUNET_JSONAPI_Error *err,
33 json_t **result)
34{
35 *result = json_object ();
36
37 if ((NULL != err->id) &&
38 (0 != json_object_set_new (*result,
39 GNUNET_JSONAPI_KEY_ID,
40 json_string (err->id))))
41 return GNUNET_SYSERR;
42 if ((NULL != err->status) &&
43 (0 != json_object_set_new (*result,
44 GNUNET_JSONAPI_KEY_STATUS,
45 json_string (err->status))))
46 return GNUNET_SYSERR;
47 if ((NULL != err->code) &&
48 (0 != json_object_set_new (*result,
49 GNUNET_JSONAPI_KEY_CODE,
50 json_string (err->code))))
51 return GNUNET_SYSERR;
52
53 if ((NULL != err->title) &&
54 (0 != json_object_set_new (*result,
55 GNUNET_JSONAPI_KEY_TITLE,
56 json_string (err->title))))
57 return GNUNET_SYSERR;
58 if ((NULL != err->detail) &&
59 (0 != json_object_set_new (*result,
60 GNUNET_JSONAPI_KEY_DETAIL,
61 json_string (err->detail))))
62 return GNUNET_SYSERR;
63 if ((NULL != err->source) &&
64 (0 != json_object_set_new (*result,
65 GNUNET_JSONAPI_KEY_SOURCE,
66 err->source)))
67 return GNUNET_SYSERR;
68 if ((NULL != err->links) &&
69 (0 != json_object_set_new (*result,
70 GNUNET_JSONAPI_KEY_LINKS,
71 err->links)))
72 return GNUNET_SYSERR;
73 if ((NULL != err->meta) &&
74 (0 != json_object_set_new (*result,
75 GNUNET_JSONAPI_KEY_META,
76 err->meta)))
77 return GNUNET_SYSERR;
78 return GNUNET_OK;
79}
80
81
82/**
83 * Parse given JSON object to jsonapi document.
84 *
85 * @param cls closure, NULL
86 * @param root the json object representing data
87 * @param[out] spec where to write the data
88 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
89 */
90static int
91parse_jsonapierror (void *cls,
92 json_t *root,
93 struct GNUNET_JSON_Specification *spec)
94{
95 struct GNUNET_JSONAPI_Error *result;
96 json_t *pos;
97
98 GNUNET_assert (NULL != root);
99 result = GNUNET_new (struct GNUNET_JSONAPI_Error);
100 pos = json_object_get (root, GNUNET_JSONAPI_KEY_ID);
101 if (json_is_string (pos))
102 result->id = GNUNET_strdup (json_string_value (pos));
103
104 pos = json_object_get (root, GNUNET_JSONAPI_KEY_LINKS);
105 if (json_is_object (pos))
106 result->links = json_deep_copy (pos);
107
108 pos = json_object_get (root, GNUNET_JSONAPI_KEY_STATUS);
109 if (json_is_string (pos))
110 result->status = GNUNET_strdup (json_string_value (pos));
111
112 pos = json_object_get (root, GNUNET_JSONAPI_KEY_CODE);
113 if (json_is_string (pos))
114 result->code = GNUNET_strdup (json_string_value (pos));
115
116 pos = json_object_get (root, GNUNET_JSONAPI_KEY_TITLE);
117 if (json_is_string (pos))
118 result->title = GNUNET_strdup (json_string_value (pos));
119
120 pos = json_object_get (root, GNUNET_JSONAPI_KEY_DETAIL);
121 if (json_is_string (pos))
122 result->detail = GNUNET_strdup (json_string_value (pos));
123
124 pos = json_object_get (root, GNUNET_JSONAPI_KEY_SOURCE);
125 if (json_is_object (pos))
126 result->source = json_deep_copy (pos);
127 pos = json_object_get (root, GNUNET_JSONAPI_KEY_META);
128 if (json_is_object (pos))
129 result->meta = json_deep_copy (pos);
130 *(struct GNUNET_JSONAPI_Error **) spec->ptr = result;
131 return GNUNET_OK;
132}
133
134/**
135 * Create a JSON API error
136 *
137 * @param res the JSON error
138 */
139struct GNUNET_JSONAPI_Error*
140GNUNET_JSONAPI_error_new (const char *id,
141 const char *status,
142 const char *code,
143 const char *title,
144 const char *detail,
145 json_t *links,
146 json_t *source,
147 json_t *meta)
148{
149 struct GNUNET_JSONAPI_Error *error;
150 error = GNUNET_new (struct GNUNET_JSONAPI_Error);
151
152 if (NULL != id)
153 error->id = GNUNET_strdup (id);
154 if (NULL != status)
155 error->status = GNUNET_strdup (status);
156 if (NULL != code)
157 error->code = GNUNET_strdup (code);
158 if (NULL != title)
159 error->title = GNUNET_strdup (title);
160 if (NULL != detail)
161 error->detail = GNUNET_strdup (detail);
162 if (NULL != links)
163 error->links = json_deep_copy (links);
164 if (NULL != source)
165 error->source = json_deep_copy (source);
166 if (NULL != meta)
167 error->meta = json_deep_copy (meta);
168 return error;
169}
170/**
171 * Delete a JSON API error
172 *
173 * @param res the JSON error
174 */
175void
176GNUNET_JSONAPI_error_delete (struct GNUNET_JSONAPI_Error *error)
177{
178 GNUNET_assert (NULL != error);
179
180 if (NULL != error->id)
181 GNUNET_free (error->id);
182 if (NULL != error->status)
183 GNUNET_free (error->status);
184 if (NULL != error->code)
185 GNUNET_free (error->code);
186 if (NULL != error->title)
187 GNUNET_free (error->title);
188 if (NULL != error->detail)
189 GNUNET_free (error->detail);
190 if (NULL != error->links)
191 json_decref (error->links);
192 if (NULL != error->source)
193 json_decref (error->source);
194 if (NULL != error->meta)
195 json_decref (error->meta);
196 GNUNET_free (error);
197}
198
199
200
201/**
202 * Cleanup data left from parsing RSA public key.
203 *
204 * @param cls closure, NULL
205 * @param[out] spec where to free the data
206 */
207static void
208clean_jsonapierror (void *cls,
209 struct GNUNET_JSON_Specification *spec)
210{
211 struct GNUNET_JSONAPI_Error **jsonapi_obj;
212 jsonapi_obj = (struct GNUNET_JSONAPI_Error **) spec->ptr;
213 if (NULL != *jsonapi_obj)
214 {
215 GNUNET_JSONAPI_error_delete (*jsonapi_obj);
216 *jsonapi_obj = NULL;
217 }
218}
219/**
220 * JSON object.
221 *
222 * @param name name of the JSON field
223 * @param[out] jsonp where to store the JSON found under @a name
224 */
225struct GNUNET_JSON_Specification
226GNUNET_JSON_spec_jsonapi_error (struct GNUNET_JSONAPI_Error **jsonapi_object)
227{
228 struct GNUNET_JSON_Specification ret = {
229 .parser = &parse_jsonapierror,
230 .cleaner = &clean_jsonapierror,
231 .cls = NULL,
232 .field = NULL,
233 .ptr = jsonapi_object,
234 .ptr_size = 0,
235 .size_ptr = NULL
236 };
237 *jsonapi_object = NULL;
238 return ret;
239}
240
241
diff --git a/src/jsonapi/jsonapi_objects.h b/src/jsonapi/jsonapi_objects.h
deleted file mode 100644
index 27c64eeb7..000000000
--- a/src/jsonapi/jsonapi_objects.h
+++ /dev/null
@@ -1,162 +0,0 @@
1#include "platform.h"
2#include "gnunet_jsonapi_lib.h"
3/**
4 * jsonapi error object
5 */
6struct GNUNET_JSONAPI_Error
7{
8 /**
9 * DLL
10 */
11 struct GNUNET_JSONAPI_Error *next;
12
13 /**
14 * DLL
15 */
16 struct GNUNET_JSONAPI_Error *prev;
17
18 /**
19 * Unique error id
20 */
21 char *id;
22
23 /**
24 * Links object
25 */
26 json_t *links;
27
28 /**
29 * HTTP status code for this error
30 */
31 char *status;
32
33 /**
34 * Application error code
35 */
36 char *code;
37
38 /**
39 * Error title
40 */
41 char *title;
42
43 /**
44 * Error details
45 */
46 char *detail;
47
48 /**
49 * Error source
50 */
51 json_t *source;
52
53 /**
54 * Meta info for the error
55 */
56 json_t *meta;
57};
58
59struct GNUNET_JSONAPI_Relationship
60{
61 /**
62 * Links object
63 */
64 struct GNUNET_JSONAPI_Link *links;
65
66 /**
67 * Resource linkage data
68 */
69 struct GNUNET_JSONAPI_Resource *res_list_head;
70
71 /**
72 * DLL
73 */
74 struct GNUNET_JSONAPI_Resource *res_list_tail;
75
76 /**
77 * Number of resources in data section
78 */
79 int res_count;
80
81 /**
82 * Meta information
83 */
84 json_t *meta;
85};
86
87/**
88 * A jsonapi resource object
89 */
90struct GNUNET_JSONAPI_Resource
91{
92 /**
93 * DLL
94 */
95 struct GNUNET_JSONAPI_Resource *next;
96
97 /**
98 * DLL
99 */
100 struct GNUNET_JSONAPI_Resource *prev;
101
102 /**
103 * Resource type
104 */
105 char *type;
106
107 /**
108 * Resource ID
109 */
110 char *id;
111
112 /**
113 * Attributes object
114 */
115 json_t *attr_obj;
116
117 /**
118 * Relationship
119 */
120 struct GNUNET_JSONAPI_Relationship *relationship;
121};
122
123
124struct GNUNET_JSONAPI_Document
125{
126 /**
127 * DLL Resource
128 */
129 struct GNUNET_JSONAPI_Resource *res_list_head;
130
131 /**
132 * DLL Resource
133 */
134 struct GNUNET_JSONAPI_Resource *res_list_tail;
135
136 /**
137 * num resources
138 */
139 int res_count;
140
141 /**
142 * DLL Error
143 */
144 struct GNUNET_JSONAPI_Error *err_list_head;
145
146 /**
147 * DLL Error
148 */
149 struct GNUNET_JSONAPI_Error *err_list_tail;
150
151 /**
152 * num errors
153 */
154 int err_count;
155
156 /**
157 * Meta info
158 */
159 json_t *meta;
160};
161
162
diff --git a/src/jsonapi/jsonapi_relationship.c b/src/jsonapi/jsonapi_relationship.c
deleted file mode 100644
index b88e74cc9..000000000
--- a/src/jsonapi/jsonapi_relationship.c
+++ /dev/null
@@ -1,17 +0,0 @@
1#include "platform.h"
2#include "gnunet_jsonapi_lib.h"
3
4
5/**
6 * Delete a JSON API relationship TODO
7 *
8 * @param res the JSON relationship
9 */
10void
11GNUNET_JSONAPI_relationship_delete (struct GNUNET_JSONAPI_Relationship *relationship)
12{
13 GNUNET_assert (NULL != relationship);
14 GNUNET_free (relationship);
15}
16
17
diff --git a/src/jsonapi/jsonapi_resource.c b/src/jsonapi/jsonapi_resource.c
deleted file mode 100644
index be28ad5df..000000000
--- a/src/jsonapi/jsonapi_resource.c
+++ /dev/null
@@ -1,367 +0,0 @@
1#include "platform.h"
2#include "gnunet_jsonapi_lib.h"
3#include "jsonapi_objects.h"
4
5/**
6 * String serialze jsonapi resources
7 *
8 * @param data the JSON API resource
9 * @param result where to store the result
10 * @return GNUNET_SYSERR on error else GNUNET_OK
11 */
12int
13GNUNET_JSONAPI_resource_to_json (const struct GNUNET_JSONAPI_Resource *res,
14 json_t **result)
15{
16 struct GNUNET_JSONAPI_Resource *rel_res;
17 json_t *relationship;
18 json_t *res_json_tmp;
19 *result = json_object ();
20
21 if (0 != json_object_set_new (*result,
22 GNUNET_JSONAPI_KEY_ID,
23 json_string (res->id)))
24 return GNUNET_SYSERR;
25 if (0 != json_object_set_new (*result,
26 GNUNET_JSONAPI_KEY_TYPE,
27 json_string (res->type)))
28 return GNUNET_SYSERR;
29 if ((NULL != res->attr_obj) &&
30 (0 != json_object_set (*result,
31 GNUNET_JSONAPI_KEY_ATTRIBUTES,
32 res->attr_obj)))
33 return GNUNET_SYSERR;
34
35 //Relationships
36 if (NULL != res->relationship)
37 {
38 relationship = json_object ();
39 if (0 != res->relationship->res_count)
40 {
41 json_t *res_json;
42 switch (res->relationship->res_count)
43 {
44 case 0:
45 res_json = json_null();
46 break;
47 case 1:
48 GNUNET_assert (GNUNET_OK ==
49 GNUNET_JSONAPI_resource_to_json (res->relationship->res_list_head,
50 &res_json));
51 break;
52 default:
53 res_json = json_array ();
54 rel_res = NULL;
55 for (rel_res = res->relationship->res_list_head;
56 rel_res != NULL;
57 rel_res = rel_res->next)
58 {
59 GNUNET_assert (GNUNET_OK ==
60 GNUNET_JSONAPI_resource_to_json (rel_res,
61 &res_json_tmp));
62 json_array_append_new (res_json, res_json_tmp);
63 }
64 break;
65 }
66 json_object_set_new (relationship,
67 GNUNET_JSONAPI_KEY_DATA,
68 res_json);
69 }
70 if ((NULL != res->relationship->meta) &&
71 (0 != json_object_set_new (relationship,
72 GNUNET_JSONAPI_KEY_META,
73 res->relationship->meta)))
74 return GNUNET_SYSERR;
75 //TODO link
76 }
77
78
79 return GNUNET_OK;
80}
81
82
83/**
84 * Create a JSON API resource
85 *
86 * @param type the JSON API resource type
87 * @param id the JSON API resource id
88 * @return a new JSON API resource or NULL on error.
89 */
90struct GNUNET_JSONAPI_Resource*
91GNUNET_JSONAPI_resource_new (const char *type, const char *id)
92{
93 struct GNUNET_JSONAPI_Resource *res;
94
95 if (NULL == type)
96 return NULL;
97 if (NULL == id)
98 return NULL;
99
100 res = GNUNET_new (struct GNUNET_JSONAPI_Resource);
101 res->prev = NULL;
102 res->next = NULL;
103 res->attr_obj = NULL;
104 res->relationship = NULL;
105 res->id = GNUNET_strdup (id);
106 res->type = GNUNET_strdup (type);
107 return res;
108}
109
110/**
111 * Add a jsonapi relationship
112 * @param res the resource to add to
113 * @param rel the relationship to add
114 * @return #GNUNETOK if added successfully
115 */
116int
117GNUNET_JSONAPI_resource_set_relationship (struct GNUNET_JSONAPI_Resource *res,
118 struct GNUNET_JSONAPI_Relationship *rel)
119{
120 GNUNET_assert (NULL != res);
121 GNUNET_assert (NULL != rel);
122 if (NULL != res->relationship)
123 return GNUNET_SYSERR;
124 res->relationship = rel;
125 return GNUNET_OK;
126}
127
128/**
129 * Add a JSON API attribute
130 *
131 * @param res the JSON resource
132 * @param key the key for the attribute
133 * @param json the json_t attribute to add
134 * @return #GNUNET_OK if added successfully
135 * #GNUNET_SYSERR if not
136 */
137int
138GNUNET_JSONAPI_resource_add_attr (struct GNUNET_JSONAPI_Resource *resource,
139 const char* key,
140 json_t *json)
141{
142 if ( (NULL == resource) ||
143 (NULL == key) ||
144 (NULL == json) )
145 return GNUNET_SYSERR;
146 if (NULL == resource->attr_obj)
147 resource->attr_obj = json_object ();
148 json_object_set (resource->attr_obj, key, json);
149 return GNUNET_OK;
150}
151
152/**
153 * Read a JSON API attribute
154 *
155 * @param res the JSON resource
156 * @param key the key for the attribute
157 * @return the json_t object
158 */
159json_t*
160GNUNET_JSONAPI_resource_read_attr (const struct GNUNET_JSONAPI_Resource *resource,
161 const char* key)
162{
163 if ( (NULL == resource) ||
164 (NULL == key) ||
165 (NULL == resource->attr_obj))
166 return NULL;
167 return json_object_get (resource->attr_obj, key);
168}
169
170int
171check_resource_attr_str (const struct GNUNET_JSONAPI_Resource *resource,
172 const char* key,
173 const char* attr)
174{
175 json_t *value;
176 if ( (NULL == resource) ||
177 (NULL == key) ||
178 (NULL == attr) ||
179 (NULL == resource->attr_obj))
180 return GNUNET_NO;
181 value = json_object_get (resource->attr_obj, key);
182 if (NULL == value)
183 return GNUNET_NO;
184 if (!json_is_string (value) ||
185 (0 != strcmp (attr, json_string_value(value))))
186 {
187 return GNUNET_NO;
188 }
189 return GNUNET_YES;
190}
191
192/**
193 * Check a JSON API resource type
194 *
195 * @param res the JSON resource
196 * @param type the expected type
197 * @return GNUNET_YES if id matches
198 */
199int
200GNUNET_JSONAPI_resource_check_type (const struct GNUNET_JSONAPI_Resource *resource,
201 const char* type)
202{
203 return (0 == memcmp (type, resource->type,
204 strlen (resource->type))) ? GNUNET_YES : GNUNET_NO;
205}
206
207
208/**
209 * Delete a JSON API resource
210 *
211 * @param res the JSON resource
212 * @param result Pointer where the resource should be stored
213 */
214void
215GNUNET_JSONAPI_resource_delete (struct GNUNET_JSONAPI_Resource *resource)
216{
217 GNUNET_free (resource->id);
218 GNUNET_free (resource->type);
219 if (NULL != resource->attr_obj)
220 json_decref (resource->attr_obj);
221 if (NULL != resource->relationship)
222 GNUNET_JSONAPI_relationship_delete (resource->relationship);
223 GNUNET_free (resource);
224 resource = NULL;
225}
226
227
228/**
229 * Check a JSON API resource id
230 *
231 * @param res the JSON resource
232 * @param id the expected id
233 * @return GNUNET_YES if id matches
234 */
235int
236GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource,
237 const char* id)
238{
239 return (0 == memcmp (resource->id, id, strlen (id))) ? GNUNET_YES : GNUNET_NO;
240}
241
242/**
243 * Check a JSON API resource id
244 *
245 * @param res the JSON resource
246 * @return the resource id
247 */
248const char*
249GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource)
250{
251 return resource->id;
252}
253
254/**
255 * Parse json to resource object
256 *
257 * @param res_json JSON object
258 * @param[out] res resource object
259 * @return GNUNET_OK on success
260 */
261int
262GNUNET_JSONAPI_json_to_resource (json_t *res_json,
263 struct GNUNET_JSONAPI_Resource **res)
264{
265 struct GNUNET_JSON_Specification jsonapispecresource[] = {
266 GNUNET_JSON_spec_jsonapi_resource (res),
267 GNUNET_JSON_spec_end()
268 };
269 return GNUNET_JSON_parse (res_json, jsonapispecresource,
270 NULL, NULL);
271}
272
273/**
274 * Parse given JSON object to jsonapi document.
275 *
276 * @param cls closure, NULL
277 * @param root the json object representing data
278 * @param[out] spec where to write the data
279 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
280 */
281static int
282parse_jsonapiresource (void *cls,
283 json_t *root,
284 struct GNUNET_JSON_Specification *spec)
285{
286 struct GNUNET_JSONAPI_Resource *res;
287 const char *type;
288 const char *id;
289 json_t *attrs;
290
291 struct GNUNET_JSON_Specification dspec[] = {
292 GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_TYPE, &type),
293 GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_ID, &id),
294 GNUNET_JSON_spec_end()
295 };
296
297 if (GNUNET_OK !=
298 GNUNET_JSON_parse (root, dspec,
299 NULL, NULL))
300 {
301 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to parse resource\n");
302 return GNUNET_SYSERR;
303 }
304 res = GNUNET_JSONAPI_resource_new (type, id);
305 GNUNET_JSON_parse_free (dspec);
306
307 struct GNUNET_JSON_Specification attrspec[] = {
308 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ATTRIBUTES, &attrs),
309 GNUNET_JSON_spec_end()
310 };
311 if (GNUNET_OK !=
312 GNUNET_JSON_parse (root, attrspec,
313 NULL, NULL))
314 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Resource does not contain attributes\n");
315 if (NULL != attrs)
316 res->attr_obj = json_deep_copy (attrs);
317
318 //TODO relationship
319 GNUNET_JSON_parse_free (attrspec);
320 *(struct GNUNET_JSONAPI_Resource **) spec->ptr = res;
321 return GNUNET_OK;
322}
323
324
325/**
326 * Cleanup data left from parsing resource.
327 *
328 * @param cls closure, NULL
329 * @param[out] spec where to free the data
330 */
331static void
332clean_jsonapiresource (void *cls,
333 struct GNUNET_JSON_Specification *spec)
334{
335 struct GNUNET_JSONAPI_Resource **jsonapi_obj;
336 jsonapi_obj = (struct GNUNET_JSONAPI_Resource **) spec->ptr;
337 if (NULL != *jsonapi_obj)
338 {
339 GNUNET_JSONAPI_resource_delete (*jsonapi_obj);
340 *jsonapi_obj = NULL;
341 }
342}
343
344
345/**
346 * JSON object.
347 *
348 * @param name name of the JSON field
349 * @param[out] jsonp where to store the JSON found under @a name
350 */
351struct GNUNET_JSON_Specification
352GNUNET_JSON_spec_jsonapi_resource (struct GNUNET_JSONAPI_Resource **jsonapi_object)
353{
354 struct GNUNET_JSON_Specification ret = {
355 .parser = &parse_jsonapiresource,
356 .cleaner = &clean_jsonapiresource,
357 .cls = NULL,
358 .field = NULL,
359 .ptr = jsonapi_object,
360 .ptr_size = 0,
361 .size_ptr = NULL
362 };
363 *jsonapi_object = NULL;
364 return ret;
365}
366
367
diff --git a/src/jsonapi/plugin_rest_reclaim.c b/src/jsonapi/plugin_rest_reclaim.c
deleted file mode 100644
index 38ffc4ddb..000000000
--- a/src/jsonapi/plugin_rest_reclaim.c
+++ /dev/null
@@ -1,1253 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18/**
19 * @author Martin Schanzenbach
20 * @author Philippe Buschmann
21 * @file reclaim/plugin_rest_reclaim.c
22 * @brief GNUnet reclaim REST plugin
23 *
24 */
25
26#include "platform.h"
27#include "gnunet_rest_plugin.h"
28#include "gnunet_identity_service.h"
29#include "gnunet_gns_service.h"
30#include "gnunet_gnsrecord_lib.h"
31#include "gnunet_namestore_service.h"
32#include "gnunet_rest_lib.h"
33#include "gnunet_jsonapi_lib.h"
34#include "gnunet_jsonapi_util.h"
35#include "microhttpd.h"
36#include <jansson.h>
37#include <inttypes.h>
38#include "gnunet_signatures.h"
39#include "gnunet_reclaim_attribute_lib.h"
40#include "gnunet_reclaim_service.h"
41
42/**
43 * REST root namespace
44 */
45#define GNUNET_REST_API_NS_RECLAIM "/reclaim"
46
47/**
48 * Attribute namespace
49 */
50#define GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES "/reclaim/attributes"
51
52/**
53 * Ticket namespace
54 */
55#define GNUNET_REST_API_NS_IDENTITY_TICKETS "/reclaim/tickets"
56
57/**
58 * Revoke namespace
59 */
60#define GNUNET_REST_API_NS_IDENTITY_REVOKE "/reclaim/revoke"
61
62/**
63 * Revoke namespace
64 */
65#define GNUNET_REST_API_NS_IDENTITY_CONSUME "/reclaim/consume"
66
67/**
68 * Attribute key
69 */
70#define GNUNET_REST_JSONAPI_RECLAIM_ATTRIBUTE "attribute"
71
72/**
73 * Ticket key
74 */
75#define GNUNET_REST_JSONAPI_IDENTITY_TICKET "ticket"
76
77
78/**
79 * Value key
80 */
81#define GNUNET_REST_JSONAPI_RECLAIM_ATTRIBUTE_VALUE "value"
82
83/**
84 * State while collecting all egos
85 */
86#define ID_REST_STATE_INIT 0
87
88/**
89 * Done collecting egos
90 */
91#define ID_REST_STATE_POST_INIT 1
92
93/**
94 * The configuration handle
95 */
96const struct GNUNET_CONFIGURATION_Handle *cfg;
97
98/**
99 * HTTP methods allows for this plugin
100 */
101static char* allow_methods;
102
103/**
104 * @brief struct returned by the initialization function of the plugin
105 */
106struct Plugin
107{
108 const struct GNUNET_CONFIGURATION_Handle *cfg;
109};
110
111/**
112 * The ego list
113 */
114struct EgoEntry
115{
116 /**
117 * DLL
118 */
119 struct EgoEntry *next;
120
121 /**
122 * DLL
123 */
124 struct EgoEntry *prev;
125
126 /**
127 * Ego Identifier
128 */
129 char *identifier;
130
131 /**
132 * Public key string
133 */
134 char *keystring;
135
136 /**
137 * The Ego
138 */
139 struct GNUNET_IDENTITY_Ego *ego;
140};
141
142
143struct RequestHandle
144{
145 /**
146 * Ego list
147 */
148 struct EgoEntry *ego_head;
149
150 /**
151 * Ego list
152 */
153 struct EgoEntry *ego_tail;
154
155 /**
156 * Selected ego
157 */
158 struct EgoEntry *ego_entry;
159
160 /**
161 * Pointer to ego private key
162 */
163 struct GNUNET_CRYPTO_EcdsaPrivateKey priv_key;
164
165 /**
166 * The processing state
167 */
168 int state;
169
170 /**
171 * Handle to Identity service.
172 */
173 struct GNUNET_IDENTITY_Handle *identity_handle;
174
175 /**
176 * Rest connection
177 */
178 struct GNUNET_REST_RequestHandle *rest_handle;
179
180 /**
181 * Handle to NAMESTORE
182 */
183 struct GNUNET_NAMESTORE_Handle *namestore_handle;
184
185 /**
186 * Iterator for NAMESTORE
187 */
188 struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it;
189
190 /**
191 * Attribute claim list
192 */
193 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList *attr_list;
194
195 /**
196 * IDENTITY Operation
197 */
198 struct GNUNET_IDENTITY_Operation *op;
199
200 /**
201 * Identity Provider
202 */
203 struct GNUNET_RECLAIM_Handle *idp;
204
205 /**
206 * Idp Operation
207 */
208 struct GNUNET_RECLAIM_Operation *idp_op;
209
210 /**
211 * Attribute iterator
212 */
213 struct GNUNET_RECLAIM_AttributeIterator *attr_it;
214
215 /**
216 * Ticket iterator
217 */
218 struct GNUNET_RECLAIM_TicketIterator *ticket_it;
219
220 /**
221 * A ticket
222 */
223 struct GNUNET_RECLAIM_Ticket ticket;
224
225 /**
226 * Desired timeout for the lookup (default is no timeout).
227 */
228 struct GNUNET_TIME_Relative timeout;
229
230 /**
231 * ID of a task associated with the resolution process.
232 */
233 struct GNUNET_SCHEDULER_Task *timeout_task;
234
235 /**
236 * The plugin result processor
237 */
238 GNUNET_REST_ResultProcessor proc;
239
240 /**
241 * The closure of the result processor
242 */
243 void *proc_cls;
244
245 /**
246 * The url
247 */
248 char *url;
249
250 /**
251 * Error response message
252 */
253 char *emsg;
254
255 /**
256 * Reponse code
257 */
258 int response_code;
259
260 /**
261 * Response object
262 */
263 struct GNUNET_JSONAPI_Document *resp_object;
264
265};
266
267/**
268 * Cleanup lookup handle
269 * @param handle Handle to clean up
270 */
271static void
272cleanup_handle (struct RequestHandle *handle)
273{
274 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry;
275 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp;
276 struct EgoEntry *ego_entry;
277 struct EgoEntry *ego_tmp;
278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
279 "Cleaning up\n");
280 if (NULL != handle->resp_object)
281 GNUNET_JSONAPI_document_delete (handle->resp_object);
282 if (NULL != handle->timeout_task)
283 GNUNET_SCHEDULER_cancel (handle->timeout_task);
284 if (NULL != handle->identity_handle)
285 GNUNET_IDENTITY_disconnect (handle->identity_handle);
286 if (NULL != handle->attr_it)
287 GNUNET_RECLAIM_get_attributes_stop (handle->attr_it);
288 if (NULL != handle->ticket_it)
289 GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it);
290 if (NULL != handle->idp)
291 GNUNET_RECLAIM_disconnect (handle->idp);
292 if (NULL != handle->url)
293 GNUNET_free (handle->url);
294 if (NULL != handle->emsg)
295 GNUNET_free (handle->emsg);
296 if (NULL != handle->namestore_handle)
297 GNUNET_NAMESTORE_disconnect (handle->namestore_handle);
298 if ( NULL != handle->attr_list )
299 {
300 for (claim_entry = handle->attr_list->list_head;
301 NULL != claim_entry;)
302 {
303 claim_tmp = claim_entry;
304 claim_entry = claim_entry->next;
305 GNUNET_free(claim_tmp->claim);
306 GNUNET_free(claim_tmp);
307 }
308 GNUNET_free (handle->attr_list);
309 }
310 for (ego_entry = handle->ego_head;
311 NULL != ego_entry;)
312 {
313 ego_tmp = ego_entry;
314 ego_entry = ego_entry->next;
315 GNUNET_free (ego_tmp->identifier);
316 GNUNET_free (ego_tmp->keystring);
317 GNUNET_free (ego_tmp);
318 }
319 if (NULL != handle->attr_it)
320 {
321 GNUNET_free(handle->attr_it);
322 }
323 GNUNET_free (handle);
324}
325
326static void
327cleanup_handle_delayed (void *cls)
328{
329 cleanup_handle (cls);
330}
331
332
333/**
334 * Task run on error, sends error message. Cleans up everything.
335 *
336 * @param cls the `struct RequestHandle`
337 */
338static void
339do_error (void *cls)
340{
341 struct RequestHandle *handle = cls;
342 struct MHD_Response *resp;
343 char *json_error;
344
345 GNUNET_asprintf (&json_error, "{ \"error\" : \"%s\" }",
346 handle->emsg);
347 if ( 0 == handle->response_code )
348 {
349 handle->response_code = MHD_HTTP_BAD_REQUEST;
350 }
351 resp = GNUNET_REST_create_response (json_error);
352 MHD_add_response_header (resp, "Content-Type", "application/json");
353 handle->proc (handle->proc_cls, resp, handle->response_code);
354 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
355 GNUNET_free (json_error);
356}
357
358
359/**
360 * Task run on timeout, sends error message. Cleans up everything.
361 *
362 * @param cls the `struct RequestHandle`
363 */
364static void
365do_timeout (void *cls)
366{
367 struct RequestHandle *handle = cls;
368
369 handle->timeout_task = NULL;
370 do_error (handle);
371}
372
373
374static void
375collect_error_cb (void *cls)
376{
377 struct RequestHandle *handle = cls;
378
379 do_error (handle);
380}
381
382static void
383finished_cont (void *cls,
384 int32_t success,
385 const char *emsg)
386{
387 struct RequestHandle *handle = cls;
388 struct MHD_Response *resp;
389
390 resp = GNUNET_REST_create_response (emsg);
391 if (GNUNET_OK != success)
392 {
393 GNUNET_SCHEDULER_add_now (&do_error, handle);
394 return;
395 }
396 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
397 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
398}
399
400
401/**
402 * Return attributes for identity
403 *
404 * @param cls the request handle
405 */
406static void
407return_response (void *cls)
408{
409 char* result_str;
410 struct RequestHandle *handle = cls;
411 struct MHD_Response *resp;
412
413 GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str);
414 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
415 resp = GNUNET_REST_create_response (result_str);
416 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
417 GNUNET_free (result_str);
418 cleanup_handle (handle);
419}
420
421static void
422collect_finished_cb (void *cls)
423{
424 struct RequestHandle *handle = cls;
425 //Done
426 handle->attr_it = NULL;
427 handle->ticket_it = NULL;
428 GNUNET_SCHEDULER_add_now (&return_response, handle);
429}
430
431
432/**
433 * Collect all attributes for an ego
434 *
435 */
436static void
437ticket_collect (void *cls,
438 const struct GNUNET_RECLAIM_Ticket *ticket)
439{
440 struct GNUNET_JSONAPI_Resource *json_resource;
441 struct RequestHandle *handle = cls;
442 json_t *value;
443 char* tmp;
444
445 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding ticket\n");
446 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
447 sizeof (uint64_t));
448 json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_TICKET,
449 tmp);
450 GNUNET_free (tmp);
451 GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource);
452
453 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->identity,
454 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
455 value = json_string (tmp);
456 GNUNET_JSONAPI_resource_add_attr (json_resource,
457 "issuer",
458 value);
459 GNUNET_free (tmp);
460 json_decref (value);
461 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->audience,
462 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
463 value = json_string (tmp);
464 GNUNET_JSONAPI_resource_add_attr (json_resource,
465 "audience",
466 value);
467 GNUNET_free (tmp);
468 json_decref (value);
469 tmp = GNUNET_STRINGS_data_to_string_alloc (&ticket->rnd,
470 sizeof (uint64_t));
471 value = json_string (tmp);
472 GNUNET_JSONAPI_resource_add_attr (json_resource,
473 "rnd",
474 value);
475 GNUNET_free (tmp);
476 json_decref (value);
477 GNUNET_RECLAIM_ticket_iteration_next (handle->ticket_it);
478}
479
480
481
482/**
483 * List tickets for identity request
484 *
485 * @param con_handle the connection handle
486 * @param url the url
487 * @param cls the RequestHandle
488 */
489static void
490list_tickets_cont (struct GNUNET_REST_RequestHandle *con_handle,
491 const char* url,
492 void *cls)
493{
494 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
495 struct RequestHandle *handle = cls;
496 struct EgoEntry *ego_entry;
497 char *identity;
498
499 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting tickets for %s.\n",
500 handle->url);
501 if ( strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) >=
502 strlen (handle->url))
503 {
504 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
505 GNUNET_SCHEDULER_add_now (&do_error, handle);
506 return;
507 }
508 identity = handle->url + strlen (GNUNET_REST_API_NS_IDENTITY_TICKETS) + 1;
509
510 for (ego_entry = handle->ego_head;
511 NULL != ego_entry;
512 ego_entry = ego_entry->next)
513 if (0 == strcmp (identity, ego_entry->identifier))
514 break;
515 handle->resp_object = GNUNET_JSONAPI_document_new ();
516
517 if (NULL == ego_entry)
518 {
519 //Done
520 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n",
521 identity);
522 GNUNET_SCHEDULER_add_now (&return_response, handle);
523 return;
524 }
525 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
526 handle->idp = GNUNET_RECLAIM_connect (cfg);
527 handle->ticket_it = GNUNET_RECLAIM_ticket_iteration_start (handle->idp,
528 priv_key,
529 &collect_error_cb,
530 handle,
531 &ticket_collect,
532 handle,
533 &collect_finished_cb,
534 handle);
535}
536
537
538static void
539add_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
540 const char* url,
541 void *cls)
542{
543 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
544 const char* identity;
545 const char* name_str;
546 const char* value_str;
547 const char* exp_str;
548
549 struct RequestHandle *handle = cls;
550 struct EgoEntry *ego_entry;
551 struct MHD_Response *resp;
552 struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attribute;
553 struct GNUNET_JSONAPI_Document *json_obj;
554 struct GNUNET_JSONAPI_Resource *json_res;
555 struct GNUNET_TIME_Relative exp;
556 char term_data[handle->rest_handle->data_size+1];
557 json_t *value_json;
558 json_t *data_json;
559 json_t *exp_json;
560 json_error_t err;
561 struct GNUNET_JSON_Specification docspec[] = {
562 GNUNET_JSON_spec_jsonapi_document (&json_obj),
563 GNUNET_JSON_spec_end()
564 };
565
566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding an attribute for %s.\n",
567 handle->url);
568 if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >=
569 strlen (handle->url))
570 {
571 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
572 GNUNET_SCHEDULER_add_now (&do_error, handle);
573 return;
574 }
575 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
576
577 for (ego_entry = handle->ego_head;
578 NULL != ego_entry;
579 ego_entry = ego_entry->next)
580 if (0 == strcmp (identity, ego_entry->identifier))
581 break;
582
583 if (NULL == ego_entry)
584 {
585 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
586 "Identity unknown (%s)\n", identity);
587 GNUNET_JSONAPI_document_delete (json_obj);
588 return;
589 }
590 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
591
592 if (0 >= handle->rest_handle->data_size)
593 {
594 GNUNET_SCHEDULER_add_now (&do_error, handle);
595 return;
596 }
597
598 term_data[handle->rest_handle->data_size] = '\0';
599 GNUNET_memcpy (term_data,
600 handle->rest_handle->data,
601 handle->rest_handle->data_size);
602 data_json = json_loads (term_data,
603 JSON_DECODE_ANY,
604 &err);
605 GNUNET_assert (GNUNET_OK ==
606 GNUNET_JSON_parse (data_json, docspec,
607 NULL, NULL));
608 json_decref (data_json);
609 if (NULL == json_obj)
610 {
611 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
612 "Unable to parse JSONAPI Object from %s\n",
613 term_data);
614 GNUNET_SCHEDULER_add_now (&do_error, handle);
615 return;
616 }
617 if (1 != GNUNET_JSONAPI_document_resource_count (json_obj))
618 {
619 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
620 "Cannot create more than 1 resource! (Got %d)\n",
621 GNUNET_JSONAPI_document_resource_count (json_obj));
622 GNUNET_JSONAPI_document_delete (json_obj);
623 GNUNET_SCHEDULER_add_now (&do_error, handle);
624 return;
625 }
626 json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0);
627 if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res,
628 GNUNET_REST_JSONAPI_RECLAIM_ATTRIBUTE))
629 {
630 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
631 "Unsupported JSON data type\n");
632 GNUNET_JSONAPI_document_delete (json_obj);
633 resp = GNUNET_REST_create_response (NULL);
634 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
635 cleanup_handle (handle);
636 return;
637 }
638 name_str = GNUNET_JSONAPI_resource_get_id (json_res);
639 exp_json = GNUNET_JSONAPI_resource_read_attr (json_res,
640 "exp");
641 exp_str = json_string_value (exp_json);
642 if (NULL == exp_str) {
643 exp = GNUNET_TIME_UNIT_HOURS;
644 } else {
645 if (GNUNET_OK != GNUNET_STRINGS_fancy_time_to_relative (exp_str,
646 &exp)) {
647 exp = GNUNET_TIME_UNIT_HOURS;
648 }
649 }
650
651 value_json = GNUNET_JSONAPI_resource_read_attr (json_res,
652 "value");
653 value_str = json_string_value (value_json);
654 attribute = GNUNET_RECLAIM_ATTRIBUTE_claim_new (name_str,
655 GNUNET_RECLAIM_ATTRIBUTE_TYPE_STRING,
656 value_str,
657 strlen (value_str) + 1);
658 handle->idp = GNUNET_RECLAIM_connect (cfg);
659 handle->idp_op = GNUNET_RECLAIM_attribute_store (handle->idp,
660 identity_priv,
661 attribute,
662 &exp,
663 &finished_cont,
664 handle);
665 GNUNET_free (attribute);
666 GNUNET_JSONAPI_document_delete (json_obj);
667}
668
669
670
671/**
672 * Collect all attributes for an ego
673 *
674 */
675static void
676attr_collect (void *cls,
677 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
678 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
679{
680 struct GNUNET_JSONAPI_Resource *json_resource;
681 struct RequestHandle *handle = cls;
682 json_t *value;
683 char* tmp_value;
684
685 if ((NULL == attr->name) || (NULL == attr->data))
686 {
687 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
688 return;
689 }
690
691 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n",
692 attr->name);
693 json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_RECLAIM_ATTRIBUTE,
694 attr->name);
695 GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource);
696
697 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type,
698 attr->data,
699 attr->data_size);
700
701 value = json_string (tmp_value);
702
703 GNUNET_JSONAPI_resource_add_attr (json_resource,
704 "value",
705 value);
706 json_decref (value);
707 GNUNET_free(tmp_value);
708 GNUNET_RECLAIM_get_attributes_next (handle->attr_it);
709}
710
711
712
713/**
714 * List attributes for identity request
715 *
716 * @param con_handle the connection handle
717 * @param url the url
718 * @param cls the RequestHandle
719 */
720static void
721list_attribute_cont (struct GNUNET_REST_RequestHandle *con_handle,
722 const char* url,
723 void *cls)
724{
725 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
726 struct RequestHandle *handle = cls;
727 struct EgoEntry *ego_entry;
728 char *identity;
729
730 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting attributes for %s.\n",
731 handle->url);
732 if ( strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) >=
733 strlen (handle->url))
734 {
735 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No identity given.\n");
736 GNUNET_SCHEDULER_add_now (&do_error, handle);
737 return;
738 }
739 identity = handle->url + strlen (GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES) + 1;
740
741 for (ego_entry = handle->ego_head;
742 NULL != ego_entry;
743 ego_entry = ego_entry->next)
744 if (0 == strcmp (identity, ego_entry->identifier))
745 break;
746 handle->resp_object = GNUNET_JSONAPI_document_new ();
747
748
749 if (NULL == ego_entry)
750 {
751 //Done
752 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ego %s not found.\n",
753 identity);
754 GNUNET_SCHEDULER_add_now (&return_response, handle);
755 return;
756 }
757 priv_key = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
758 handle->idp = GNUNET_RECLAIM_connect (cfg);
759 handle->attr_it = GNUNET_RECLAIM_get_attributes_start (handle->idp,
760 priv_key,
761 &collect_error_cb,
762 handle,
763 &attr_collect,
764 handle,
765 &collect_finished_cb,
766 handle);
767}
768
769
770static void
771revoke_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
772 const char* url,
773 void *cls)
774{
775 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
776 const char* identity_str;
777 const char* audience_str;
778 const char* rnd_str;
779
780 struct RequestHandle *handle = cls;
781 struct EgoEntry *ego_entry;
782 struct MHD_Response *resp;
783 struct GNUNET_RECLAIM_Ticket ticket;
784 struct GNUNET_JSONAPI_Document *json_obj;
785 struct GNUNET_JSONAPI_Resource *json_res;
786 struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
787 char term_data[handle->rest_handle->data_size+1];
788 json_t *rnd_json;
789 json_t *identity_json;
790 json_t *audience_json;
791 json_t *data_json;
792 json_error_t err;
793 struct GNUNET_JSON_Specification docspec[] = {
794 GNUNET_JSON_spec_jsonapi_document (&json_obj),
795 GNUNET_JSON_spec_end()
796 };
797
798 if (0 >= handle->rest_handle->data_size)
799 {
800 GNUNET_SCHEDULER_add_now (&do_error, handle);
801 return;
802 }
803
804 term_data[handle->rest_handle->data_size] = '\0';
805 GNUNET_memcpy (term_data,
806 handle->rest_handle->data,
807 handle->rest_handle->data_size);
808 data_json = json_loads (term_data,
809 JSON_DECODE_ANY,
810 &err);
811 GNUNET_assert (GNUNET_OK ==
812 GNUNET_JSON_parse (data_json, docspec,
813 NULL, NULL));
814 json_decref (data_json);
815 if (NULL == json_obj)
816 {
817 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
818 "Unable to parse JSONAPI Object from %s\n",
819 term_data);
820 GNUNET_SCHEDULER_add_now (&do_error, handle);
821 return;
822 }
823 if (1 != GNUNET_JSONAPI_document_resource_count (json_obj))
824 {
825 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
826 "Cannot create more than 1 resource! (Got %d)\n",
827 GNUNET_JSONAPI_document_resource_count (json_obj));
828 GNUNET_JSONAPI_document_delete (json_obj);
829 GNUNET_SCHEDULER_add_now (&do_error, handle);
830 return;
831 }
832 json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0);
833 if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res,
834 GNUNET_REST_JSONAPI_IDENTITY_TICKET))
835 {
836 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
837 "Unsupported JSON data type\n");
838 GNUNET_JSONAPI_document_delete (json_obj);
839 resp = GNUNET_REST_create_response (NULL);
840 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
841 cleanup_handle (handle);
842 return;
843 }
844 rnd_json = GNUNET_JSONAPI_resource_read_attr (json_res,
845 "rnd");
846 identity_json = GNUNET_JSONAPI_resource_read_attr (json_res,
847 "issuer");
848 audience_json = GNUNET_JSONAPI_resource_read_attr (json_res,
849 "audience");
850 rnd_str = json_string_value (rnd_json);
851 identity_str = json_string_value (identity_json);
852 audience_str = json_string_value (audience_json);
853
854 GNUNET_STRINGS_string_to_data (rnd_str,
855 strlen (rnd_str),
856 &ticket.rnd,
857 sizeof (uint64_t));
858 GNUNET_STRINGS_string_to_data (identity_str,
859 strlen (identity_str),
860 &ticket.identity,
861 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
862 GNUNET_STRINGS_string_to_data (audience_str,
863 strlen (audience_str),
864 &ticket.audience,
865 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
866
867 for (ego_entry = handle->ego_head;
868 NULL != ego_entry;
869 ego_entry = ego_entry->next)
870 {
871 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
872 &tmp_pk);
873 if (0 == memcmp (&ticket.identity,
874 &tmp_pk,
875 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
876 break;
877 }
878 if (NULL == ego_entry)
879 {
880 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
881 "Identity unknown (%s)\n", identity_str);
882 GNUNET_JSONAPI_document_delete (json_obj);
883 return;
884 }
885 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
886
887 handle->idp = GNUNET_RECLAIM_connect (cfg);
888 handle->idp_op = GNUNET_RECLAIM_ticket_revoke (handle->idp,
889 identity_priv,
890 &ticket,
891 &finished_cont,
892 handle);
893 GNUNET_JSONAPI_document_delete (json_obj);
894}
895
896static void
897consume_cont (void *cls,
898 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
899 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
900{
901 struct RequestHandle *handle = cls;
902 struct GNUNET_JSONAPI_Resource *json_resource;
903 json_t *value;
904
905 if (NULL == identity)
906 {
907 GNUNET_SCHEDULER_add_now (&return_response, handle);
908 return;
909 }
910
911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Adding attribute: %s\n",
912 attr->name);
913 json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_RECLAIM_ATTRIBUTE,
914 attr->name);
915 GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource);
916
917 value = json_string (attr->data);
918 GNUNET_JSONAPI_resource_add_attr (json_resource,
919 "value",
920 value);
921 json_decref (value);
922}
923
924static void
925consume_ticket_cont (struct GNUNET_REST_RequestHandle *con_handle,
926 const char* url,
927 void *cls)
928{
929 const struct GNUNET_CRYPTO_EcdsaPrivateKey *identity_priv;
930 const char* identity_str;
931 const char* audience_str;
932 const char* rnd_str;
933
934 struct RequestHandle *handle = cls;
935 struct EgoEntry *ego_entry;
936 struct MHD_Response *resp;
937 struct GNUNET_RECLAIM_Ticket ticket;
938 struct GNUNET_JSONAPI_Document *json_obj;
939 struct GNUNET_JSONAPI_Resource *json_res;
940 struct GNUNET_CRYPTO_EcdsaPublicKey tmp_pk;
941 char term_data[handle->rest_handle->data_size+1];
942 json_t *rnd_json;
943 json_t *identity_json;
944 json_t *audience_json;
945 json_t *data_json;
946 json_error_t err;
947 struct GNUNET_JSON_Specification docspec[] = {
948 GNUNET_JSON_spec_jsonapi_document (&json_obj),
949 GNUNET_JSON_spec_end()
950 };
951
952 if (0 >= handle->rest_handle->data_size)
953 {
954 GNUNET_SCHEDULER_add_now (&do_error, handle);
955 return;
956 }
957
958 term_data[handle->rest_handle->data_size] = '\0';
959 GNUNET_memcpy (term_data,
960 handle->rest_handle->data,
961 handle->rest_handle->data_size);
962 data_json = json_loads (term_data,
963 JSON_DECODE_ANY,
964 &err);
965 GNUNET_assert (GNUNET_OK ==
966 GNUNET_JSON_parse (data_json, docspec,
967 NULL, NULL));
968 json_decref (data_json);
969 if (NULL == json_obj)
970 {
971 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
972 "Unable to parse JSONAPI Object from %s\n",
973 term_data);
974 GNUNET_SCHEDULER_add_now (&do_error, handle);
975 return;
976 }
977 if (1 != GNUNET_JSONAPI_document_resource_count (json_obj))
978 {
979 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
980 "Cannot create more than 1 resource! (Got %d)\n",
981 GNUNET_JSONAPI_document_resource_count (json_obj));
982 GNUNET_JSONAPI_document_delete (json_obj);
983 GNUNET_SCHEDULER_add_now (&do_error, handle);
984 return;
985 }
986 json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0);
987 if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res,
988 GNUNET_REST_JSONAPI_IDENTITY_TICKET))
989 {
990 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
991 "Unsupported JSON data type\n");
992 GNUNET_JSONAPI_document_delete (json_obj);
993 resp = GNUNET_REST_create_response (NULL);
994 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
995 cleanup_handle (handle);
996 return;
997 }
998 rnd_json = GNUNET_JSONAPI_resource_read_attr (json_res,
999 "rnd");
1000 identity_json = GNUNET_JSONAPI_resource_read_attr (json_res,
1001 "identity");
1002 audience_json = GNUNET_JSONAPI_resource_read_attr (json_res,
1003 "audience");
1004 rnd_str = json_string_value (rnd_json);
1005 identity_str = json_string_value (identity_json);
1006 audience_str = json_string_value (audience_json);
1007
1008 GNUNET_STRINGS_string_to_data (rnd_str,
1009 strlen (rnd_str),
1010 &ticket.rnd,
1011 sizeof (uint64_t));
1012 GNUNET_STRINGS_string_to_data (identity_str,
1013 strlen (identity_str),
1014 &ticket.identity,
1015 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1016 GNUNET_STRINGS_string_to_data (audience_str,
1017 strlen (audience_str),
1018 &ticket.audience,
1019 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
1020
1021 for (ego_entry = handle->ego_head;
1022 NULL != ego_entry;
1023 ego_entry = ego_entry->next)
1024 {
1025 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego,
1026 &tmp_pk);
1027 if (0 == memcmp (&ticket.audience,
1028 &tmp_pk,
1029 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)))
1030 break;
1031 }
1032 if (NULL == ego_entry)
1033 {
1034 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1035 "Identity unknown (%s)\n", identity_str);
1036 GNUNET_JSONAPI_document_delete (json_obj);
1037 return;
1038 }
1039 identity_priv = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego);
1040 handle->resp_object = GNUNET_JSONAPI_document_new ();
1041 handle->idp = GNUNET_RECLAIM_connect (cfg);
1042 handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp,
1043 identity_priv,
1044 &ticket,
1045 &consume_cont,
1046 handle);
1047 GNUNET_JSONAPI_document_delete (json_obj);
1048}
1049
1050
1051
1052/**
1053 * Respond to OPTIONS request
1054 *
1055 * @param con_handle the connection handle
1056 * @param url the url
1057 * @param cls the RequestHandle
1058 */
1059static void
1060options_cont (struct GNUNET_REST_RequestHandle *con_handle,
1061 const char* url,
1062 void *cls)
1063{
1064 struct MHD_Response *resp;
1065 struct RequestHandle *handle = cls;
1066
1067 //For now, independent of path return all options
1068 resp = GNUNET_REST_create_response (NULL);
1069 MHD_add_response_header (resp,
1070 "Access-Control-Allow-Methods",
1071 allow_methods);
1072 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
1073 cleanup_handle (handle);
1074 return;
1075}
1076
1077/**
1078 * Handle rest request
1079 *
1080 * @param handle the request handle
1081 */
1082static void
1083init_cont (struct RequestHandle *handle)
1084{
1085 struct GNUNET_REST_RequestHandlerError err;
1086 static const struct GNUNET_REST_RequestHandler handlers[] = {
1087 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &list_attribute_cont},
1088 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_RECLAIM_ATTRIBUTES, &add_attribute_cont},
1089 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont},
1090 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont},
1091 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont},
1092 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_RECLAIM,
1093 &options_cont},
1094 GNUNET_REST_HANDLER_END
1095 };
1096
1097 if (GNUNET_NO == GNUNET_REST_handle_request (handle->rest_handle,
1098 handlers,
1099 &err,
1100 handle))
1101 {
1102 handle->response_code = err.error_code;
1103 GNUNET_SCHEDULER_add_now (&do_error, handle);
1104 }
1105}
1106
1107/**
1108 * If listing is enabled, prints information about the egos.
1109 *
1110 * This function is initially called for all egos and then again
1111 * whenever a ego's identifier changes or if it is deleted. At the
1112 * end of the initial pass over all egos, the function is once called
1113 * with 'NULL' for 'ego'. That does NOT mean that the callback won't
1114 * be invoked in the future or that there was an error.
1115 *
1116 * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get',
1117 * this function is only called ONCE, and 'NULL' being passed in
1118 * 'ego' does indicate an error (i.e. name is taken or no default
1119 * value is known). If 'ego' is non-NULL and if '*ctx'
1120 * is set in those callbacks, the value WILL be passed to a subsequent
1121 * call to the identity callback of 'GNUNET_IDENTITY_connect' (if
1122 * that one was not NULL).
1123 *
1124 * When an identity is renamed, this function is called with the
1125 * (known) ego but the NEW identifier.
1126 *
1127 * When an identity is deleted, this function is called with the
1128 * (known) ego and "NULL" for the 'identifier'. In this case,
1129 * the 'ego' is henceforth invalid (and the 'ctx' should also be
1130 * cleaned up).
1131 *
1132 * @param cls closure
1133 * @param ego ego handle
1134 * @param ctx context for application to store data for this ego
1135 * (during the lifetime of this process, initially NULL)
1136 * @param identifier identifier assigned by the user for this ego,
1137 * NULL if the user just deleted the ego and it
1138 * must thus no longer be used
1139 */
1140static void
1141list_ego (void *cls,
1142 struct GNUNET_IDENTITY_Ego *ego,
1143 void **ctx,
1144 const char *identifier)
1145{
1146 struct RequestHandle *handle = cls;
1147 struct EgoEntry *ego_entry;
1148 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
1149
1150 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
1151 {
1152 handle->state = ID_REST_STATE_POST_INIT;
1153 init_cont (handle);
1154 return;
1155 }
1156 if (ID_REST_STATE_INIT == handle->state) {
1157 ego_entry = GNUNET_new (struct EgoEntry);
1158 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
1159 ego_entry->keystring =
1160 GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
1161 ego_entry->ego = ego;
1162 ego_entry->identifier = GNUNET_strdup (identifier);
1163 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry);
1164 }
1165
1166}
1167
1168static void
1169rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
1170 GNUNET_REST_ResultProcessor proc,
1171 void *proc_cls)
1172{
1173 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
1174 handle->response_code = 0;
1175 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
1176 handle->proc_cls = proc_cls;
1177 handle->proc = proc;
1178 handle->state = ID_REST_STATE_INIT;
1179 handle->rest_handle = rest_handle;
1180
1181 handle->url = GNUNET_strdup (rest_handle->url);
1182 if (handle->url[strlen (handle->url)-1] == '/')
1183 handle->url[strlen (handle->url)-1] = '\0';
1184 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1185 "Connecting...\n");
1186 handle->identity_handle = GNUNET_IDENTITY_connect (cfg,
1187 &list_ego,
1188 handle);
1189 handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg);
1190 handle->timeout_task =
1191 GNUNET_SCHEDULER_add_delayed (handle->timeout,
1192 &do_timeout,
1193 handle);
1194 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1195 "Connected\n");
1196}
1197
1198/**
1199 * Entry point for the plugin.
1200 *
1201 * @param cls Config info
1202 * @return NULL on error, otherwise the plugin context
1203 */
1204void *
1205libgnunet_plugin_rest_reclaim_init (void *cls)
1206{
1207 static struct Plugin plugin;
1208 struct GNUNET_REST_Plugin *api;
1209
1210 cfg = cls;
1211 if (NULL != plugin.cfg)
1212 return NULL; /* can only initialize once! */
1213 memset (&plugin, 0, sizeof (struct Plugin));
1214 plugin.cfg = cfg;
1215 api = GNUNET_new (struct GNUNET_REST_Plugin);
1216 api->cls = &plugin;
1217 api->name = GNUNET_REST_API_NS_RECLAIM;
1218 api->process_request = &rest_identity_process_request;
1219 GNUNET_asprintf (&allow_methods,
1220 "%s, %s, %s, %s, %s",
1221 MHD_HTTP_METHOD_GET,
1222 MHD_HTTP_METHOD_POST,
1223 MHD_HTTP_METHOD_PUT,
1224 MHD_HTTP_METHOD_DELETE,
1225 MHD_HTTP_METHOD_OPTIONS);
1226
1227 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1228 _("Identity Provider REST API initialized\n"));
1229 return api;
1230}
1231
1232
1233/**
1234 * Exit point from the plugin.
1235 *
1236 * @param cls the plugin context (as returned by "init")
1237 * @return always NULL
1238 */
1239void *
1240libgnunet_plugin_rest_reclaim_done (void *cls)
1241{
1242 struct GNUNET_REST_Plugin *api = cls;
1243 struct Plugin *plugin = api->cls;
1244 plugin->cfg = NULL;
1245
1246 GNUNET_free_non_null (allow_methods);
1247 GNUNET_free (api);
1248 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1249 "Identity Provider REST plugin is finished\n");
1250 return NULL;
1251}
1252
1253/* end of plugin_rest_reclaim.c */
diff --git a/src/jsonapi/test_jsonapi.c b/src/jsonapi/test_jsonapi.c
deleted file mode 100644
index 59d0bed76..000000000
--- a/src/jsonapi/test_jsonapi.c
+++ /dev/null
@@ -1,190 +0,0 @@
1/*
2 This file is part of GNUnet
3 (C) 2015, 2016 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * @file json/test_jsonapi.c
21 * @brief Tests for jsonapi conversion functions
22 * @author Martin Schanzenbach
23 */
24#include "platform.h"
25#include "gnunet_util_lib.h"
26#include "gnunet_jsonapi_lib.h"
27#include "gnunet_json_lib.h"
28
29#define TEST_JSONAPI_DOCUMENT "{\"data\":[{\"id\":\"1\",\"type\":\"bar\",\"attributes\":{\"foo\":\"bar\"}}]}"
30
31#define TEST_JSONAPI_DOCUMENT_ERR "{\"errors\":[{\"id\":\"1\",\"status\":\"403\",\"code\":\"23\", \"title\":\"Error\", \"detail\":\"Error details\"}]}"
32
33static int
34test_document_error ()
35{
36 struct GNUNET_JSONAPI_Document *obj;
37 struct GNUNET_JSONAPI_Error *error;
38 json_t *doc_json;
39 json_t *data_js;
40 json_error_t err;
41
42 obj = GNUNET_JSONAPI_document_new ();
43 error = GNUNET_JSONAPI_error_new ("1",
44 "403",
45 "23",
46 "Error",
47 "Error details",
48 NULL,
49 NULL,
50 NULL);
51
52
53 GNUNET_JSONAPI_document_error_add (obj,
54 error);
55
56 GNUNET_assert (GNUNET_OK ==
57 GNUNET_JSONAPI_document_to_json (obj,
58 &doc_json));
59 data_js = json_loads (TEST_JSONAPI_DOCUMENT_ERR,
60 JSON_DECODE_ANY,
61 &err);
62 GNUNET_assert (NULL != data_js);
63 GNUNET_assert (0 != json_equal (data_js, doc_json));
64 GNUNET_JSONAPI_document_delete (obj);
65 json_decref (data_js);
66 json_decref (doc_json);
67 return 0;
68}
69
70
71static int
72test_document ()
73{
74 struct GNUNET_JSONAPI_Document *obj;
75 struct GNUNET_JSONAPI_Resource *res;
76 json_t *doc_json;
77 json_t *data_js;
78 json_error_t err;
79 int ret;
80
81 obj = GNUNET_JSONAPI_document_new ();
82 res = GNUNET_JSONAPI_resource_new ("bar",
83 "1");
84
85 GNUNET_assert (GNUNET_OK ==
86 GNUNET_JSONAPI_resource_add_attr (res,
87 "foo",
88 json_string ("bar")));
89
90 GNUNET_JSONAPI_document_resource_add (obj,
91 res);
92
93 GNUNET_assert (GNUNET_OK ==
94 GNUNET_JSONAPI_document_to_json (obj,
95 &doc_json));
96 data_js = json_loads (TEST_JSONAPI_DOCUMENT,
97 JSON_DECODE_ANY,
98 &err);
99 GNUNET_assert (NULL != data_js);
100 ret = json_equal (data_js, doc_json) ? 0 : 1;
101 GNUNET_JSONAPI_document_delete (obj);
102 json_decref (data_js);
103 json_decref (doc_json);
104 return ret;
105}
106
107static int
108test_serialize ()
109{
110 struct GNUNET_JSONAPI_Document *obj;
111 char* tmp_data;
112 int ret;
113 json_t* data_js;
114 json_t* tmp_data_js;
115 json_error_t err;
116 struct GNUNET_JSON_Specification jsonapispec[] = {
117 GNUNET_JSON_spec_jsonapi_document (&obj),
118 GNUNET_JSON_spec_end()
119 };
120 data_js = json_loads (TEST_JSONAPI_DOCUMENT,
121 JSON_DECODE_ANY,
122 &err);
123 GNUNET_assert (NULL != data_js);
124 GNUNET_assert (GNUNET_OK ==
125 GNUNET_JSON_parse (data_js, jsonapispec,
126 NULL, NULL));
127 GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_document_serialize (obj,
128 &tmp_data));
129 GNUNET_JSON_parse_free (jsonapispec);
130 tmp_data_js = json_loads (tmp_data, JSON_DECODE_ANY, &err);
131 GNUNET_assert (NULL != tmp_data_js);
132 ret = (1 == json_equal (tmp_data_js, data_js)) ? 0 : 1;
133 json_decref (data_js);
134 json_decref (tmp_data_js);
135 GNUNET_free (tmp_data);
136 return ret;
137}
138
139/**
140 * Test rsa conversions from/to JSON.
141 *
142 * @return 0 on success
143 */
144static int
145test_spec_jsonapi ()
146{
147 struct GNUNET_JSONAPI_Document *obj;
148 struct GNUNET_JSONAPI_Resource *res;
149 const char* data = "{\"data\":{\"id\":\"1\", \"type\":\"test\"}}";
150 json_t* data_js;
151 json_error_t err;
152
153 struct GNUNET_JSON_Specification jsonapispec[] = {
154 GNUNET_JSON_spec_jsonapi_document (&obj),
155 GNUNET_JSON_spec_end()
156 };
157 data_js = json_loads (data, JSON_DECODE_ANY, &err);
158 GNUNET_assert (NULL != data_js);
159 GNUNET_assert (GNUNET_OK ==
160 GNUNET_JSON_parse (data_js, jsonapispec,
161 NULL, NULL));
162 json_decref (data_js);
163 res = GNUNET_JSONAPI_document_get_resource (obj, 0);
164 GNUNET_assert (GNUNET_YES == GNUNET_JSONAPI_resource_check_id (res, "1"));
165 GNUNET_assert (GNUNET_YES == GNUNET_JSONAPI_resource_check_type (res, "test"));
166 GNUNET_assert (1 == GNUNET_JSONAPI_document_resource_count (obj));
167 GNUNET_JSON_parse_free (jsonapispec);
168 return 0;
169}
170
171
172int
173main(int argc,
174 const char *const argv[])
175{
176 GNUNET_log_setup ("test-jsonapi",
177 "WARNING",
178 NULL);
179 if (0 != test_spec_jsonapi ())
180 return 1;
181 if (0 != test_serialize ())
182 return 1;
183 if (0 != test_document ())
184 return 1;
185 if (0 != test_document_error ())
186 return 1;
187 return 0;
188}
189
190/* end of test_json.c */