aboutsummaryrefslogtreecommitdiff
path: root/src/identity
diff options
context:
space:
mode:
authorPhil <phil.buschmann@tum.de>2018-06-25 00:17:06 +0200
committerPhil <phil.buschmann@tum.de>2018-06-25 00:17:06 +0200
commit4e6cb01843318385cfad41aec4cde5791f51cde2 (patch)
tree5759d9767f06c668d453f2c2e7fb646199be2a1b /src/identity
parent688bd873c3cb463090039f64b9f13b9a029695dc (diff)
downloadgnunet-4e6cb01843318385cfad41aec4cde5791f51cde2.tar.gz
gnunet-4e6cb01843318385cfad41aec4cde5791f51cde2.zip
Identity+GNS Rest changed and fixed
Diffstat (limited to 'src/identity')
-rw-r--r--src/identity/plugin_rest_identity.c837
-rwxr-xr-xsrc/identity/test_plugin_rest_identity.sh216
2 files changed, 598 insertions, 455 deletions
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c
index fd6562f1d..8d525b950 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -1,26 +1,27 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2012-2015 GNUnet e.V. 3 Copyright (C) 2012-2015 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software; you can redistribute it and/or modify
6 under the terms of the GNU Affero General Public License as published 6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation, either version 3 of the License, 7 by the Free Software Foundation; either version 3, or (at your
8 or (at your option) any later version. 8 option) any later version.
9 9
10 GNUnet is distributed in the hope that it will be useful, but 10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with GNUnet; see the file COPYING. If not, write to the
17 */ 17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19 */
18/** 20/**
19 * @author Martin Schanzenbach 21 * @author Martin Schanzenbach
20 * @author Philippe Buschmann 22 * @author Philippe Buschmann
21 * @file identity/plugin_rest_identity.c 23 * @file identity/plugin_rest_identity.c
22 * @brief GNUnet Namestore REST plugin 24 * @brief GNUnet Identity REST plugin
23 *
24 */ 25 */
25 26
26#include "platform.h" 27#include "platform.h"
@@ -29,56 +30,34 @@
29#include "gnunet_rest_lib.h" 30#include "gnunet_rest_lib.h"
30#include "microhttpd.h" 31#include "microhttpd.h"
31#include <jansson.h> 32#include <jansson.h>
32#include "gnunet_signatures.h"
33 33
34/**
35 * REST root namespace
36 */
37#define GNUNET_REST_API_NS_IDENTITY "/identity" 34#define GNUNET_REST_API_NS_IDENTITY "/identity"
38 35
39/** 36/**
40 * State while collecting all egos 37 * Parameter names
41 */
42#define ID_REST_STATE_INIT 0
43
44/**
45 * Done collecting egos
46 */
47#define ID_REST_STATE_POST_INIT 1
48
49/**
50 * Resource type
51 */
52#define GNUNET_REST_JSON_IDENTITY_EGO "ego"
53
54/**
55 * Name attribute
56 */
57#define GNUNET_REST_JSON_IDENTITY_NAME "name"
58
59/**
60 * Attribute to rename "name" TODO we changed id to the pubkey
61 * so this can be unified with "name"
62 */ 38 */
63#define GNUNET_REST_JSON_IDENTITY_NEWNAME "newname" 39#define GNUNET_REST_PARAM_PUBKEY "pubkey"
64 40#define GNUNET_REST_PARAM_SUBSYSTEM "subsystem"
65/** 41#define GNUNET_REST_PARAM_NAME "name"
66 * URL parameter to change the subsytem for ego 42#define GNUNET_REST_PARAM_NEWNAME "newname"
67 */
68#define GNUNET_REST_JSON_IDENTITY_SUBSYSTEM "subsystem"
69
70 43
71/** 44/**
72 * Error messages 45 * Error messages
73 */ 46 */
47#define GNUNET_REST_ERROR_UNKNOWN "Unknown Error"
74#define GNUNET_REST_ERROR_RESOURCE_INVALID "Resource location invalid" 48#define GNUNET_REST_ERROR_RESOURCE_INVALID "Resource location invalid"
75#define GNUNET_REST_ERROR_NO_DATA "No data" 49#define GNUNET_REST_ERROR_NO_DATA "No data"
76#define GNUNET_REST_ERROR_DATA_INVALID "Data invalid" 50#define GNUNET_REST_ERROR_DATA_INVALID "Data invalid"
77 51
78/** 52/**
79 * GNUid token lifetime 53 * State while collecting all egos
54 */
55#define ID_REST_STATE_INIT 0
56
57/**
58 * Done collecting egos
80 */ 59 */
81#define GNUNET_GNUID_TOKEN_EXPIRATION_MICROSECONDS 300000000 60#define ID_REST_STATE_POST_INIT 1
82 61
83/** 62/**
84 * The configuration handle 63 * The configuration handle
@@ -129,28 +108,37 @@ struct EgoEntry
129 struct GNUNET_IDENTITY_Ego *ego; 108 struct GNUNET_IDENTITY_Ego *ego;
130}; 109};
131 110
132
133struct RequestHandle 111struct RequestHandle
134{ 112{
135 /** 113 /**
136 * Ego list 114 * The data from the REST request
137 */ 115 */
138 struct EgoEntry *ego_head; 116 const char* data;
139 117
140 /** 118 /**
141 * Ego list 119 * The name to look up
142 */ 120 */
143 struct EgoEntry *ego_tail; 121 char *name;
144 122
145 /** 123 /**
146 * Handle to the rest connection 124 * the length of the REST data
147 */ 125 */
148 struct GNUNET_REST_RequestHandle *conndata_handle; 126 size_t data_size;
149 127
150 /** 128 /**
151 * response code 129 * Requested Subsystem
152 */ 130 */
153 int response_code; 131 char *subsystem;
132
133 /**
134 * Ego list
135 */
136 struct EgoEntry *ego_head;
137
138 /**
139 * Ego list
140 */
141 struct EgoEntry *ego_tail;
154 142
155 /** 143 /**
156 * The processing state 144 * The processing state
@@ -158,7 +146,7 @@ struct RequestHandle
158 int state; 146 int state;
159 147
160 /** 148 /**
161 * Handle to GNS service. 149 * Handle to Identity service.
162 */ 150 */
163 struct GNUNET_IDENTITY_Handle *identity_handle; 151 struct GNUNET_IDENTITY_Handle *identity_handle;
164 152
@@ -168,6 +156,11 @@ struct RequestHandle
168 struct GNUNET_IDENTITY_Operation *op; 156 struct GNUNET_IDENTITY_Operation *op;
169 157
170 /** 158 /**
159 * Rest connection
160 */
161 struct GNUNET_REST_RequestHandle *rest_handle;
162
163 /**
171 * Desired timeout for the lookup (default is no timeout). 164 * Desired timeout for the lookup (default is no timeout).
172 */ 165 */
173 struct GNUNET_TIME_Relative timeout; 166 struct GNUNET_TIME_Relative timeout;
@@ -175,7 +168,7 @@ struct RequestHandle
175 /** 168 /**
176 * ID of a task associated with the resolution process. 169 * ID of a task associated with the resolution process.
177 */ 170 */
178 struct GNUNET_SCHEDULER_Task * timeout_task; 171 struct GNUNET_SCHEDULER_Task *timeout_task;
179 172
180 /** 173 /**
181 * The plugin result processor 174 * The plugin result processor
@@ -188,43 +181,22 @@ struct RequestHandle
188 void *proc_cls; 181 void *proc_cls;
189 182
190 /** 183 /**
191 * The name to look up
192 */
193 char *name;
194
195 /**
196 * The subsystem set from REST
197 */
198 char *subsys;
199
200 /**
201 * The url 184 * The url
202 */ 185 */
203 char *url; 186 char *url;
204 187
205 /** 188 /**
206 * The data from the REST request 189 * Error response message
207 */
208 const char* data;
209
210 /**
211 * the length of the REST data
212 */
213 size_t data_size;
214
215 /**
216 * HTTP method
217 */ 190 */
218 const char* method; 191 char *emsg;
219 192
220 /** 193 /**
221 * Error response message 194 * Reponse code
222 */ 195 */
223 char *emsg; 196 int response_code;
224 197
225}; 198};
226 199
227
228/** 200/**
229 * Cleanup lookup handle 201 * Cleanup lookup handle
230 * @param handle Handle to clean up 202 * @param handle Handle to clean up
@@ -234,35 +206,37 @@ cleanup_handle (struct RequestHandle *handle)
234{ 206{
235 struct EgoEntry *ego_entry; 207 struct EgoEntry *ego_entry;
236 struct EgoEntry *ego_tmp; 208 struct EgoEntry *ego_tmp;
237 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 209
238 "Cleaning up\n"); 210 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
239 if (NULL != handle->name)
240 GNUNET_free (handle->name);
241 if (NULL != handle->timeout_task) 211 if (NULL != handle->timeout_task)
242 { 212 {
243 GNUNET_SCHEDULER_cancel (handle->timeout_task); 213 GNUNET_SCHEDULER_cancel (handle->timeout_task);
244 handle->timeout_task = NULL; 214 handle->timeout_task = NULL;
245 } 215 }
246 if (NULL != handle->identity_handle) 216
247 GNUNET_IDENTITY_disconnect (handle->identity_handle); 217 if (NULL != handle->subsystem)
248 if (NULL != handle->subsys) 218 GNUNET_free(handle->subsystem);
249 GNUNET_free (handle->subsys);
250 if (NULL != handle->url) 219 if (NULL != handle->url)
251 GNUNET_free (handle->url); 220 GNUNET_free(handle->url);
252 if (NULL != handle->emsg) 221 if (NULL != handle->emsg)
253 GNUNET_free (handle->emsg); 222 GNUNET_free(handle->emsg);
223 if (NULL != handle->name)
224 GNUNET_free (handle->name);
225 if (NULL != handle->identity_handle)
226 GNUNET_IDENTITY_disconnect (handle->identity_handle);
227
254 for (ego_entry = handle->ego_head; 228 for (ego_entry = handle->ego_head;
255 NULL != ego_entry;) 229 NULL != ego_entry;)
256 { 230 {
257 ego_tmp = ego_entry; 231 ego_tmp = ego_entry;
258 ego_entry = ego_entry->next; 232 ego_entry = ego_entry->next;
259 GNUNET_free (ego_tmp->identifier); 233 GNUNET_free(ego_tmp->identifier);
260 GNUNET_free (ego_tmp->keystring); 234 GNUNET_free(ego_tmp->keystring);
261 GNUNET_free (ego_tmp); 235 GNUNET_free(ego_tmp);
262 } 236 }
263 GNUNET_free (handle);
264}
265 237
238 GNUNET_free(handle);
239}
266 240
267/** 241/**
268 * Task run on errors. Reports an error and cleans up everything. 242 * Task run on errors. Reports an error and cleans up everything.
@@ -277,10 +251,12 @@ do_error (void *cls)
277 char *json_error; 251 char *json_error;
278 252
279 if (NULL == handle->emsg) 253 if (NULL == handle->emsg)
280 handle->emsg = GNUNET_strdup("Unknown Error"); 254 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_UNKNOWN);
281 255
282 GNUNET_asprintf (&json_error, "{\"error\": \"%s\"}", handle->emsg); 256 GNUNET_asprintf (&json_error, "{\"error\": \"%s\"}", handle->emsg);
283 handle->response_code = MHD_HTTP_OK; 257
258 if (0 == handle->response_code)
259 handle->response_code = MHD_HTTP_OK;
284 260
285 resp = GNUNET_REST_create_response (json_error); 261 resp = GNUNET_REST_create_response (json_error);
286 handle->proc (handle->proc_cls, resp, handle->response_code); 262 handle->proc (handle->proc_cls, resp, handle->response_code);
@@ -288,9 +264,8 @@ do_error (void *cls)
288 GNUNET_free(json_error); 264 GNUNET_free(json_error);
289} 265}
290 266
291
292/** 267/**
293 * Callback for IDENTITY_get() 268 * Callback for GET Request with subsystem
294 * 269 *
295 * @param cls the RequestHandle 270 * @param cls the RequestHandle
296 * @param ego the Ego found 271 * @param ego the Ego found
@@ -298,173 +273,153 @@ do_error (void *cls)
298 * @param name the id of the ego 273 * @param name the id of the ego
299 */ 274 */
300static void 275static void
301get_ego_for_subsys (void *cls, 276ego_get_for_subsystem (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx,
302 struct GNUNET_IDENTITY_Ego *ego, 277 const char *name)
303 void **ctx,
304 const char *name)
305{ 278{
306 struct RequestHandle *handle = cls; 279 struct RequestHandle *handle = cls;
307 struct EgoEntry *ego_entry;
308 struct MHD_Response *resp; 280 struct MHD_Response *resp;
281 struct GNUNET_CRYPTO_EcdsaPublicKey public_key;
309 json_t *json_root; 282 json_t *json_root;
310 json_t *json_ego;
311 json_t *name_json;
312 char *result_str; 283 char *result_str;
313 size_t index; 284 char *public_key_string;
314
315 json_root = json_array();
316 285
317 for (ego_entry = handle->ego_head; 286 if(NULL == ego)
318 NULL != ego_entry;
319 ego_entry = ego_entry->next)
320 { 287 {
321 if ( (NULL != name) && (0 != strcmp (name, ego_entry->identifier)) ) 288 handle->emsg = GNUNET_strdup("No identity found for subsystem");
322 continue;
323 if (NULL == name)
324 continue;
325
326 json_ego = json_object();
327 name_json = json_string (ego_entry->identifier);
328 json_object_set_new(json_ego, GNUNET_REST_JSON_IDENTITY_EGO, name_json);
329 json_array_append(json_root, json_ego);
330
331 break;
332 }
333
334 if (0 == json_array_size(json_root))
335 {
336 json_decref(json_root);
337 handle->emsg = GNUNET_strdup("No identity matches results!");
338 GNUNET_SCHEDULER_add_now (&do_error, handle); 289 GNUNET_SCHEDULER_add_now (&do_error, handle);
339 return; 290 return;
340 } 291 }
341 292
342 result_str = json_dumps(json_root, 0); 293 GNUNET_IDENTITY_ego_get_public_key(ego,&public_key);
343 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 294 public_key_string = GNUNET_CRYPTO_ecdsa_public_key_to_string(&public_key);
295
296 // create json with subsystem identity
297 json_root = json_object ();
298 json_object_set_new (json_root, GNUNET_REST_PARAM_PUBKEY, json_string(public_key_string));
299 json_object_set_new (json_root, GNUNET_REST_PARAM_NAME, json_string(name));
300
301 result_str = json_dumps (json_root, 0);
302 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
344 resp = GNUNET_REST_create_response (result_str); 303 resp = GNUNET_REST_create_response (result_str);
345 304
346 json_array_foreach(json_root, index, json_ego )
347 {
348 json_decref(json_ego);
349 }
350 json_decref (json_root); 305 json_decref (json_root);
351 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 306 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
352 GNUNET_free (result_str); 307 GNUNET_free(result_str);
308 GNUNET_free(public_key_string);
353 cleanup_handle (handle); 309 cleanup_handle (handle);
354} 310}
355 311
356
357/** 312/**
358 * Create a response with requested ego(s) 313 * Handle identity GET request
359 * 314 *
360 * @param con the Rest handle 315 * @param con_handle the connection handle
361 * @param url the requested url 316 * @param url the url
362 * @param cls the request handle 317 * @param cls the RequestHandle
363 */ 318 */
364static void 319void
365ego_info_response (struct GNUNET_REST_RequestHandle *con, 320ego_get (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
366 const char *url, 321 void *cls)
367 void *cls)
368{ 322{
369 const char *egoname;
370 char *result_str;
371 char *subsys_val;
372 char *keystring;
373 struct RequestHandle *handle = cls; 323 struct RequestHandle *handle = cls;
374 struct EgoEntry *ego_entry; 324 struct EgoEntry *ego_entry;
375 struct GNUNET_HashCode key; 325 struct GNUNET_HashCode key;
376 struct MHD_Response *resp; 326 struct MHD_Response *resp;
327 char *keystring;
328 const char *egoname;
377 json_t *json_root; 329 json_t *json_root;
378 json_t *json_ego; 330 json_t *json_ego;
379 json_t *name_str; 331 char *result_str;
380 size_t index; 332 size_t index;
381 333
382 if (GNUNET_NO == GNUNET_REST_namespace_match (handle->url, GNUNET_REST_API_NS_IDENTITY)) 334 //if subsystem
383 { 335 GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_SUBSYSTEM,
384 resp = GNUNET_REST_create_response (NULL); 336 strlen (GNUNET_REST_PARAM_SUBSYSTEM), &key);
385 handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST); 337 if ( GNUNET_YES
386 cleanup_handle (handle); 338 == GNUNET_CONTAINER_multihashmap_contains (
339 handle->rest_handle->url_param_map, &key))
340 {
341 handle->subsystem = GNUNET_strdup(
342 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
343 &key));
344 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n",
345 handle->subsystem);
346
347 handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
348 handle->subsystem, &ego_get_for_subsystem,
349 handle);
350 if (NULL == handle->op)
351 {
352 handle->emsg = GNUNET_strdup("No identity found for subsystem");
353 GNUNET_SCHEDULER_add_now (&do_error, handle);
354 return;
355 }
387 return; 356 return;
388 } 357 }
389 egoname = NULL; 358 egoname = NULL;
390 keystring = NULL; 359 keystring = NULL;
391 if (strlen (GNUNET_REST_API_NS_IDENTITY) < strlen (handle->url)) 360
361 //if only one identity requested
362 GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_PUBKEY,
363 strlen (GNUNET_REST_PARAM_PUBKEY), &key);
364 if ( GNUNET_YES
365 == GNUNET_CONTAINER_multihashmap_contains (
366 handle->rest_handle->url_param_map, &key))
392 { 367 {
393 keystring = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY)+1]; 368 keystring = GNUNET_CONTAINER_multihashmap_get (
394 //Return all egos 369 handle->rest_handle->url_param_map, &key);
370
395 for (ego_entry = handle->ego_head; 371 for (ego_entry = handle->ego_head;
396 NULL != ego_entry; 372 NULL != ego_entry; ego_entry = ego_entry->next)
397 ego_entry = ego_entry->next)
398 { 373 {
399 if ( (NULL != keystring) && (0 != strcmp (keystring, ego_entry->keystring)) ) 374 if ((NULL != keystring)
400 continue; 375 && (0 != strcmp (keystring, ego_entry->keystring)))
376 continue;
401 egoname = ego_entry->identifier; 377 egoname = ego_entry->identifier;
402 } 378 }
403 } 379 }
404 380
405 if ( NULL == egoname ) { 381 json_root = json_array ();
406 GNUNET_CRYPTO_hash (GNUNET_REST_JSON_IDENTITY_SUBSYSTEM, 382 //Return ego/egos
407 strlen (GNUNET_REST_JSON_IDENTITY_SUBSYSTEM),
408 &key);
409 if ( GNUNET_YES ==
410 GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
411 &key) )
412 {
413 subsys_val = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
414 &key);
415 if (NULL != subsys_val)
416 {
417 GNUNET_asprintf (&handle->subsys, "%s", subsys_val);
418 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsys_val);
419 handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
420 handle->subsys,
421 &get_ego_for_subsys,
422 handle);
423 return;
424 }
425 }
426 }
427
428 json_root = json_array();
429
430 //Return all egos
431 for (ego_entry = handle->ego_head; 383 for (ego_entry = handle->ego_head;
432 NULL != ego_entry; 384 NULL != ego_entry; ego_entry = ego_entry->next)
433 ego_entry = ego_entry->next)
434 { 385 {
435 if ( (NULL != egoname) && (0 != strcmp (egoname, ego_entry->identifier)) ) 386 //if only one ego requested
436 continue; 387 if ((NULL != egoname)){
437 388 if(0 != strcmp (egoname, ego_entry->identifier)){
438 json_ego = json_object(); 389 continue;
439 390 }
440 json_object_set_new( json_ego, "id", json_string (ego_entry->keystring)); 391 }
441 json_object_set_new( json_ego, "type", json_string (GNUNET_REST_JSON_IDENTITY_EGO));
442 name_str = json_string (ego_entry->identifier);
443 json_object_set_new( json_ego, "name", name_str);
444 392
445 json_array_append( json_root, json_ego ); 393 json_ego = json_object ();
394 json_object_set_new (json_ego,
395 GNUNET_REST_PARAM_PUBKEY,
396 json_string (ego_entry->keystring));
397 json_object_set_new (json_ego,
398 GNUNET_REST_PARAM_NAME,
399 json_string (ego_entry->identifier));
400 json_array_append (json_root, json_ego);
446 } 401 }
447 402
448 if ((size_t)0 == json_array_size(json_root)) 403 if ((size_t) 0 == json_array_size (json_root))
449 { 404 {
450 json_decref (json_root); 405 json_decref (json_root);
451 handle->emsg = GNUNET_strdup ("No identities found!"); 406 handle->emsg = GNUNET_strdup("No identities found!");
452 GNUNET_SCHEDULER_add_now (&do_error, handle); 407 GNUNET_SCHEDULER_add_now (&do_error, handle);
453 return; 408 return;
454 } 409 }
455 410
456 result_str = json_dumps(json_root, 0); 411 result_str = json_dumps (json_root, 0);
457 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 412 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
458 resp = GNUNET_REST_create_response (result_str); 413 resp = GNUNET_REST_create_response (result_str);
459 414
460 //delete json_objects in json_array with macro 415 //delete json_objects in json_array with macro
461 json_array_foreach(json_root, index, json_ego ) 416 json_array_foreach(json_root, index, json_ego )
462 { 417 {
463 json_decref(json_ego); 418 json_decref (json_ego);
464 } 419 }
465 json_decref (json_root); 420 json_decref (json_root);
466 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 421 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
467 GNUNET_free (result_str); 422 GNUNET_free(result_str);
468 cleanup_handle (handle); 423 cleanup_handle (handle);
469} 424}
470 425
@@ -483,7 +438,7 @@ do_finished (void *cls, const char *emsg)
483 handle->op = NULL; 438 handle->op = NULL;
484 if (NULL != emsg) 439 if (NULL != emsg)
485 { 440 {
486 handle->emsg = GNUNET_strdup (emsg); 441 handle->emsg = GNUNET_strdup(emsg);
487 GNUNET_SCHEDULER_add_now (&do_error, handle); 442 GNUNET_SCHEDULER_add_now (&do_error, handle);
488 return; 443 return;
489 } 444 }
@@ -493,288 +448,280 @@ do_finished (void *cls, const char *emsg)
493} 448}
494 449
495/** 450/**
496 * Create a new ego 451 * Handle identity PUT request
497 * 452 *
498 * @param con rest handle 453 * @param con_handle the connection handle
499 * @param url url 454 * @param url the url
500 * @param cls request handle 455 * @param cls the RequestHandle
501 */ 456 */
502static void 457void
503ego_create_cont (struct GNUNET_REST_RequestHandle *con, 458ego_edit (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
504 const char *url, 459 void *cls)
505 void *cls)
506{ 460{
507 struct RequestHandle *handle = cls; 461 struct RequestHandle *handle = cls;
508 struct EgoEntry *ego_entry; 462 struct EgoEntry *ego_entry;
463 struct EgoEntry *ego_entry_tmp;
509 struct MHD_Response *resp; 464 struct MHD_Response *resp;
510 json_t *egoname_json; 465 json_t *subsys_json;
466 json_t *name_json;
467 json_t *key_json;
511 json_t *data_js; 468 json_t *data_js;
512 json_error_t err; 469 json_error_t err;
513 const char* egoname; 470 const char *keystring;
514 char term_data[handle->data_size+1]; 471 const char *subsys;
515 472 const char *newname;
516 if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url)) 473 char term_data[handle->data_size + 1];
517 { 474 int ego_exists = GNUNET_NO;
518 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID);
519 GNUNET_SCHEDULER_add_now (&do_error, handle);
520 return;
521 }
522 475
476 //if no data
523 if (0 >= handle->data_size) 477 if (0 >= handle->data_size)
524 { 478 {
525 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA); 479 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
526 GNUNET_SCHEDULER_add_now (&do_error, handle); 480 GNUNET_SCHEDULER_add_now (&do_error, handle);
527 return; 481 return;
528 } 482 }
483 //if not json
529 term_data[handle->data_size] = '\0'; 484 term_data[handle->data_size] = '\0';
530 GNUNET_memcpy (term_data, handle->data, handle->data_size); 485 GNUNET_memcpy(term_data, handle->data, handle->data_size);
531 data_js = json_loads (term_data, 486 data_js = json_loads (term_data,JSON_DECODE_ANY,&err);
532 JSON_DECODE_ANY,
533 &err);
534
535
536 if (NULL == data_js) 487 if (NULL == data_js)
537 { 488 {
538 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID); 489 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
539 GNUNET_SCHEDULER_add_now (&do_error, handle); 490 GNUNET_SCHEDULER_add_now (&do_error, handle);
540 return; 491 return;
541 } 492 }
542 //instead of parse
543 if (!json_is_object(data_js)) 493 if (!json_is_object(data_js))
544 { 494 {
545 json_decref(data_js); 495 json_decref (data_js);
546 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID); 496 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
547 GNUNET_SCHEDULER_add_now (&do_error, handle); 497 GNUNET_SCHEDULER_add_now (&do_error, handle);
548 return; 498 return;
549 } 499 }
550 500 //json must contain pubkey and (subsystem or name)
551 if (1 != json_object_size (data_js)) 501 if (2 != json_object_size (data_js))
552 { 502 {
553 json_decref (data_js); 503 json_decref (data_js);
554 handle->emsg = GNUNET_strdup("Provided resource count invalid"); 504 handle->emsg = GNUNET_strdup("Resource amount invalid");
555 GNUNET_SCHEDULER_add_now (&do_error, handle); 505 GNUNET_SCHEDULER_add_now (&do_error, handle);
556 return; 506 return;
557 } 507 }
558 508
559 egoname_json = json_object_get (data_js, GNUNET_REST_JSON_IDENTITY_NAME); 509 key_json = json_object_get (data_js, GNUNET_REST_PARAM_PUBKEY);
560 if (!json_is_string (egoname_json)) 510 if ((NULL == key_json) || !json_is_string(key_json))
561 { 511 {
562 json_decref (data_js); 512 json_decref (data_js);
563 handle->emsg = GNUNET_strdup ("No name provided"); 513 handle->emsg = GNUNET_strdup("Missing element pubkey");
564 GNUNET_SCHEDULER_add_now (&do_error, handle); 514 GNUNET_SCHEDULER_add_now (&do_error, handle);
565 return; 515 return;
566 } 516 }
567 egoname = json_string_value (egoname_json); 517 keystring = json_string_value (key_json);
568 if(0 >= strlen(egoname)) 518
519 for (ego_entry = handle->ego_head;
520 NULL != ego_entry; ego_entry = ego_entry->next)
521 {
522 if (0 != strcasecmp (keystring, ego_entry->keystring))
523 continue;
524 ego_exists = GNUNET_YES;
525 break;
526 }
527
528 if (GNUNET_NO == ego_exists)
569 { 529 {
570 json_decref (data_js); 530 json_decref (data_js);
571 handle->emsg = GNUNET_strdup ("No name provided"); 531 resp = GNUNET_REST_create_response (NULL);
572 GNUNET_SCHEDULER_add_now (&do_error, handle); 532 handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
533 cleanup_handle (handle);
573 return; 534 return;
574 } 535 }
575 for (ego_entry = handle->ego_head; 536 //This is a rename
576 NULL != ego_entry; 537 name_json = json_object_get (data_js, GNUNET_REST_PARAM_NEWNAME);
577 ego_entry = ego_entry->next) 538 if ((NULL != name_json) && json_is_string(name_json))
578 { 539 {
579 if (0 == strcasecmp (egoname, ego_entry->identifier)) 540 newname = json_string_value (name_json);
541 if (0 >= strlen (newname))
580 { 542 {
581 json_decref (data_js); 543 json_decref (data_js);
582 resp = GNUNET_REST_create_response (NULL); 544 handle->emsg = GNUNET_strdup("No name provided");
583 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); 545 GNUNET_SCHEDULER_add_now (&do_error, handle);
584 cleanup_handle (handle);
585 return; 546 return;
586 } 547 }
548 for (ego_entry_tmp = handle->ego_head;
549 NULL != ego_entry_tmp; ego_entry_tmp = ego_entry_tmp->next)
550 {
551 if (0 == strcasecmp (newname, ego_entry_tmp->identifier)
552 && 0 != strcasecmp (keystring, ego_entry_tmp->keystring))
553 {
554 //Ego with same name not allowed
555 json_decref (data_js);
556 resp = GNUNET_REST_create_response (NULL);
557 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
558 cleanup_handle (handle);
559 return;
560 }
561 }
562 handle->response_code = MHD_HTTP_NO_CONTENT;
563 handle->op = GNUNET_IDENTITY_rename (handle->identity_handle,
564 ego_entry->identifier, newname,
565 &do_finished, handle);
566 json_decref (data_js);
567 return;
568 }
569
570 //Set subsystem
571 subsys_json = json_object_get (data_js, GNUNET_REST_PARAM_SUBSYSTEM);
572 if ((NULL != subsys_json) && json_is_string(subsys_json))
573 {
574 subsys = json_string_value (subsys_json);
575 if (0 >= strlen (subsys))
576 {
577 json_decref (data_js);
578 handle->emsg = GNUNET_strdup("Invalid subsystem name");
579 GNUNET_SCHEDULER_add_now (&do_error, handle);
580 return;
581 }
582 GNUNET_asprintf (&handle->subsystem, "%s", subsys);
583 json_decref (data_js);
584 handle->response_code = MHD_HTTP_NO_CONTENT;
585 handle->op = GNUNET_IDENTITY_set (handle->identity_handle, handle->subsystem,
586 ego_entry->ego, &do_finished, handle);
587 return;
587 } 588 }
588 GNUNET_asprintf (&handle->name, "%s", egoname);
589 json_decref (data_js); 589 json_decref (data_js);
590 handle->response_code = MHD_HTTP_CREATED; 590 handle->emsg = GNUNET_strdup("Subsystem not provided");
591 handle->op = GNUNET_IDENTITY_create (handle->identity_handle, 591 GNUNET_SCHEDULER_add_now (&do_error, handle);
592 handle->name,
593 &do_finished,
594 handle);
595} 592}
596 593
597
598/** 594/**
599 * Handle ego edit request 595 * Handle identity POST request
600 * 596 *
601 * @param con rest connection handle 597 * @param con_handle the connection handle
602 * @param url the url that is requested 598 * @param url the url
603 * @param cls the RequestHandle 599 * @param cls the RequestHandle
604 */ 600 */
605static void 601void
606ego_edit_cont (struct GNUNET_REST_RequestHandle *con, 602ego_create (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
607 const char *url, 603 void *cls)
608 void *cls)
609{ 604{
610 struct RequestHandle *handle = cls; 605 struct RequestHandle *handle = cls;
611 struct EgoEntry *ego_entry; 606 struct EgoEntry *ego_entry;
612 struct EgoEntry *ego_entry_tmp;
613 struct MHD_Response *resp; 607 struct MHD_Response *resp;
614 json_t *subsys_json; 608 json_t *egoname_json;
615 json_t *name_json;
616 json_t *data_js; 609 json_t *data_js;
617 json_error_t err; 610 json_error_t err;
618 const char *keystring; 611 const char* egoname;
619 const char *subsys; 612 char term_data[handle->data_size + 1];
620 const char *newname;
621 char term_data[handle->data_size+1];
622 int ego_exists = GNUNET_NO;
623 613
624 if (strlen (GNUNET_REST_API_NS_IDENTITY) > strlen (handle->url)) 614 if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url))
625 { 615 {
626 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID); 616 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_RESOURCE_INVALID);
627 GNUNET_SCHEDULER_add_now (&do_error, handle); 617 GNUNET_SCHEDULER_add_now (&do_error, handle);
628 return; 618 return;
629 } 619 }
630 620
631 keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY)+1];
632
633 for (ego_entry = handle->ego_head;
634 NULL != ego_entry;
635 ego_entry = ego_entry->next)
636 {
637 if (0 != strcasecmp (keystring, ego_entry->keystring))
638 continue;
639 ego_exists = GNUNET_YES;
640 break;
641 }
642
643 if (GNUNET_NO == ego_exists)
644 {
645 resp = GNUNET_REST_create_response (NULL);
646 handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
647 cleanup_handle (handle);
648 return;
649 }
650
651 if (0 >= handle->data_size) 621 if (0 >= handle->data_size)
652 { 622 {
653 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA); 623 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
654 GNUNET_SCHEDULER_add_now (&do_error, handle); 624 GNUNET_SCHEDULER_add_now (&do_error, handle);
655 return; 625 return;
656 } 626 }
657
658 term_data[handle->data_size] = '\0'; 627 term_data[handle->data_size] = '\0';
659 GNUNET_memcpy (term_data, handle->data, handle->data_size); 628 GNUNET_memcpy(term_data, handle->data, handle->data_size);
660 data_js = json_loads (term_data, 629 data_js = json_loads (term_data,
661 JSON_DECODE_ANY, 630 JSON_DECODE_ANY,
662 &err); 631 &err);
632
663 if (NULL == data_js) 633 if (NULL == data_js)
664 { 634 {
665 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA); 635 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
666 GNUNET_SCHEDULER_add_now (&do_error, handle); 636 GNUNET_SCHEDULER_add_now (&do_error, handle);
667 return; 637 return;
668 } 638 }
639 //instead of parse
669 if (!json_is_object(data_js)) 640 if (!json_is_object(data_js))
670 { 641 {
671 json_decref (data_js); 642 json_decref (data_js);
672 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID); 643 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
673 GNUNET_SCHEDULER_add_now (&do_error, handle); 644 GNUNET_SCHEDULER_add_now (&do_error, handle);
674 return; 645 return;
675 } 646 }
676 647
677 if (1 != json_object_size(data_js)) 648 if (1 != json_object_size (data_js))
678 { 649 {
679 json_decref (data_js); 650 json_decref (data_js);
680 handle->emsg = GNUNET_strdup ("Resource amount invalid"); 651 handle->emsg = GNUNET_strdup("Provided resource count invalid");
681 GNUNET_SCHEDULER_add_now (&do_error, handle); 652 GNUNET_SCHEDULER_add_now (&do_error, handle);
682 return; 653 return;
683 } 654 }
684 655
685 //This is a rename 656 egoname_json = json_object_get (data_js, GNUNET_REST_PARAM_NAME);
686 name_json = json_object_get (data_js, GNUNET_REST_JSON_IDENTITY_NEWNAME); 657 if (!json_is_string(egoname_json))
687 if ((NULL != name_json) && json_is_string (name_json))
688 { 658 {
689 newname = json_string_value (name_json);
690 if(0 >= strlen(newname))
691 {
692 json_decref (data_js);
693 handle->emsg = GNUNET_strdup ("No name provided");
694 GNUNET_SCHEDULER_add_now (&do_error, handle);
695 return;
696 }
697 for (ego_entry_tmp = handle->ego_head;
698 NULL != ego_entry_tmp;
699 ego_entry_tmp = ego_entry_tmp->next)
700 {
701 if (0 == strcasecmp (newname, ego_entry_tmp->identifier) &&
702 0 != strcasecmp (keystring, ego_entry_tmp->keystring))
703 {
704 //Ego with same name not allowed
705 json_decref (data_js);
706 resp = GNUNET_REST_create_response (NULL);
707 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
708 cleanup_handle (handle);
709 return;
710 }
711 }
712 handle->response_code = MHD_HTTP_NO_CONTENT;
713 handle->op = GNUNET_IDENTITY_rename (handle->identity_handle,
714 ego_entry->identifier,
715 newname,
716 &do_finished,
717 handle);
718 json_decref (data_js); 659 json_decref (data_js);
660 handle->emsg = GNUNET_strdup("No name provided");
661 GNUNET_SCHEDULER_add_now (&do_error, handle);
719 return; 662 return;
720 } 663 }
721 664 egoname = json_string_value (egoname_json);
722 //Set subsystem 665 if (0 >= strlen (egoname))
723 subsys_json = json_object_get (data_js, GNUNET_REST_JSON_IDENTITY_SUBSYSTEM);
724 if ( (NULL != subsys_json) && json_is_string (subsys_json))
725 { 666 {
726 subsys = json_string_value (subsys_json); 667 json_decref (data_js);
727 if(0 >= strlen(subsys)) 668 handle->emsg = GNUNET_strdup("No name provided");
669 GNUNET_SCHEDULER_add_now (&do_error, handle);
670 return;
671 }
672 for (ego_entry = handle->ego_head;
673 NULL != ego_entry; ego_entry = ego_entry->next)
674 {
675 if (0 == strcasecmp (egoname, ego_entry->identifier))
728 { 676 {
729 json_decref (data_js); 677 json_decref (data_js);
730 handle->emsg = GNUNET_strdup ("No name provided"); 678 resp = GNUNET_REST_create_response (NULL);
731 GNUNET_SCHEDULER_add_now (&do_error, handle); 679 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
680 cleanup_handle (handle);
732 return; 681 return;
733 } 682 }
734 GNUNET_asprintf (&handle->subsys, "%s", subsys);
735 json_decref (data_js);
736 handle->response_code = MHD_HTTP_NO_CONTENT;
737 handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
738 handle->subsys,
739 ego_entry->ego,
740 &do_finished,
741 handle);
742 return;
743 } 683 }
684 GNUNET_asprintf (&handle->name, "%s", egoname);
744 json_decref (data_js); 685 json_decref (data_js);
745 handle->emsg = GNUNET_strdup ("Subsystem not provided"); 686 handle->response_code = MHD_HTTP_CREATED;
746 GNUNET_SCHEDULER_add_now (&do_error, handle); 687 handle->op = GNUNET_IDENTITY_create (handle->identity_handle, handle->name,
688 &do_finished, handle);
747} 689}
748 690
749/** 691/**
750 * Handle ego delete request 692 * Handle identity DELETE request
751 * 693 *
752 * @param con_handle the connection handle 694 * @param con_handle the connection handle
753 * @param url the url 695 * @param url the url
754 * @param cls the RequestHandle 696 * @param cls the RequestHandle
755 */ 697 */
756void 698void
757ego_delete_cont (struct GNUNET_REST_RequestHandle *con_handle, 699ego_delete (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
758 const char* url, 700 void *cls)
759 void *cls)
760{ 701{
761 const char *keystring; 702 const char *keystring;
762 struct EgoEntry *ego_entry; 703 struct EgoEntry *ego_entry;
704 struct GNUNET_HashCode key;
763 struct MHD_Response *resp; 705 struct MHD_Response *resp;
764 struct RequestHandle *handle = cls; 706 struct RequestHandle *handle = cls;
765 int ego_exists = GNUNET_NO; 707 int ego_exists = GNUNET_NO;
766 708
767 if (strlen (GNUNET_REST_API_NS_IDENTITY) >= strlen (handle->url)) 709 //if only one identity requested
710 GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_PUBKEY,
711 strlen (GNUNET_REST_PARAM_PUBKEY), &key);
712 if ( GNUNET_NO
713 == GNUNET_CONTAINER_multihashmap_contains (
714 handle->rest_handle->url_param_map, &key))
768 { 715 {
769 handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID); 716 handle->emsg = GNUNET_strdup("Missing parameter pubkey");
770 GNUNET_SCHEDULER_add_now (&do_error, handle); 717 GNUNET_SCHEDULER_add_now (&do_error, handle);
771 return; 718 return;
772 } 719 }
773 720
774 keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY)+1]; 721 keystring = GNUNET_CONTAINER_multihashmap_get (
722 handle->rest_handle->url_param_map,&key);
775 for (ego_entry = handle->ego_head; 723 for (ego_entry = handle->ego_head;
776 NULL != ego_entry; 724 NULL != ego_entry; ego_entry = ego_entry->next)
777 ego_entry = ego_entry->next)
778 { 725 {
779 if (0 != strcasecmp (keystring, ego_entry->keystring)) 726 if (0 != strcasecmp (keystring, ego_entry->keystring))
780 continue; 727 continue;
@@ -790,13 +737,11 @@ ego_delete_cont (struct GNUNET_REST_RequestHandle *con_handle,
790 } 737 }
791 handle->response_code = MHD_HTTP_NO_CONTENT; 738 handle->response_code = MHD_HTTP_NO_CONTENT;
792 handle->op = GNUNET_IDENTITY_delete (handle->identity_handle, 739 handle->op = GNUNET_IDENTITY_delete (handle->identity_handle,
793 ego_entry->identifier, 740 ego_entry->identifier, &do_finished,
794 &do_finished, 741 handle);
795 handle);
796 742
797} 743}
798 744
799
800/** 745/**
801 * Respond to OPTIONS request 746 * Respond to OPTIONS request
802 * 747 *
@@ -805,18 +750,15 @@ ego_delete_cont (struct GNUNET_REST_RequestHandle *con_handle,
805 * @param cls the RequestHandle 750 * @param cls the RequestHandle
806 */ 751 */
807static void 752static void
808options_cont (struct GNUNET_REST_RequestHandle *con_handle, 753options_cont (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
809 const char* url, 754 void *cls)
810 void *cls)
811{ 755{
812 struct MHD_Response *resp; 756 struct MHD_Response *resp;
813 struct RequestHandle *handle = cls; 757 struct RequestHandle *handle = cls;
814 758
815 //For now, independent of path return all options 759 //For now, independent of path return all options
816 resp = GNUNET_REST_create_response (NULL); 760 resp = GNUNET_REST_create_response (NULL);
817 MHD_add_response_header (resp, 761 MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
818 "Access-Control-Allow-Methods",
819 allow_methods);
820 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 762 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
821 cleanup_handle (handle); 763 cleanup_handle (handle);
822 return; 764 return;
@@ -832,18 +774,17 @@ init_cont (struct RequestHandle *handle)
832{ 774{
833 struct GNUNET_REST_RequestHandlerError err; 775 struct GNUNET_REST_RequestHandlerError err;
834 static const struct GNUNET_REST_RequestHandler handlers[] = { 776 static const struct GNUNET_REST_RequestHandler handlers[] = {
835 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_info_response}, 777 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get },
836 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create_cont}, 778 { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY, &ego_edit },
837 {MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY, &ego_edit_cont}, 779 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create },
838 {MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_IDENTITY, &ego_delete_cont}, 780 { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_IDENTITY, &ego_delete },
839 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont}, 781 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont },
840 GNUNET_REST_HANDLER_END 782 GNUNET_REST_HANDLER_END
841 }; 783 };
842 784
843 if (GNUNET_NO == GNUNET_REST_handle_request (handle->conndata_handle, 785 if (GNUNET_NO
844 handlers, 786 == GNUNET_REST_handle_request (handle->rest_handle, handlers, &err,
845 &err, 787 handle))
846 handle))
847 { 788 {
848 handle->response_code = err.error_code; 789 handle->response_code = err.error_code;
849 GNUNET_SCHEDULER_add_now (&do_error, handle); 790 GNUNET_SCHEDULER_add_now (&do_error, handle);
@@ -884,10 +825,8 @@ init_cont (struct RequestHandle *handle)
884 * must thus no longer be used 825 * must thus no longer be used
885 */ 826 */
886static void 827static void
887list_ego (void *cls, 828init_egos (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx,
888 struct GNUNET_IDENTITY_Ego *ego, 829 const char *identifier)
889 void **ctx,
890 const char *identifier)
891{ 830{
892 struct RequestHandle *handle = cls; 831 struct RequestHandle *handle = cls;
893 struct EgoEntry *ego_entry; 832 struct EgoEntry *ego_entry;
@@ -899,16 +838,16 @@ list_ego (void *cls,
899 init_cont (handle); 838 init_cont (handle);
900 return; 839 return;
901 } 840 }
902 if (ID_REST_STATE_INIT == handle->state) { 841 if (ID_REST_STATE_INIT == handle->state)
903 ego_entry = GNUNET_new (struct EgoEntry); 842 {
843 ego_entry = GNUNET_new(struct EgoEntry);
904 GNUNET_IDENTITY_ego_get_public_key (ego, &pk); 844 GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
905 ego_entry->keystring = 845 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
906 GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
907 ego_entry->ego = ego; 846 ego_entry->ego = ego;
908 GNUNET_asprintf (&ego_entry->identifier, "%s", identifier); 847 GNUNET_asprintf (&ego_entry->identifier, "%s", identifier);
909 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry); 848 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head, handle->ego_tail,
849 ego_entry);
910 } 850 }
911
912} 851}
913 852
914/** 853/**
@@ -923,39 +862,30 @@ list_ego (void *cls,
923 * @return GNUNET_OK if request accepted 862 * @return GNUNET_OK if request accepted
924 */ 863 */
925static void 864static void
926rest_identity_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, 865rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
927 GNUNET_REST_ResultProcessor proc, 866 GNUNET_REST_ResultProcessor proc, void *proc_cls)
928 void *proc_cls)
929{ 867{
930 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 868 struct RequestHandle *handle = GNUNET_new(struct RequestHandle);
931
932
933 869
870 handle->response_code = 0;
934 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 871 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
935 handle->response_code = MHD_HTTP_OK;
936 handle->proc_cls = proc_cls; 872 handle->proc_cls = proc_cls;
937 handle->proc = proc; 873 handle->proc = proc;
938 handle->state = ID_REST_STATE_INIT; 874 handle->rest_handle = rest_handle;
939 handle->conndata_handle = conndata_handle; 875 handle->data = rest_handle->data;
940 handle->data = conndata_handle->data; 876 handle->data_size = rest_handle->data_size;
941 handle->data_size = conndata_handle->data_size; 877
942 handle->method = conndata_handle->method; 878 handle->url = GNUNET_strdup(rest_handle->url);
943 GNUNET_asprintf (&handle->url, "%s", conndata_handle->url); 879 if (handle->url[strlen (handle->url) - 1] == '/')
944 if (handle->url[strlen (handle->url)-1] == '/') 880 handle->url[strlen (handle->url) - 1] = '\0';
945 handle->url[strlen (handle->url)-1] = '\0'; 881 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 882
947 "Connecting...\n"); 883 handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &init_egos, handle);
948 handle->identity_handle = GNUNET_IDENTITY_connect (cfg, 884
949 &list_ego, 885 handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
950 handle); 886 &do_error, handle);
951 handle->timeout_task = 887
952 GNUNET_SCHEDULER_add_delayed (handle->timeout, 888 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
953 &do_error,
954 handle);
955
956
957 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
958 "Connected\n");
959} 889}
960 890
961/** 891/**
@@ -972,27 +902,24 @@ libgnunet_plugin_rest_identity_init (void *cls)
972 902
973 cfg = cls; 903 cfg = cls;
974 if (NULL != plugin.cfg) 904 if (NULL != plugin.cfg)
975 return NULL; /* can only initialize once! */ 905 return NULL; /* can only initialize once! */
976 memset (&plugin, 0, sizeof (struct Plugin)); 906 memset (&plugin, 0, sizeof(struct Plugin));
977 plugin.cfg = cfg; 907 plugin.cfg = cfg;
978 api = GNUNET_new (struct GNUNET_REST_Plugin); 908 api = GNUNET_new(struct GNUNET_REST_Plugin);
979 api->cls = &plugin; 909 api->cls = &plugin;
980 api->name = GNUNET_REST_API_NS_IDENTITY; 910 api->name = GNUNET_REST_API_NS_IDENTITY;
981 api->process_request = &rest_identity_process_request; 911 api->process_request = &rest_process_request;
982 GNUNET_asprintf (&allow_methods, 912 GNUNET_asprintf (&allow_methods, "%s, %s, %s, %s, %s",
983 "%s, %s, %s, %s, %s", 913 MHD_HTTP_METHOD_GET,
984 MHD_HTTP_METHOD_GET, 914 MHD_HTTP_METHOD_POST,
985 MHD_HTTP_METHOD_POST, 915 MHD_HTTP_METHOD_PUT,
986 MHD_HTTP_METHOD_PUT, 916 MHD_HTTP_METHOD_DELETE,
987 MHD_HTTP_METHOD_DELETE, 917 MHD_HTTP_METHOD_OPTIONS);
988 MHD_HTTP_METHOD_OPTIONS); 918
989 919 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, _("Identity REST API initialized\n"));
990 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
991 _("Identity REST API initialized\n"));
992 return api; 920 return api;
993} 921}
994 922
995
996/** 923/**
997 * Exit point from the plugin. 924 * Exit point from the plugin.
998 * 925 *
@@ -1004,13 +931,13 @@ libgnunet_plugin_rest_identity_done (void *cls)
1004{ 931{
1005 struct GNUNET_REST_Plugin *api = cls; 932 struct GNUNET_REST_Plugin *api = cls;
1006 struct Plugin *plugin = api->cls; 933 struct Plugin *plugin = api->cls;
1007
1008 plugin->cfg = NULL; 934 plugin->cfg = NULL;
1009 GNUNET_free_non_null (allow_methods); 935
1010 GNUNET_free (api); 936 GNUNET_free_non_null(allow_methods);
1011 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 937 GNUNET_free(api);
1012 "Identity REST plugin is finished\n"); 938 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Identity REST plugin is finished\n");
1013 return NULL; 939 return NULL;
1014} 940}
1015 941
1016/* end of plugin_rest_gns.c */ 942/* end of plugin_rest_identity.c */
943
diff --git a/src/identity/test_plugin_rest_identity.sh b/src/identity/test_plugin_rest_identity.sh
new file mode 100755
index 000000000..b48becc45
--- /dev/null
+++ b/src/identity/test_plugin_rest_identity.sh
@@ -0,0 +1,216 @@
1#!/usr/bin/bash
2
3#First, start gnunet-arm and the rest-service. Make sure, no identity exists
4#Exit 0 means success, exit 1 means failed test
5
6#No test for subsystem available
7
8link_to_api="http://localhost:7776/identity"
9wrong_link="http://localhost:7776/idenmmmy"
10wrong_link2="http://localhost:7776/identityandmore"
11
12#Test GET (multiple identities) for error when no identity exists
13#The next test case can be ignored if you have already added identities
14cache="$(curl --silent "$link_to_api" | grep "error")"
15if [ "" == "$cache" ]
16then
17 exit 1
18fi
19
20#Test POST success code, error response code and error json
21#The next test case can be ignored if you have already added an identity with the name Test
22cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":\"Test\"}" 2>&1 | grep "HTTP/1.1 201")"
23if [ "" == "$cache" ]
24then
25 exit 1
26fi
27
28cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":\"Test\"}" 2>&1 | grep "HTTP/1.1 409")"
29if [ "" == "$cache" ]
30then
31 exit 1
32fi
33
34cache="$(curl -v -X "POST" "$link_to_api" 2>&1 | grep "error")"
35if [ "" == "$cache" ]
36then
37 exit 1
38fi
39
40cache="$(curl -v -X "POST" "$link_to_api" --data "wrong" 2>&1 | grep "error")"
41if [ "" == "$cache" ]
42then
43 exit 1
44fi
45
46cache="$(curl -v -X "POST" "$link_to_api" --data "[{}]" 2>&1 | grep "error")"
47if [ "" == "$cache" ]
48then
49 exit 1
50fi
51
52cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":\"Test\",\"other\":\"Test\"}" 2>&1 | grep "error")"
53if [ "" == "$cache" ]
54then
55 exit 1
56fi
57
58cache="$(curl -v -X "POST" "$link_to_api" --data "{\"nam\":\"Test\"}" 2>&1 | grep "error")"
59if [ "" == "$cache" ]
60then
61 exit 1
62fi
63
64cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":123}" 2>&1 | grep "error")"
65if [ "" == "$cache" ]
66then
67 exit 1
68fi
69
70cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":""}" 2>&1 | grep "error")"
71if [ "" == "$cache" ]
72then
73 exit 1
74fi
75
76
77#Test GET (multiple identities) for success and error json
78cache="$(curl --silent "$link_to_api" | grep "error")"
79if [ "" != "$cache" ]
80then
81 exit 1
82fi
83
84
85id="$(gnunet-identity -d | grep "Test - " | sed "s/Test - //g")"
86#Test GET (one identity) for success and error json
87cache="$(curl --silent "${link_to_api}?pubkey=$id" | grep "error")"
88if [ "" != "$cache" ]
89then
90 exit 1
91fi
92
93
94#Test DELETE success code, error response code and error json
95#echo "Next tests for DELETE will probably fail when POST fails"
96cache="$(curl -v -X "DELETE" "${link_to_api}?pubkey=$id" 2>&1 | grep "HTTP/1.1 404")"
97if [ "" != "$cache" ]
98then
99 exit 1
100fi
101
102curl --silent -X "POST" "$link_to_api" --data "{\"name\":\"Test\"}"
103id="$(gnunet-identity -d | grep "Test - " | sed "s/Test - //g")"
104
105cache="$(curl -v -X "DELETE" "${link_to_api}?pubkey=df1" 2>&1 | grep "HTTP/1.1 404")"
106if [ "" == "$cache" ]
107then
108 exit 1
109fi
110
111cache="$(curl -v -X "DELETE" "${link_to_api}?pubke=$id" 2>&1 | grep "error")"
112if [ "" == "$cache" ]
113then
114 exit 1
115fi
116
117#Test PUT success code, error response codes and error json
118cache="$(curl -v -X "PUT" "${link_to_api}" --data "{\"newname\":\"NewTest\",\"pubkey\":\"${id}\"}" 2>&1 | grep "HTTP/1.1 204")"
119if [ "" == "$cache" ]
120then
121 exit 1
122fi
123
124cache="$(curl -v -X "PUT" "${link_to_api}" --data "{\"newname\":\"NewNewTest\",\"pubkey\":\"${id}1\"}" 2>&1 | grep "HTTP/1.1 404")"
125if [ "" == "$cache" ]
126then
127 exit 1
128fi
129
130# feature: you can rename your identity with its own name.
131# cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newname\":\"NewTest\",\"pubkey\":\"${id}\"}" 2>&1 | grep "error")"
132# if [ "" == "$cache" ]
133# then
134# exit 1
135# fi
136
137
138cache="$(curl -v -X "PUT" "$link_to_api" 2>&1 | grep "error")"
139if [ "" == "$cache" ]
140then
141 exit 1
142fi
143
144cache="$(curl -v -X "PUT" "$link_to_api" --data "wrong" 2>&1 | grep "error")"
145if [ "" == "$cache" ]
146then
147 exit 1
148fi
149
150cache="$(curl -v -X "PUT" "$link_to_api" --data "[{}]" 2>&1 | grep "error")"
151if [ "" == "$cache" ]
152then
153 exit 1
154fi
155
156cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newname\":\"Test\",\"other\":\"Test\",\"pubkey\":\"${id}\"}" 2>&1 | grep "error")"
157if [ "" == "$cache" ]
158then
159 exit 1
160fi
161
162cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newnam\":\"Test\",\"pubkey\":\"${id}\"}" 2>&1 | grep "error")"
163if [ "" == "$cache" ]
164then
165 exit 1
166fi
167
168cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newname\":\"Test\",\"pubke\":\"${id}\"}" 2>&1 | grep "error")"
169if [ "" == "$cache" ]
170then
171 exit 1
172fi
173
174cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newname\":123,\"pubkey\":\"${id}\"}" 2>&1 | grep "error")"
175if [ "" == "$cache" ]
176then
177 exit 1
178fi
179
180cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newname\":"",\"pubkey\":\"${id}\"}" 2>&1 | grep "error")"
181if [ "" == "$cache" ]
182then
183 exit 1
184fi
185#TODO Missing subsystem test
186
187#Missing OPTIONS success - nothing can really go wrong here
188
189#Test wrong url
190cache="$(curl -v "$wrong_link" 2>&1 | grep "HTTP/1.1 404")"
191if [ "" == "$cache" ]
192then
193 exit 1
194fi
195
196cache="$(curl -X "PUT" -v "$wrong_link" --data "{\"newname\":\"Testing\",\"pubkey\":\"${id}\"}" 2>&1 | grep "HTTP/1.1 404")"
197if [ "" == "$cache" ]
198then
199 exit 1
200fi
201
202cache="$(curl -X "POST" -v "$wrong_link?pubkey=$id" --data "{\"name\":\"Test\"}" 2>&1 | grep "HTTP/1.1 404")"
203if [ "" == "$cache" ]
204then
205 exit 1
206fi
207
208cache="$(curl -X "DELETE" -v "${wrong_link}?pubkey=$id" 2>&1 | grep "HTTP/1.1 404")"
209if [ "" == "$cache" ]
210then
211 exit 1
212fi
213
214gnunet-identity -D NewTest
215
216exit 0