diff options
Diffstat (limited to 'src/identity')
-rw-r--r-- | src/identity/Makefile.am | 19 | ||||
-rw-r--r-- | src/identity/gnunet-service-identity.c | 2 | ||||
-rw-r--r-- | src/identity/plugin_rest_identity.c | 1059 | ||||
-rwxr-xr-x | src/identity/test_plugin_rest_identity.sh | 159 |
4 files changed, 1 insertions, 1238 deletions
diff --git a/src/identity/Makefile.am b/src/identity/Makefile.am index e7104f0c3..1f21fc65d 100644 --- a/src/identity/Makefile.am +++ b/src/identity/Makefile.am | |||
@@ -39,14 +39,6 @@ bin_PROGRAMS = \ | |||
39 | libexec_PROGRAMS = \ | 39 | libexec_PROGRAMS = \ |
40 | gnunet-service-identity | 40 | gnunet-service-identity |
41 | 41 | ||
42 | if HAVE_MHD | ||
43 | if HAVE_JSON | ||
44 | plugin_LTLIBRARIES = \ | ||
45 | libgnunet_plugin_rest_identity.la | ||
46 | endif | ||
47 | endif | ||
48 | |||
49 | |||
50 | gnunet_service_identity_SOURCES = \ | 42 | gnunet_service_identity_SOURCES = \ |
51 | gnunet-service-identity.c | 43 | gnunet-service-identity.c |
52 | gnunet_service_identity_LDADD = \ | 44 | gnunet_service_identity_LDADD = \ |
@@ -55,17 +47,6 @@ gnunet_service_identity_LDADD = \ | |||
55 | $(GN_LIBINTL) | 47 | $(GN_LIBINTL) |
56 | 48 | ||
57 | 49 | ||
58 | libgnunet_plugin_rest_identity_la_SOURCES = \ | ||
59 | plugin_rest_identity.c | ||
60 | libgnunet_plugin_rest_identity_la_LIBADD = \ | ||
61 | libgnunetidentity.la \ | ||
62 | $(top_builddir)/src/rest/libgnunetrest.la \ | ||
63 | $(top_builddir)/src/util/libgnunetutil.la $(XLIBS) \ | ||
64 | $(LTLIBINTL) -ljansson -lmicrohttpd | ||
65 | libgnunet_plugin_rest_identity_la_LDFLAGS = \ | ||
66 | $(GN_PLUGIN_LDFLAGS) | ||
67 | |||
68 | |||
69 | gnunet_identity_SOURCES = \ | 50 | gnunet_identity_SOURCES = \ |
70 | gnunet-identity.c | 51 | gnunet-identity.c |
71 | gnunet_identity_LDADD = \ | 52 | gnunet_identity_LDADD = \ |
diff --git a/src/identity/gnunet-service-identity.c b/src/identity/gnunet-service-identity.c index 266f5ccc3..155c49cc5 100644 --- a/src/identity/gnunet-service-identity.c +++ b/src/identity/gnunet-service-identity.c | |||
@@ -752,7 +752,7 @@ handle_rename_message (void *cls, | |||
752 | old_name = GNUNET_strdup (old_name_tmp); | 752 | old_name = GNUNET_strdup (old_name_tmp); |
753 | GNUNET_STRINGS_utf8_tolower (old_name_tmp, old_name); | 753 | GNUNET_STRINGS_utf8_tolower (old_name_tmp, old_name); |
754 | new_name = GNUNET_strdup (&old_name_tmp[old_name_len]); | 754 | new_name = GNUNET_strdup (&old_name_tmp[old_name_len]); |
755 | GNUNET_STRINGS_utf8_tolower (&old_name_tmp[old_name_len], old_name); | 755 | GNUNET_STRINGS_utf8_tolower (&old_name_tmp[old_name_len], new_name); |
756 | 756 | ||
757 | /* check if new name is already in use */ | 757 | /* check if new name is already in use */ |
758 | for (ego = ego_head; NULL != ego; ego = ego->next) | 758 | for (ego = ego_head; NULL != ego; ego = ego->next) |
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c deleted file mode 100644 index a518a74cc..000000000 --- a/src/identity/plugin_rest_identity.c +++ /dev/null | |||
@@ -1,1059 +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 identity/plugin_rest_identity.c | ||
22 | * @brief GNUnet Identity REST plugin | ||
23 | */ | ||
24 | |||
25 | #include "platform.h" | ||
26 | #include "gnunet_rest_plugin.h" | ||
27 | #include "gnunet_identity_service.h" | ||
28 | #include "gnunet_rest_lib.h" | ||
29 | #include "microhttpd.h" | ||
30 | #include <jansson.h> | ||
31 | |||
32 | #define GNUNET_REST_API_NS_IDENTITY "/identity" | ||
33 | |||
34 | /** | ||
35 | * Parameter names | ||
36 | */ | ||
37 | #define GNUNET_REST_PARAM_PUBKEY "pubkey" | ||
38 | #define GNUNET_REST_PARAM_SUBSYSTEM "subsystem" | ||
39 | #define GNUNET_REST_PARAM_NAME "name" | ||
40 | #define GNUNET_REST_PARAM_NEWNAME "newname" | ||
41 | |||
42 | /** | ||
43 | * Error messages | ||
44 | */ | ||
45 | #define GNUNET_REST_IDENTITY_ERROR_UNKNOWN "Unknown Error" | ||
46 | #define GNUNET_REST_ERROR_RESOURCE_INVALID "Resource location invalid" | ||
47 | #define GNUNET_REST_ERROR_NO_DATA "No data" | ||
48 | #define GNUNET_REST_ERROR_DATA_INVALID "Data invalid" | ||
49 | |||
50 | /** | ||
51 | * State while collecting all egos | ||
52 | */ | ||
53 | #define ID_REST_STATE_INIT 0 | ||
54 | |||
55 | /** | ||
56 | * Done collecting egos | ||
57 | */ | ||
58 | #define ID_REST_STATE_POST_INIT 1 | ||
59 | |||
60 | /** | ||
61 | * The configuration handle | ||
62 | */ | ||
63 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
64 | |||
65 | /** | ||
66 | * HTTP methods allows for this plugin | ||
67 | */ | ||
68 | static char* allow_methods; | ||
69 | |||
70 | /** | ||
71 | * @brief struct returned by the initialization function of the plugin | ||
72 | */ | ||
73 | struct Plugin | ||
74 | { | ||
75 | const struct GNUNET_CONFIGURATION_Handle *cfg; | ||
76 | }; | ||
77 | |||
78 | /** | ||
79 | * The ego list | ||
80 | */ | ||
81 | struct EgoEntry | ||
82 | { | ||
83 | /** | ||
84 | * DLL | ||
85 | */ | ||
86 | struct EgoEntry *next; | ||
87 | |||
88 | /** | ||
89 | * DLL | ||
90 | */ | ||
91 | struct EgoEntry *prev; | ||
92 | |||
93 | /** | ||
94 | * Ego Identifier | ||
95 | */ | ||
96 | char *identifier; | ||
97 | |||
98 | /** | ||
99 | * Public key string | ||
100 | */ | ||
101 | char *keystring; | ||
102 | |||
103 | /** | ||
104 | * The Ego | ||
105 | */ | ||
106 | struct GNUNET_IDENTITY_Ego *ego; | ||
107 | }; | ||
108 | |||
109 | struct RequestHandle | ||
110 | { | ||
111 | /** | ||
112 | * The data from the REST request | ||
113 | */ | ||
114 | const char* data; | ||
115 | |||
116 | /** | ||
117 | * The name to look up | ||
118 | */ | ||
119 | char *name; | ||
120 | |||
121 | /** | ||
122 | * the length of the REST data | ||
123 | */ | ||
124 | size_t data_size; | ||
125 | |||
126 | /** | ||
127 | * Requested Subsystem | ||
128 | */ | ||
129 | char *subsystem; | ||
130 | |||
131 | /** | ||
132 | * Ego list | ||
133 | */ | ||
134 | struct EgoEntry *ego_head; | ||
135 | |||
136 | /** | ||
137 | * Ego list | ||
138 | */ | ||
139 | struct EgoEntry *ego_tail; | ||
140 | |||
141 | /** | ||
142 | * The processing state | ||
143 | */ | ||
144 | int state; | ||
145 | |||
146 | /** | ||
147 | * Handle to Identity service. | ||
148 | */ | ||
149 | struct GNUNET_IDENTITY_Handle *identity_handle; | ||
150 | |||
151 | /** | ||
152 | * IDENTITY Operation | ||
153 | */ | ||
154 | struct GNUNET_IDENTITY_Operation *op; | ||
155 | |||
156 | /** | ||
157 | * Rest connection | ||
158 | */ | ||
159 | struct GNUNET_REST_RequestHandle *rest_handle; | ||
160 | |||
161 | /** | ||
162 | * Desired timeout for the lookup (default is no timeout). | ||
163 | */ | ||
164 | struct GNUNET_TIME_Relative timeout; | ||
165 | |||
166 | /** | ||
167 | * ID of a task associated with the resolution process. | ||
168 | */ | ||
169 | struct GNUNET_SCHEDULER_Task *timeout_task; | ||
170 | |||
171 | /** | ||
172 | * The plugin result processor | ||
173 | */ | ||
174 | GNUNET_REST_ResultProcessor proc; | ||
175 | |||
176 | /** | ||
177 | * The closure of the result processor | ||
178 | */ | ||
179 | void *proc_cls; | ||
180 | |||
181 | /** | ||
182 | * The url | ||
183 | */ | ||
184 | char *url; | ||
185 | |||
186 | /** | ||
187 | * Error response message | ||
188 | */ | ||
189 | char *emsg; | ||
190 | |||
191 | /** | ||
192 | * Reponse code | ||
193 | */ | ||
194 | int response_code; | ||
195 | |||
196 | }; | ||
197 | |||
198 | /** | ||
199 | * Cleanup lookup handle | ||
200 | * @param handle Handle to clean up | ||
201 | */ | ||
202 | static void | ||
203 | cleanup_handle (void *cls) | ||
204 | { | ||
205 | struct RequestHandle *handle = cls; | ||
206 | struct EgoEntry *ego_entry; | ||
207 | struct EgoEntry *ego_tmp; | ||
208 | |||
209 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); | ||
210 | if (NULL != handle->timeout_task) | ||
211 | { | ||
212 | GNUNET_SCHEDULER_cancel (handle->timeout_task); | ||
213 | handle->timeout_task = NULL; | ||
214 | } | ||
215 | |||
216 | if (NULL != handle->subsystem) | ||
217 | GNUNET_free(handle->subsystem); | ||
218 | if (NULL != handle->url) | ||
219 | GNUNET_free(handle->url); | ||
220 | if (NULL != handle->emsg) | ||
221 | GNUNET_free(handle->emsg); | ||
222 | if (NULL != handle->name) | ||
223 | GNUNET_free (handle->name); | ||
224 | if (NULL != handle->identity_handle) | ||
225 | GNUNET_IDENTITY_disconnect (handle->identity_handle); | ||
226 | |||
227 | for (ego_entry = handle->ego_head; | ||
228 | NULL != ego_entry;) | ||
229 | { | ||
230 | ego_tmp = ego_entry; | ||
231 | ego_entry = ego_entry->next; | ||
232 | GNUNET_free(ego_tmp->identifier); | ||
233 | GNUNET_free(ego_tmp->keystring); | ||
234 | GNUNET_free(ego_tmp); | ||
235 | } | ||
236 | |||
237 | GNUNET_free(handle); | ||
238 | } | ||
239 | |||
240 | /** | ||
241 | * Task run on errors. Reports an error and cleans up everything. | ||
242 | * | ||
243 | * @param cls the `struct RequestHandle` | ||
244 | */ | ||
245 | static void | ||
246 | do_error (void *cls) | ||
247 | { | ||
248 | struct RequestHandle *handle = cls; | ||
249 | struct MHD_Response *resp; | ||
250 | json_t *json_error = json_object(); | ||
251 | char *response; | ||
252 | |||
253 | if (NULL == handle->emsg) | ||
254 | handle->emsg = GNUNET_strdup(GNUNET_REST_IDENTITY_ERROR_UNKNOWN); | ||
255 | |||
256 | json_object_set_new(json_error,"error", json_string(handle->emsg)); | ||
257 | |||
258 | if (0 == handle->response_code) | ||
259 | handle->response_code = MHD_HTTP_OK; | ||
260 | response = json_dumps (json_error, 0); | ||
261 | resp = GNUNET_REST_create_response (response); | ||
262 | handle->proc (handle->proc_cls, resp, handle->response_code); | ||
263 | json_decref(json_error); | ||
264 | GNUNET_free(response); | ||
265 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
266 | } | ||
267 | |||
268 | |||
269 | |||
270 | /** | ||
271 | * Get EgoEntry from list with either a public key or a name | ||
272 | * If public key and name are not NULL, it returns the public key result first | ||
273 | * | ||
274 | * @param handle the RequestHandle | ||
275 | * @param pubkey the public key of an identity (only one can be NULL) | ||
276 | * @param name the name of an identity (only one can be NULL) | ||
277 | * @return EgoEntry or NULL if not found | ||
278 | */ | ||
279 | struct EgoEntry* | ||
280 | get_egoentry(struct RequestHandle *handle, char* pubkey, char *name) | ||
281 | { | ||
282 | struct EgoEntry *ego_entry; | ||
283 | if (NULL != pubkey) | ||
284 | { | ||
285 | for (ego_entry = handle->ego_head; | ||
286 | NULL != ego_entry; | ||
287 | ego_entry = ego_entry->next) | ||
288 | { | ||
289 | if (0 != strcasecmp (pubkey, ego_entry->keystring)) | ||
290 | continue; | ||
291 | return ego_entry; | ||
292 | } | ||
293 | } | ||
294 | if (NULL != name) | ||
295 | { | ||
296 | for (ego_entry = handle->ego_head; | ||
297 | NULL != ego_entry; | ||
298 | ego_entry = ego_entry->next) | ||
299 | { | ||
300 | if (0 != strcasecmp (name, ego_entry->identifier)) | ||
301 | continue; | ||
302 | return ego_entry; | ||
303 | } | ||
304 | } | ||
305 | return NULL; | ||
306 | } | ||
307 | |||
308 | |||
309 | /** | ||
310 | * Callback for GET Request with subsystem | ||
311 | * | ||
312 | * @param cls the RequestHandle | ||
313 | * @param ego the Ego found | ||
314 | * @param ctx the context | ||
315 | * @param name the id of the ego | ||
316 | */ | ||
317 | static void | ||
318 | ego_get_for_subsystem (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, | ||
319 | const char *name) | ||
320 | { | ||
321 | struct RequestHandle *handle = cls; | ||
322 | struct MHD_Response *resp; | ||
323 | struct GNUNET_CRYPTO_EcdsaPublicKey public_key; | ||
324 | json_t *json_root; | ||
325 | char *result_str; | ||
326 | char *public_key_string; | ||
327 | |||
328 | if(NULL == ego) | ||
329 | { | ||
330 | handle->emsg = GNUNET_strdup("No identity found for subsystem"); | ||
331 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
332 | return; | ||
333 | } | ||
334 | |||
335 | GNUNET_IDENTITY_ego_get_public_key(ego,&public_key); | ||
336 | public_key_string = GNUNET_CRYPTO_ecdsa_public_key_to_string(&public_key); | ||
337 | |||
338 | // create json with subsystem identity | ||
339 | json_root = json_object (); | ||
340 | json_object_set_new (json_root, GNUNET_REST_PARAM_PUBKEY, json_string(public_key_string)); | ||
341 | json_object_set_new (json_root, GNUNET_REST_PARAM_NAME, json_string(name)); | ||
342 | |||
343 | result_str = json_dumps (json_root, 0); | ||
344 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); | ||
345 | resp = GNUNET_REST_create_response (result_str); | ||
346 | |||
347 | json_decref (json_root); | ||
348 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
349 | GNUNET_free(result_str); | ||
350 | GNUNET_free(public_key_string); | ||
351 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
352 | } | ||
353 | |||
354 | /** | ||
355 | * Handle identity GET request | ||
356 | * | ||
357 | * @param con_handle the connection handle | ||
358 | * @param url the url | ||
359 | * @param cls the RequestHandle | ||
360 | */ | ||
361 | void | ||
362 | ego_get (struct GNUNET_REST_RequestHandle *con_handle, const char* url, | ||
363 | void *cls) | ||
364 | { | ||
365 | struct RequestHandle *handle = cls; | ||
366 | struct EgoEntry *ego_entry; | ||
367 | struct GNUNET_HashCode key; | ||
368 | struct MHD_Response *resp; | ||
369 | char *keystring; | ||
370 | char *egoname; | ||
371 | json_t *json_root; | ||
372 | json_t *json_ego; | ||
373 | char *result_str; | ||
374 | |||
375 | //requested default identity of subsystem | ||
376 | GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_SUBSYSTEM, | ||
377 | strlen (GNUNET_REST_PARAM_SUBSYSTEM), &key); | ||
378 | if ( GNUNET_YES | ||
379 | == GNUNET_CONTAINER_multihashmap_contains ( | ||
380 | handle->rest_handle->url_param_map, &key)) | ||
381 | { | ||
382 | handle->subsystem = GNUNET_strdup( | ||
383 | GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, | ||
384 | &key)); | ||
385 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", | ||
386 | handle->subsystem); | ||
387 | |||
388 | handle->op = GNUNET_IDENTITY_get (handle->identity_handle, | ||
389 | handle->subsystem, | ||
390 | &ego_get_for_subsystem, | ||
391 | handle); | ||
392 | if (NULL == handle->op) | ||
393 | { | ||
394 | handle->emsg = GNUNET_strdup("No identity found for subsystem"); | ||
395 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
396 | return; | ||
397 | } | ||
398 | return; | ||
399 | } | ||
400 | egoname = NULL; | ||
401 | keystring = NULL; | ||
402 | |||
403 | //one identity requested with key | ||
404 | GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_PUBKEY, | ||
405 | strlen (GNUNET_REST_PARAM_PUBKEY), | ||
406 | &key); | ||
407 | if ( GNUNET_YES | ||
408 | == GNUNET_CONTAINER_multihashmap_contains ( | ||
409 | handle->rest_handle->url_param_map, &key)) | ||
410 | { | ||
411 | keystring = GNUNET_CONTAINER_multihashmap_get ( | ||
412 | handle->rest_handle->url_param_map, &key); | ||
413 | |||
414 | ego_entry = get_egoentry(handle, keystring, NULL); | ||
415 | if (NULL == ego_entry) | ||
416 | { | ||
417 | handle->emsg = GNUNET_strdup("No identity found for public key"); | ||
418 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
419 | return; | ||
420 | } | ||
421 | egoname = ego_entry->identifier; | ||
422 | } | ||
423 | |||
424 | //one identity requested with name | ||
425 | if (NULL == egoname) | ||
426 | { | ||
427 | GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_NAME, | ||
428 | strlen (GNUNET_REST_PARAM_NAME), | ||
429 | &key); | ||
430 | if ( GNUNET_YES | ||
431 | == GNUNET_CONTAINER_multihashmap_contains ( | ||
432 | handle->rest_handle->url_param_map, &key)) | ||
433 | { | ||
434 | egoname = GNUNET_CONTAINER_multihashmap_get ( | ||
435 | handle->rest_handle->url_param_map, &key); | ||
436 | if (0 >= strlen(egoname)) | ||
437 | { | ||
438 | handle->emsg = GNUNET_strdup("No identity found for name"); | ||
439 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
440 | return; | ||
441 | } | ||
442 | //LOWERCASE ego names? | ||
443 | GNUNET_STRINGS_utf8_tolower(egoname, egoname); | ||
444 | } | ||
445 | } | ||
446 | |||
447 | json_root = json_array (); | ||
448 | //Return ego/egos | ||
449 | for (ego_entry = handle->ego_head; | ||
450 | NULL != ego_entry; ego_entry = ego_entry->next) | ||
451 | { | ||
452 | //if only one ego requested | ||
453 | if ((NULL != egoname)){ | ||
454 | if(0 != strcmp (egoname, ego_entry->identifier)){ | ||
455 | continue; | ||
456 | } | ||
457 | } | ||
458 | |||
459 | json_ego = json_object (); | ||
460 | json_object_set_new (json_ego, | ||
461 | GNUNET_REST_PARAM_PUBKEY, | ||
462 | json_string (ego_entry->keystring)); | ||
463 | json_object_set_new (json_ego, | ||
464 | GNUNET_REST_PARAM_NAME, | ||
465 | json_string (ego_entry->identifier)); | ||
466 | json_array_append (json_root, json_ego); | ||
467 | json_decref (json_ego); | ||
468 | } | ||
469 | |||
470 | if ((size_t) 0 == json_array_size (json_root)) | ||
471 | { | ||
472 | json_decref (json_root); | ||
473 | handle->emsg = GNUNET_strdup("No identities found!"); | ||
474 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
475 | return; | ||
476 | } | ||
477 | |||
478 | result_str = json_dumps (json_root, 0); | ||
479 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); | ||
480 | resp = GNUNET_REST_create_response (result_str); | ||
481 | |||
482 | json_decref (json_root); | ||
483 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
484 | GNUNET_free(result_str); | ||
485 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
486 | } | ||
487 | |||
488 | |||
489 | /** | ||
490 | * Processing finished | ||
491 | * | ||
492 | * @param cls request handle | ||
493 | * @param emsg error message | ||
494 | */ | ||
495 | static void | ||
496 | do_finished (void *cls, const char *emsg) | ||
497 | { | ||
498 | struct RequestHandle *handle = cls; | ||
499 | struct MHD_Response *resp; | ||
500 | |||
501 | handle->op = NULL; | ||
502 | if (NULL != emsg) | ||
503 | { | ||
504 | handle->emsg = GNUNET_strdup(emsg); | ||
505 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
506 | return; | ||
507 | } | ||
508 | resp = GNUNET_REST_create_response (NULL); | ||
509 | handle->proc (handle->proc_cls, resp, handle->response_code); | ||
510 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
511 | } | ||
512 | |||
513 | |||
514 | /** | ||
515 | * Handle identity PUT request | ||
516 | * | ||
517 | * @param con_handle the connection handle | ||
518 | * @param url the url | ||
519 | * @param cls the RequestHandle | ||
520 | */ | ||
521 | void | ||
522 | ego_edit (struct GNUNET_REST_RequestHandle *con_handle, | ||
523 | const char* url, | ||
524 | void *cls) | ||
525 | { | ||
526 | struct RequestHandle *handle = cls; | ||
527 | struct EgoEntry *ego_entry; | ||
528 | struct EgoEntry *ego_entry_tmp; | ||
529 | struct MHD_Response *resp; | ||
530 | int json_state; | ||
531 | json_t *data_js; | ||
532 | json_error_t err; | ||
533 | char *pubkey; | ||
534 | char *name; | ||
535 | char *newsubsys; | ||
536 | char *newname; | ||
537 | char term_data[handle->data_size + 1]; | ||
538 | |||
539 | //if no data | ||
540 | if (0 >= handle->data_size) | ||
541 | { | ||
542 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA); | ||
543 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
544 | return; | ||
545 | } | ||
546 | //if not json | ||
547 | term_data[handle->data_size] = '\0'; | ||
548 | GNUNET_memcpy(term_data, handle->data, handle->data_size); | ||
549 | data_js = json_loads (term_data,JSON_DECODE_ANY,&err); | ||
550 | |||
551 | if (NULL == data_js) | ||
552 | { | ||
553 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA); | ||
554 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
555 | return; | ||
556 | } | ||
557 | |||
558 | ego_entry = NULL; | ||
559 | pubkey = NULL; | ||
560 | name = NULL; | ||
561 | newname = NULL; | ||
562 | //NEW NAME | ||
563 | json_state = 0; | ||
564 | json_state = json_unpack(data_js, | ||
565 | "{s:s,s?:s,s?:s}", | ||
566 | GNUNET_REST_PARAM_NEWNAME, | ||
567 | &newname, | ||
568 | GNUNET_REST_PARAM_PUBKEY, | ||
569 | &pubkey, | ||
570 | GNUNET_REST_PARAM_NAME, | ||
571 | &name); | ||
572 | //Change name with pubkey or name identifier | ||
573 | if (0 == json_state) | ||
574 | { | ||
575 | if (NULL == newname) | ||
576 | { | ||
577 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID); | ||
578 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
579 | json_decref (data_js); | ||
580 | return; | ||
581 | } | ||
582 | |||
583 | if (0 >= strlen(newname)) | ||
584 | { | ||
585 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID); | ||
586 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
587 | json_decref (data_js); | ||
588 | return; | ||
589 | } | ||
590 | //lower case name | ||
591 | GNUNET_STRINGS_utf8_tolower(newname,newname); | ||
592 | |||
593 | ego_entry = get_egoentry(handle,pubkey,name); | ||
594 | |||
595 | if (NULL == ego_entry) | ||
596 | { | ||
597 | resp = GNUNET_REST_create_response (NULL); | ||
598 | handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND); | ||
599 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
600 | json_decref (data_js); | ||
601 | return; | ||
602 | } | ||
603 | |||
604 | for (ego_entry_tmp = handle->ego_head; | ||
605 | NULL != ego_entry_tmp; ego_entry_tmp = ego_entry_tmp->next) | ||
606 | { | ||
607 | if (0 == strcasecmp (newname, ego_entry_tmp->identifier)) | ||
608 | { | ||
609 | //Ego with same name not allowed | ||
610 | resp = GNUNET_REST_create_response (NULL); | ||
611 | handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); | ||
612 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
613 | json_decref (data_js); | ||
614 | return; | ||
615 | } | ||
616 | } | ||
617 | handle->response_code = MHD_HTTP_NO_CONTENT; | ||
618 | handle->op = GNUNET_IDENTITY_rename (handle->identity_handle, | ||
619 | ego_entry->identifier, newname, | ||
620 | &do_finished, handle); | ||
621 | json_decref (data_js); | ||
622 | return; | ||
623 | } | ||
624 | |||
625 | newsubsys = NULL; | ||
626 | //SUBSYSTEM | ||
627 | json_state = 0; | ||
628 | json_state = json_unpack(data_js, | ||
629 | "{s:s,s?:s,s?:s}", | ||
630 | GNUNET_REST_PARAM_SUBSYSTEM, | ||
631 | &newsubsys, | ||
632 | GNUNET_REST_PARAM_PUBKEY, | ||
633 | &pubkey, | ||
634 | GNUNET_REST_PARAM_NAME, | ||
635 | &name); | ||
636 | //Change subsystem with pubkey or name identifier | ||
637 | if (0 == json_state) | ||
638 | { | ||
639 | if (NULL == newsubsys || (NULL == pubkey && NULL == name)) | ||
640 | { | ||
641 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID); | ||
642 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
643 | json_decref (data_js); | ||
644 | return; | ||
645 | } | ||
646 | |||
647 | if (0 >= strlen(newsubsys)) | ||
648 | { | ||
649 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID); | ||
650 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
651 | json_decref (data_js); | ||
652 | return; | ||
653 | } | ||
654 | |||
655 | ego_entry = get_egoentry(handle, pubkey, name); | ||
656 | |||
657 | if (NULL == ego_entry) | ||
658 | { | ||
659 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID); | ||
660 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
661 | json_decref (data_js); | ||
662 | return; | ||
663 | } | ||
664 | |||
665 | handle->response_code = MHD_HTTP_NO_CONTENT; | ||
666 | handle->op = GNUNET_IDENTITY_set (handle->identity_handle, | ||
667 | newsubsys, | ||
668 | ego_entry->ego, | ||
669 | &do_finished, | ||
670 | handle); | ||
671 | json_decref (data_js); | ||
672 | return; | ||
673 | } | ||
674 | |||
675 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID); | ||
676 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
677 | json_decref (data_js); | ||
678 | return; | ||
679 | } | ||
680 | |||
681 | /** | ||
682 | * Handle identity POST request | ||
683 | * | ||
684 | * @param con_handle the connection handle | ||
685 | * @param url the url | ||
686 | * @param cls the RequestHandle | ||
687 | */ | ||
688 | void | ||
689 | ego_create (struct GNUNET_REST_RequestHandle *con_handle, const char* url, | ||
690 | void *cls) | ||
691 | { | ||
692 | struct RequestHandle *handle = cls; | ||
693 | struct EgoEntry *ego_entry; | ||
694 | struct MHD_Response *resp; | ||
695 | json_t *data_js; | ||
696 | json_error_t err; | ||
697 | char* egoname; | ||
698 | int json_unpack_state; | ||
699 | char term_data[handle->data_size + 1]; | ||
700 | |||
701 | if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url)) | ||
702 | { | ||
703 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_RESOURCE_INVALID); | ||
704 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
705 | return; | ||
706 | } | ||
707 | |||
708 | if (0 >= handle->data_size) | ||
709 | { | ||
710 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA); | ||
711 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
712 | return; | ||
713 | } | ||
714 | term_data[handle->data_size] = '\0'; | ||
715 | GNUNET_memcpy(term_data, handle->data, handle->data_size); | ||
716 | data_js = json_loads (term_data, | ||
717 | JSON_DECODE_ANY, | ||
718 | &err); | ||
719 | if (NULL == data_js) | ||
720 | { | ||
721 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA); | ||
722 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
723 | json_decref (data_js); | ||
724 | return; | ||
725 | } | ||
726 | json_unpack_state = 0; | ||
727 | json_unpack_state = json_unpack(data_js, | ||
728 | "{s:s!}", | ||
729 | GNUNET_REST_PARAM_NAME, | ||
730 | &egoname); | ||
731 | if (0 != json_unpack_state) | ||
732 | { | ||
733 | handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID); | ||
734 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
735 | json_decref (data_js); | ||
736 | return; | ||
737 | } | ||
738 | |||
739 | if (NULL == egoname) | ||
740 | { | ||
741 | handle->emsg = GNUNET_strdup("No name provided"); | ||
742 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
743 | json_decref (data_js); | ||
744 | return; | ||
745 | } | ||
746 | if (0 >= strlen (egoname)) | ||
747 | { | ||
748 | json_decref (data_js); | ||
749 | handle->emsg = GNUNET_strdup("No name provided"); | ||
750 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
751 | return; | ||
752 | } | ||
753 | GNUNET_STRINGS_utf8_tolower(egoname, egoname); | ||
754 | for (ego_entry = handle->ego_head; | ||
755 | NULL != ego_entry; ego_entry = ego_entry->next) | ||
756 | { | ||
757 | if (0 == strcasecmp (egoname, ego_entry->identifier)) | ||
758 | { | ||
759 | resp = GNUNET_REST_create_response (NULL); | ||
760 | handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); | ||
761 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
762 | json_decref (data_js); | ||
763 | return; | ||
764 | } | ||
765 | } | ||
766 | handle->name = GNUNET_strdup(egoname); | ||
767 | json_decref (data_js); | ||
768 | handle->response_code = MHD_HTTP_CREATED; | ||
769 | handle->op = GNUNET_IDENTITY_create (handle->identity_handle, handle->name, | ||
770 | &do_finished, handle); | ||
771 | } | ||
772 | |||
773 | /** | ||
774 | * Handle identity DELETE request | ||
775 | * | ||
776 | * @param con_handle the connection handle | ||
777 | * @param url the url | ||
778 | * @param cls the RequestHandle | ||
779 | */ | ||
780 | void | ||
781 | ego_delete (struct GNUNET_REST_RequestHandle *con_handle, const char* url, | ||
782 | void *cls) | ||
783 | { | ||
784 | struct RequestHandle *handle = cls; | ||
785 | struct EgoEntry *ego_entry; | ||
786 | struct GNUNET_HashCode key; | ||
787 | struct MHD_Response *resp; | ||
788 | const char *keystring; | ||
789 | char *egoname; | ||
790 | int ego_exists = GNUNET_NO; | ||
791 | |||
792 | keystring = NULL; | ||
793 | egoname = NULL; | ||
794 | |||
795 | //delete with pubkey | ||
796 | GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_PUBKEY, | ||
797 | strlen (GNUNET_REST_PARAM_PUBKEY), &key); | ||
798 | if ( GNUNET_YES | ||
799 | == GNUNET_CONTAINER_multihashmap_contains ( | ||
800 | handle->rest_handle->url_param_map, &key)) | ||
801 | { | ||
802 | keystring = GNUNET_CONTAINER_multihashmap_get ( | ||
803 | handle->rest_handle->url_param_map,&key); | ||
804 | } | ||
805 | |||
806 | GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_NAME, | ||
807 | strlen (GNUNET_REST_PARAM_NAME), &key); | ||
808 | if ( GNUNET_YES | ||
809 | == GNUNET_CONTAINER_multihashmap_contains ( | ||
810 | handle->rest_handle->url_param_map, &key)) | ||
811 | { | ||
812 | egoname = GNUNET_CONTAINER_multihashmap_get ( | ||
813 | handle->rest_handle->url_param_map, &key); | ||
814 | //LOWERCASE ego names? | ||
815 | //GNUNET_STRINGS_utf8_tolower(egoname, egoname); | ||
816 | } | ||
817 | |||
818 | if (NULL != keystring) | ||
819 | { | ||
820 | for (ego_entry = handle->ego_head; | ||
821 | NULL != ego_entry; ego_entry = ego_entry->next) | ||
822 | { | ||
823 | if (0 != strcasecmp (keystring, ego_entry->keystring)) | ||
824 | continue; | ||
825 | ego_exists = GNUNET_YES; | ||
826 | break; | ||
827 | } | ||
828 | } | ||
829 | else if (NULL != egoname) | ||
830 | { | ||
831 | for (ego_entry = handle->ego_head; | ||
832 | NULL != ego_entry; ego_entry = ego_entry->next) | ||
833 | { | ||
834 | if (0 != strcmp (egoname, ego_entry->identifier)) | ||
835 | continue; | ||
836 | ego_exists = GNUNET_YES; | ||
837 | break; | ||
838 | } | ||
839 | } | ||
840 | else | ||
841 | { | ||
842 | handle->emsg = GNUNET_strdup("Missing parameter pubkey or name"); | ||
843 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
844 | return; | ||
845 | } | ||
846 | |||
847 | if (GNUNET_NO == ego_exists) | ||
848 | { | ||
849 | resp = GNUNET_REST_create_response (NULL); | ||
850 | handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND); | ||
851 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
852 | return; | ||
853 | } | ||
854 | handle->response_code = MHD_HTTP_NO_CONTENT; | ||
855 | handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, | ||
856 | ego_entry->identifier, &do_finished, | ||
857 | handle); | ||
858 | |||
859 | } | ||
860 | |||
861 | /** | ||
862 | * Respond to OPTIONS request | ||
863 | * | ||
864 | * @param con_handle the connection handle | ||
865 | * @param url the url | ||
866 | * @param cls the RequestHandle | ||
867 | */ | ||
868 | static void | ||
869 | options_cont (struct GNUNET_REST_RequestHandle *con_handle, const char* url, | ||
870 | void *cls) | ||
871 | { | ||
872 | struct MHD_Response *resp; | ||
873 | struct RequestHandle *handle = cls; | ||
874 | |||
875 | //For now, independent of path return all options | ||
876 | resp = GNUNET_REST_create_response (NULL); | ||
877 | MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); | ||
878 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | ||
879 | GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); | ||
880 | return; | ||
881 | } | ||
882 | |||
883 | /** | ||
884 | * Handle rest request | ||
885 | * | ||
886 | * @param handle the request handle | ||
887 | */ | ||
888 | static void | ||
889 | init_cont (struct RequestHandle *handle) | ||
890 | { | ||
891 | struct GNUNET_REST_RequestHandlerError err; | ||
892 | static const struct GNUNET_REST_RequestHandler handlers[] = { | ||
893 | { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get }, | ||
894 | { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY, &ego_edit }, | ||
895 | { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create }, | ||
896 | { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_IDENTITY, &ego_delete }, | ||
897 | { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont }, | ||
898 | GNUNET_REST_HANDLER_END | ||
899 | }; | ||
900 | |||
901 | if (GNUNET_NO | ||
902 | == GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, | ||
903 | handle)) | ||
904 | { | ||
905 | handle->response_code = err.error_code; | ||
906 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
907 | } | ||
908 | } | ||
909 | |||
910 | /** | ||
911 | * If listing is enabled, prints information about the egos. | ||
912 | * | ||
913 | * This function is initially called for all egos and then again | ||
914 | * whenever a ego's identifier changes or if it is deleted. At the | ||
915 | * end of the initial pass over all egos, the function is once called | ||
916 | * with 'NULL' for 'ego'. That does NOT mean that the callback won't | ||
917 | * be invoked in the future or that there was an error. | ||
918 | * | ||
919 | * When used with 'GNUNET_IDENTITY_create' or 'GNUNET_IDENTITY_get', | ||
920 | * this function is only called ONCE, and 'NULL' being passed in | ||
921 | * 'ego' does indicate an error (i.e. name is taken or no default | ||
922 | * value is known). If 'ego' is non-NULL and if '*ctx' | ||
923 | * is set in those callbacks, the value WILL be passed to a subsequent | ||
924 | * call to the identity callback of 'GNUNET_IDENTITY_connect' (if | ||
925 | * that one was not NULL). | ||
926 | * | ||
927 | * When an identity is renamed, this function is called with the | ||
928 | * (known) ego but the NEW identifier. | ||
929 | * | ||
930 | * When an identity is deleted, this function is called with the | ||
931 | * (known) ego and "NULL" for the 'identifier'. In this case, | ||
932 | * the 'ego' is henceforth invalid (and the 'ctx' should also be | ||
933 | * cleaned up). | ||
934 | * | ||
935 | * @param cls closure | ||
936 | * @param ego ego handle | ||
937 | * @param ctx context for application to store data for this ego | ||
938 | * (during the lifetime of this process, initially NULL) | ||
939 | * @param identifier identifier assigned by the user for this ego, | ||
940 | * NULL if the user just deleted the ego and it | ||
941 | * must thus no longer be used | ||
942 | */ | ||
943 | static void | ||
944 | init_egos (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx, | ||
945 | const char *identifier) | ||
946 | { | ||
947 | struct RequestHandle *handle = cls; | ||
948 | struct EgoEntry *ego_entry; | ||
949 | struct GNUNET_CRYPTO_EcdsaPublicKey pk; | ||
950 | |||
951 | if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) | ||
952 | { | ||
953 | handle->state = ID_REST_STATE_POST_INIT; | ||
954 | init_cont (handle); | ||
955 | return; | ||
956 | } | ||
957 | if (ID_REST_STATE_INIT == handle->state) | ||
958 | { | ||
959 | ego_entry = GNUNET_new(struct EgoEntry); | ||
960 | GNUNET_IDENTITY_ego_get_public_key (ego, &pk); | ||
961 | ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); | ||
962 | ego_entry->ego = ego; | ||
963 | GNUNET_asprintf (&ego_entry->identifier, "%s", identifier); | ||
964 | GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head, handle->ego_tail, | ||
965 | ego_entry); | ||
966 | } | ||
967 | } | ||
968 | |||
969 | /** | ||
970 | * Function processing the REST call | ||
971 | * | ||
972 | * @param method HTTP method | ||
973 | * @param url URL of the HTTP request | ||
974 | * @param data body of the HTTP request (optional) | ||
975 | * @param data_size length of the body | ||
976 | * @param proc callback function for the result | ||
977 | * @param proc_cls closure for callback function | ||
978 | * @return GNUNET_OK if request accepted | ||
979 | */ | ||
980 | static void | ||
981 | rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle, | ||
982 | GNUNET_REST_ResultProcessor proc, void *proc_cls) | ||
983 | { | ||
984 | struct RequestHandle *handle = GNUNET_new(struct RequestHandle); | ||
985 | |||
986 | handle->response_code = 0; | ||
987 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; | ||
988 | handle->proc_cls = proc_cls; | ||
989 | handle->proc = proc; | ||
990 | handle->rest_handle = rest_handle; | ||
991 | handle->data = rest_handle->data; | ||
992 | handle->data_size = rest_handle->data_size; | ||
993 | |||
994 | handle->url = GNUNET_strdup(rest_handle->url); | ||
995 | if (handle->url[strlen (handle->url) - 1] == '/') | ||
996 | handle->url[strlen (handle->url) - 1] = '\0'; | ||
997 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); | ||
998 | |||
999 | handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &init_egos, handle); | ||
1000 | |||
1001 | handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout, | ||
1002 | &do_error, handle); | ||
1003 | |||
1004 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); | ||
1005 | } | ||
1006 | |||
1007 | /** | ||
1008 | * Entry point for the plugin. | ||
1009 | * | ||
1010 | * @param cls Config info | ||
1011 | * @return NULL on error, otherwise the plugin context | ||
1012 | */ | ||
1013 | void * | ||
1014 | libgnunet_plugin_rest_identity_init (void *cls) | ||
1015 | { | ||
1016 | static struct Plugin plugin; | ||
1017 | struct GNUNET_REST_Plugin *api; | ||
1018 | |||
1019 | cfg = cls; | ||
1020 | if (NULL != plugin.cfg) | ||
1021 | return NULL; /* can only initialize once! */ | ||
1022 | memset (&plugin, 0, sizeof(struct Plugin)); | ||
1023 | plugin.cfg = cfg; | ||
1024 | api = GNUNET_new(struct GNUNET_REST_Plugin); | ||
1025 | api->cls = &plugin; | ||
1026 | api->name = GNUNET_REST_API_NS_IDENTITY; | ||
1027 | api->process_request = &rest_process_request; | ||
1028 | GNUNET_asprintf (&allow_methods, "%s, %s, %s, %s, %s", | ||
1029 | MHD_HTTP_METHOD_GET, | ||
1030 | MHD_HTTP_METHOD_POST, | ||
1031 | MHD_HTTP_METHOD_PUT, | ||
1032 | MHD_HTTP_METHOD_DELETE, | ||
1033 | MHD_HTTP_METHOD_OPTIONS); | ||
1034 | |||
1035 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, _("Identity REST API initialized\n")); | ||
1036 | return api; | ||
1037 | } | ||
1038 | |||
1039 | /** | ||
1040 | * Exit point from the plugin. | ||
1041 | * | ||
1042 | * @param cls the plugin context (as returned by "init") | ||
1043 | * @return always NULL | ||
1044 | */ | ||
1045 | void * | ||
1046 | libgnunet_plugin_rest_identity_done (void *cls) | ||
1047 | { | ||
1048 | struct GNUNET_REST_Plugin *api = cls; | ||
1049 | struct Plugin *plugin = api->cls; | ||
1050 | plugin->cfg = NULL; | ||
1051 | |||
1052 | GNUNET_free_non_null(allow_methods); | ||
1053 | GNUNET_free(api); | ||
1054 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Identity REST plugin is finished\n"); | ||
1055 | return NULL; | ||
1056 | } | ||
1057 | |||
1058 | /* end of plugin_rest_identity.c */ | ||
1059 | |||
diff --git a/src/identity/test_plugin_rest_identity.sh b/src/identity/test_plugin_rest_identity.sh deleted file mode 100755 index d9377500e..000000000 --- a/src/identity/test_plugin_rest_identity.sh +++ /dev/null | |||
@@ -1,159 +0,0 @@ | |||
1 | #!/usr/bin/bash | ||
2 | |||
3 | #First, start gnunet-arm and the rest-service. | ||
4 | #Exit 0 means success, exit 1 means failed test | ||
5 | |||
6 | identity_link="http://localhost:7776/identity" | ||
7 | wrong_link="http://localhost:7776/identityandmore" | ||
8 | |||
9 | |||
10 | curl_get () { | ||
11 | #$1 is link | ||
12 | #$2 is grep | ||
13 | cache="$(curl -v "$1" 2>&1 | grep "$2")" | ||
14 | #echo $cache | ||
15 | if [ "" == "$cache" ] | ||
16 | then | ||
17 | exit 1 | ||
18 | fi | ||
19 | } | ||
20 | |||
21 | curl_post () { | ||
22 | #$1 is link | ||
23 | #$2 is data | ||
24 | #$3 is grep | ||
25 | cache="$(curl -v -X "POST" "$1" --data "$2" 2>&1 | grep "$3")" | ||
26 | #echo $cache | ||
27 | if [ "" == "$cache" ] | ||
28 | then | ||
29 | exit 1 | ||
30 | fi | ||
31 | } | ||
32 | |||
33 | curl_delete () { | ||
34 | #$1 is link | ||
35 | #$2 is grep | ||
36 | cache="$(curl -v -X "DELETE" "$1" 2>&1 | grep "$2")" | ||
37 | #echo $cache | ||
38 | if [ "" == "$cache" ] | ||
39 | then | ||
40 | exit 1 | ||
41 | fi | ||
42 | } | ||
43 | |||
44 | curl_put () { | ||
45 | #$1 is link | ||
46 | #$2 is data | ||
47 | #$3 is grep | ||
48 | cache="$(curl -v -X "PUT" "$1" --data "$2" 2>&1 | grep "$3")" | ||
49 | #echo $cache | ||
50 | if [ "" == "$cache" ] | ||
51 | then | ||
52 | exit 1 | ||
53 | fi | ||
54 | } | ||
55 | |||
56 | #Test GET | ||
57 | test="$(gnunet-identity -d)" | ||
58 | #if no identity exists | ||
59 | if [ "" == "$test" ] | ||
60 | then | ||
61 | curl_get "$identity_link" "error" | ||
62 | gnunet-identity -C "test_plugin_rest_identity" | ||
63 | name="$(gnunet-identity -d | awk 'NR==1{print $1}')" | ||
64 | public="$(gnunet-identity -d | awk 'NR==1{print $3}')" | ||
65 | |||
66 | curl_get "${identity_link}?name=$name" "$public" | ||
67 | curl_get "${identity_link}?name=" "error" | ||
68 | curl_get "${identity_link}?name=$public" "error" | ||
69 | |||
70 | curl_get "${identity_link}?pubkey=$public" "$name" | ||
71 | curl_get "${identity_link}?pubkey=$name" "error" | ||
72 | curl_get "${identity_link}?pubkey=" "error" | ||
73 | |||
74 | gnunet-identity -D "test_plugin_rest_identity" | ||
75 | else | ||
76 | name="$(gnunet-identity -d | awk 'NR==1{print $1}')" | ||
77 | public="$(gnunet-identity -d | awk 'NR==1{print $3}')" | ||
78 | |||
79 | curl_get "${identity_link}?name=$name" "$public" | ||
80 | curl_get "${identity_link}?name=" "error" | ||
81 | curl_get "${identity_link}?name=$public" "error" | ||
82 | |||
83 | curl_get "${identity_link}?pubkey=$public" "$name" | ||
84 | curl_get "${identity_link}?pubkey=$name" "error" | ||
85 | curl_get "${identity_link}?pubkey=" "error" | ||
86 | fi | ||
87 | |||
88 | #Test POST | ||
89 | gnunet-identity -D "test_plugin_rest_identity" > /dev/null 2>&1 | ||
90 | gnunet-identity -D "test_plugin_rest_identity1" > /dev/null 2>&1 | ||
91 | |||
92 | curl_post "${identity_link}" '{"name":"test_plugin_rest_identity"}' "HTTP/1.1 201 Created" | ||
93 | curl_post "${identity_link}" '{"name":"test_plugin_rest_identity"}' "HTTP/1.1 409" | ||
94 | curl_post "${identity_link}" '{"name":"Test_plugin_rest_identity"}' "HTTP/1.1 409" | ||
95 | curl_post "${identity_link}" '{}' "error" | ||
96 | curl_post "${identity_link}" '' "error" | ||
97 | curl_post "${identity_link}" '{"name":""}' "error" | ||
98 | curl_post "${identity_link}" '{"name":123}' "error" | ||
99 | curl_post "${identity_link}" '{"name":[]}' "error" | ||
100 | curl_post "${identity_link}" '{"name1":"test_plugin_rest_identity"}' "error" | ||
101 | curl_post "${identity_link}" '{"other":""}' "error" | ||
102 | curl_post "${identity_link}" '{"name":"test_plugin_rest_identity1", "other":"test_plugin_rest_identity2"}' "error" | ||
103 | |||
104 | #Test PUT | ||
105 | name="$(gnunet-identity -d | grep "test_plugin_rest_identity" | awk 'NR==1{print $1}')" | ||
106 | public="$(gnunet-identity -d | grep "test_plugin_rest_identity" | awk 'NR==1{print $3}')" | ||
107 | |||
108 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity1","pubkey":"'$public'"}' "HTTP/1.1 204" | ||
109 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity1","pubkey":"'$public'"}' "HTTP/1.1 409" | ||
110 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity1","pubkey":"'$public'xx"}' "HTTP/1.1 404" | ||
111 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity1","pubkey":""}' "HTTP/1.1 404" | ||
112 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity1","pubke":""}' "HTTP/1.1 404" | ||
113 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity1","pubke":"","other":"sdfdsf"}' "HTTP/1.1 404" | ||
114 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity1","pubke":"","name":"sdfdsf"}' "HTTP/1.1 404" | ||
115 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity","pubke":"","name":"test_plugin_rest_identity1"}' "HTTP/1.1 204" | ||
116 | curl_put "${identity_link}" '{"newnam":"test_plugin_rest_identity","pubkey":"'$public'"}' "error" | ||
117 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity1","name":"test_plugin_rest_identity"}' "HTTP/1.1 204" | ||
118 | curl_put "${identity_link}" '{"newname":"TEST_plugin_rest_identity1","name":"test_plugin_rest_identity1"}' "HTTP/1.1 409" | ||
119 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity1","name":"test_plugin_rest_identity1"}' "HTTP/1.1 409" | ||
120 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity","name":"test_plugin_rest_identityxxx"}' "HTTP/1.1 404" | ||
121 | curl_put "${identity_link}" '{"newname":"test_plugin_rest_identity","name":"test_plugin_rest_identity1"}' "HTTP/1.1 204" | ||
122 | curl_put "${identity_link}" '{"newnam":"test_plugin_rest_identityfail","name":"test_plugin_rest_identity"}' "error" | ||
123 | |||
124 | |||
125 | #Test subsystem | ||
126 | curl_put "${identity_link}" '{"subsystem":"namestore","name":"test_plugin_rest_identity"}' "HTTP/1.1 204" | ||
127 | curl_put "${identity_link}" '{"subsystem":"namestore","name":"test_plugin_rest_identity"}' "HTTP/1.1 204" | ||
128 | curl_get "${identity_link}?subsystem=namestore" "test_plugin_rest_identity" | ||
129 | curl_post "${identity_link}" '{"name":"test_plugin_rest_identity1"}' "HTTP/1.1 201 Created" | ||
130 | public="$(gnunet-identity -d | grep "test_plugin_rest_identity" | awk 'NR==1{print $3}')" | ||
131 | curl_put "${identity_link}" '{"subsystem":"namestore","pubkey":"'"$public"'"}' "HTTP/1.1 204" | ||
132 | curl_get "${identity_link}?subsystem=namestore" "test_plugin_rest_identity1" | ||
133 | curl_get "${identity_link}?subsystem=test_plugin_rest_identity_no_subsystem" "error" | ||
134 | curl_put "${identity_link}" '{"subsystem":"test_plugin_rest_identity_no_subsystem","name":"test_plugin_rest_identity1"}' "HTTP/1.1 204" | ||
135 | curl_get "${identity_link}?subsystem=test_plugin_rest_identity_no_subsystem" "test_plugin_rest_identity1" | ||
136 | |||
137 | curl_put "${identity_link}" '{"subsyste":"test_plugin_rest_identity_no_subsystem","name":"test_plugin_rest_identity1"}' "error" | ||
138 | curl_put "${identity_link}" '{"subsystem":"test_plugin_rest_identity_no_subsystem","name":"Test_plugin_rest_identity1"}' "HTTP/1.1 204" | ||
139 | |||
140 | #Test DELETE | ||
141 | curl_delete "${identity_link}?name=test_plugin_rest_identity" "HTTP/1.1 204" | ||
142 | curl_get "${identity_link}?name=test_plugin_rest_identity" "error" | ||
143 | curl_delete "${identity_link}?name=TEST_plugin_rest_identity1" "HTTP/1.1 404" | ||
144 | curl_delete "${identity_link}?name=test_plugin_rest_identity1" "HTTP/1.1 204" | ||
145 | curl_get "${identity_link}?name=test_plugin_rest_identity1" "error" | ||
146 | curl_delete "${identity_link}?name=test_plugin_rest_identity_not_found" "HTTP/1.1 404" | ||
147 | curl_post "${identity_link}" '{"name":"test_plugin_rest_identity1"}' "HTTP/1.1 201 Created" | ||
148 | public="$(gnunet-identity -d | grep "test_plugin_rest_identity1" | awk 'NR==1{print $3}')" | ||
149 | curl_delete "${identity_link}?pubkey=$public" "HTTP/1.1 204" | ||
150 | curl_delete "${identity_link}?pubke=$public" "error" | ||
151 | curl_delete "${identity_link}?pubkey=$public&other=232" "HTTP/1.1 404" | ||
152 | |||
153 | #Test wrong_link | ||
154 | curl_get "$wrong_link" "HTTP/1.1 404" | ||
155 | curl_post "$wrong_link" '{"name":"test_plugin_rest_identity"}' "HTTP/1.1 404" | ||
156 | curl_put "$wrong_link" '{"newname":"test_plugin_rest_identity1","name":"test_plugin_rest_identity"}' "HTTP/1.1 404" | ||
157 | curl_delete "$wrong_link?name=test_plugin_rest_identity1" "HTTP/1.1 404" | ||
158 | |||
159 | exit 0; | ||