aboutsummaryrefslogtreecommitdiff
path: root/src/identity/plugin_rest_identity.c
diff options
context:
space:
mode:
authorPhil <phil.buschmann@tum.de>2018-08-05 22:43:35 +0200
committerPhil <phil.buschmann@tum.de>2018-08-05 22:43:35 +0200
commitdc1c69e3109ccd7311a6d1f07ecc9dce0ee4c186 (patch)
tree1814039209cf3f8df15932d196f74267d5bb4d87 /src/identity/plugin_rest_identity.c
parent36a899058d6863eee242a026b282e6150b4855fa (diff)
downloadgnunet-dc1c69e3109ccd7311a6d1f07ecc9dce0ee4c186.tar.gz
gnunet-dc1c69e3109ccd7311a6d1f07ecc9dce0ee4c186.zip
Identity REST API finished
Diffstat (limited to 'src/identity/plugin_rest_identity.c')
-rw-r--r--src/identity/plugin_rest_identity.c286
1 files changed, 174 insertions, 112 deletions
diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c
index 83bf4075d..a518a74cc 100644
--- a/src/identity/plugin_rest_identity.c
+++ b/src/identity/plugin_rest_identity.c
@@ -265,6 +265,47 @@ do_error (void *cls)
265 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 265 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
266} 266}
267 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 */
279struct EgoEntry*
280get_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
268/** 309/**
269 * Callback for GET Request with subsystem 310 * Callback for GET Request with subsystem
270 * 311 *
@@ -330,7 +371,6 @@ ego_get (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
330 json_t *json_root; 371 json_t *json_root;
331 json_t *json_ego; 372 json_t *json_ego;
332 char *result_str; 373 char *result_str;
333 size_t index;
334 374
335 //requested default identity of subsystem 375 //requested default identity of subsystem
336 GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_SUBSYSTEM, 376 GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_SUBSYSTEM,
@@ -371,14 +411,14 @@ ego_get (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
371 keystring = GNUNET_CONTAINER_multihashmap_get ( 411 keystring = GNUNET_CONTAINER_multihashmap_get (
372 handle->rest_handle->url_param_map, &key); 412 handle->rest_handle->url_param_map, &key);
373 413
374 for (ego_entry = handle->ego_head; 414 ego_entry = get_egoentry(handle, keystring, NULL);
375 NULL != ego_entry; ego_entry = ego_entry->next) 415 if (NULL == ego_entry)
376 { 416 {
377 if ((NULL != keystring) 417 handle->emsg = GNUNET_strdup("No identity found for public key");
378 && (0 != strcmp (keystring, ego_entry->keystring))) 418 GNUNET_SCHEDULER_add_now (&do_error, handle);
379 continue; 419 return;
380 egoname = ego_entry->identifier;
381 } 420 }
421 egoname = ego_entry->identifier;
382 } 422 }
383 423
384 //one identity requested with name 424 //one identity requested with name
@@ -393,6 +433,12 @@ ego_get (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
393 { 433 {
394 egoname = GNUNET_CONTAINER_multihashmap_get ( 434 egoname = GNUNET_CONTAINER_multihashmap_get (
395 handle->rest_handle->url_param_map, &key); 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 }
396 //LOWERCASE ego names? 442 //LOWERCASE ego names?
397 GNUNET_STRINGS_utf8_tolower(egoname, egoname); 443 GNUNET_STRINGS_utf8_tolower(egoname, egoname);
398 } 444 }
@@ -418,6 +464,7 @@ ego_get (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
418 GNUNET_REST_PARAM_NAME, 464 GNUNET_REST_PARAM_NAME,
419 json_string (ego_entry->identifier)); 465 json_string (ego_entry->identifier));
420 json_array_append (json_root, json_ego); 466 json_array_append (json_root, json_ego);
467 json_decref (json_ego);
421 } 468 }
422 469
423 if ((size_t) 0 == json_array_size (json_root)) 470 if ((size_t) 0 == json_array_size (json_root))
@@ -432,17 +479,13 @@ ego_get (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
432 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); 479 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
433 resp = GNUNET_REST_create_response (result_str); 480 resp = GNUNET_REST_create_response (result_str);
434 481
435 //delete json_objects in json_array with macro
436 json_array_foreach(json_root, index, json_ego )
437 {
438 json_decref (json_ego);
439 }
440 json_decref (json_root); 482 json_decref (json_root);
441 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 483 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
442 GNUNET_free(result_str); 484 GNUNET_free(result_str);
443 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 485 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
444} 486}
445 487
488
446/** 489/**
447 * Processing finished 490 * Processing finished
448 * 491 *
@@ -467,6 +510,7 @@ do_finished (void *cls, const char *emsg)
467 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 510 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
468} 511}
469 512
513
470/** 514/**
471 * Handle identity PUT request 515 * Handle identity PUT request
472 * 516 *
@@ -475,23 +519,22 @@ do_finished (void *cls, const char *emsg)
475 * @param cls the RequestHandle 519 * @param cls the RequestHandle
476 */ 520 */
477void 521void
478ego_edit (struct GNUNET_REST_RequestHandle *con_handle, const char* url, 522ego_edit (struct GNUNET_REST_RequestHandle *con_handle,
479 void *cls) 523 const char* url,
524 void *cls)
480{ 525{
481 struct RequestHandle *handle = cls; 526 struct RequestHandle *handle = cls;
482 struct EgoEntry *ego_entry; 527 struct EgoEntry *ego_entry;
483 struct EgoEntry *ego_entry_tmp; 528 struct EgoEntry *ego_entry_tmp;
484 struct MHD_Response *resp; 529 struct MHD_Response *resp;
485 json_t *subsys_json; 530 int json_state;
486 json_t *name_json;
487 json_t *key_json;
488 json_t *data_js; 531 json_t *data_js;
489 json_error_t err; 532 json_error_t err;
490 const char *keystring; 533 char *pubkey;
491 const char *subsys; 534 char *name;
492 const char *newname; 535 char *newsubsys;
536 char *newname;
493 char term_data[handle->data_size + 1]; 537 char term_data[handle->data_size + 1];
494 int ego_exists = GNUNET_NO;
495 538
496 //if no data 539 //if no data
497 if (0 >= handle->data_size) 540 if (0 >= handle->data_size)
@@ -504,111 +547,135 @@ ego_edit (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
504 term_data[handle->data_size] = '\0'; 547 term_data[handle->data_size] = '\0';
505 GNUNET_memcpy(term_data, handle->data, handle->data_size); 548 GNUNET_memcpy(term_data, handle->data, handle->data_size);
506 data_js = json_loads (term_data,JSON_DECODE_ANY,&err); 549 data_js = json_loads (term_data,JSON_DECODE_ANY,&err);
550
507 if (NULL == data_js) 551 if (NULL == data_js)
508 { 552 {
509 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA); 553 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
510 GNUNET_SCHEDULER_add_now (&do_error, handle); 554 GNUNET_SCHEDULER_add_now (&do_error, handle);
511 return; 555 return;
512 } 556 }
513 if (!json_is_object(data_js))
514 {
515 json_decref (data_js);
516 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
517 GNUNET_SCHEDULER_add_now (&do_error, handle);
518 return;
519 }
520 //json must contain pubkey and (subsystem or name)
521 if (2 != json_object_size (data_js))
522 {
523 json_decref (data_js);
524 handle->emsg = GNUNET_strdup("Resource amount invalid");
525 GNUNET_SCHEDULER_add_now (&do_error, handle);
526 return;
527 }
528 557
529 key_json = json_object_get (data_js, GNUNET_REST_PARAM_PUBKEY); 558 ego_entry = NULL;
530 if ((NULL == key_json) || !json_is_string(key_json)) 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)
531 { 574 {
532 json_decref (data_js); 575 if (NULL == newname)
533 handle->emsg = GNUNET_strdup("Missing element pubkey"); 576 {
534 GNUNET_SCHEDULER_add_now (&do_error, handle); 577 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
535 return; 578 GNUNET_SCHEDULER_add_now (&do_error, handle);
536 } 579 json_decref (data_js);
537 keystring = json_string_value (key_json); 580 return;
581 }
538 582
539 for (ego_entry = handle->ego_head; 583 if (0 >= strlen(newname))
540 NULL != ego_entry; ego_entry = ego_entry->next) 584 {
541 { 585 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
542 if (0 != strcasecmp (keystring, ego_entry->keystring)) 586 GNUNET_SCHEDULER_add_now (&do_error, handle);
543 continue; 587 json_decref (data_js);
544 ego_exists = GNUNET_YES; 588 return;
545 break; 589 }
546 } 590 //lower case name
591 GNUNET_STRINGS_utf8_tolower(newname,newname);
547 592
548 if (GNUNET_NO == ego_exists) 593 ego_entry = get_egoentry(handle,pubkey,name);
549 { 594
550 json_decref (data_js); 595 if (NULL == ego_entry)
551 resp = GNUNET_REST_create_response (NULL);
552 handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
553 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
554 return;
555 }
556 //This is a rename
557 name_json = json_object_get (data_js, GNUNET_REST_PARAM_NEWNAME);
558 if ((NULL != name_json) && json_is_string(name_json))
559 {
560 newname = json_string_value (name_json);
561 if (0 >= strlen (newname))
562 { 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);
563 json_decref (data_js); 600 json_decref (data_js);
564 handle->emsg = GNUNET_strdup("No name provided");
565 GNUNET_SCHEDULER_add_now (&do_error, handle);
566 return; 601 return;
567 } 602 }
603
568 for (ego_entry_tmp = handle->ego_head; 604 for (ego_entry_tmp = handle->ego_head;
569 NULL != ego_entry_tmp; ego_entry_tmp = ego_entry_tmp->next) 605 NULL != ego_entry_tmp; ego_entry_tmp = ego_entry_tmp->next)
570 { 606 {
571 if (0 == strcasecmp (newname, ego_entry_tmp->identifier) 607 if (0 == strcasecmp (newname, ego_entry_tmp->identifier))
572 && 0 != strcasecmp (keystring, ego_entry_tmp->keystring))
573 { 608 {
574 //Ego with same name not allowed 609 //Ego with same name not allowed
575 json_decref (data_js); 610 resp = GNUNET_REST_create_response (NULL);
576 resp = GNUNET_REST_create_response (NULL); 611 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
577 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); 612 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
578 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 613 json_decref (data_js);
579 return; 614 return;
580 } 615 }
581 } 616 }
582 handle->response_code = MHD_HTTP_NO_CONTENT; 617 handle->response_code = MHD_HTTP_NO_CONTENT;
583 handle->op = GNUNET_IDENTITY_rename (handle->identity_handle, 618 handle->op = GNUNET_IDENTITY_rename (handle->identity_handle,
584 ego_entry->identifier, newname, 619 ego_entry->identifier, newname,
585 &do_finished, handle); 620 &do_finished, handle);
586 json_decref (data_js); 621 json_decref (data_js);
587 return; 622 return;
588 } 623 }
589 624
590 //Set subsystem 625 newsubsys = NULL;
591 subsys_json = json_object_get (data_js, GNUNET_REST_PARAM_SUBSYSTEM); 626 //SUBSYSTEM
592 if ((NULL != subsys_json) && json_is_string(subsys_json)) 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)
593 { 638 {
594 subsys = json_string_value (subsys_json); 639 if (NULL == newsubsys || (NULL == pubkey && NULL == name))
595 if (0 >= strlen (subsys)) 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))
596 { 648 {
649 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
650 GNUNET_SCHEDULER_add_now (&do_error, handle);
597 json_decref (data_js); 651 json_decref (data_js);
598 handle->emsg = GNUNET_strdup("Invalid subsystem name"); 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);
599 GNUNET_SCHEDULER_add_now (&do_error, handle); 660 GNUNET_SCHEDULER_add_now (&do_error, handle);
661 json_decref (data_js);
600 return; 662 return;
601 } 663 }
602 GNUNET_asprintf (&handle->subsystem, "%s", subsys); 664
603 json_decref (data_js);
604 handle->response_code = MHD_HTTP_NO_CONTENT; 665 handle->response_code = MHD_HTTP_NO_CONTENT;
605 handle->op = GNUNET_IDENTITY_set (handle->identity_handle, handle->subsystem, 666 handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
606 ego_entry->ego, &do_finished, handle); 667 newsubsys,
668 ego_entry->ego,
669 &do_finished,
670 handle);
671 json_decref (data_js);
607 return; 672 return;
608 } 673 }
609 json_decref (data_js); 674
610 handle->emsg = GNUNET_strdup("Subsystem not provided"); 675 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
611 GNUNET_SCHEDULER_add_now (&do_error, handle); 676 GNUNET_SCHEDULER_add_now (&do_error, handle);
677 json_decref (data_js);
678 return;
612} 679}
613 680
614/** 681/**
@@ -625,10 +692,10 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
625 struct RequestHandle *handle = cls; 692 struct RequestHandle *handle = cls;
626 struct EgoEntry *ego_entry; 693 struct EgoEntry *ego_entry;
627 struct MHD_Response *resp; 694 struct MHD_Response *resp;
628 json_t *egoname_json;
629 json_t *data_js; 695 json_t *data_js;
630 json_error_t err; 696 json_error_t err;
631 const char* egoname; 697 char* egoname;
698 int json_unpack_state;
632 char term_data[handle->data_size + 1]; 699 char term_data[handle->data_size + 1];
633 700
634 if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url)) 701 if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url))
@@ -649,39 +716,33 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
649 data_js = json_loads (term_data, 716 data_js = json_loads (term_data,
650 JSON_DECODE_ANY, 717 JSON_DECODE_ANY,
651 &err); 718 &err);
652
653 if (NULL == data_js) 719 if (NULL == data_js)
654 { 720 {
655 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID); 721 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
656 GNUNET_SCHEDULER_add_now (&do_error, handle); 722 GNUNET_SCHEDULER_add_now (&do_error, handle);
723 json_decref (data_js);
657 return; 724 return;
658 } 725 }
659 //instead of parse 726 json_unpack_state = 0;
660 if (!json_is_object(data_js)) 727 json_unpack_state = json_unpack(data_js,
728 "{s:s!}",
729 GNUNET_REST_PARAM_NAME,
730 &egoname);
731 if (0 != json_unpack_state)
661 { 732 {
662 json_decref (data_js);
663 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID); 733 handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
664 GNUNET_SCHEDULER_add_now (&do_error, handle); 734 GNUNET_SCHEDULER_add_now (&do_error, handle);
665 return;
666 }
667
668 if (1 != json_object_size (data_js))
669 {
670 json_decref (data_js); 735 json_decref (data_js);
671 handle->emsg = GNUNET_strdup("Provided resource count invalid");
672 GNUNET_SCHEDULER_add_now (&do_error, handle);
673 return; 736 return;
674 } 737 }
675 738
676 egoname_json = json_object_get (data_js, GNUNET_REST_PARAM_NAME); 739 if (NULL == egoname)
677 if (!json_is_string(egoname_json))
678 { 740 {
679 json_decref (data_js);
680 handle->emsg = GNUNET_strdup("No name provided"); 741 handle->emsg = GNUNET_strdup("No name provided");
681 GNUNET_SCHEDULER_add_now (&do_error, handle); 742 GNUNET_SCHEDULER_add_now (&do_error, handle);
743 json_decref (data_js);
682 return; 744 return;
683 } 745 }
684 egoname = json_string_value (egoname_json);
685 if (0 >= strlen (egoname)) 746 if (0 >= strlen (egoname))
686 { 747 {
687 json_decref (data_js); 748 json_decref (data_js);
@@ -689,19 +750,20 @@ ego_create (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
689 GNUNET_SCHEDULER_add_now (&do_error, handle); 750 GNUNET_SCHEDULER_add_now (&do_error, handle);
690 return; 751 return;
691 } 752 }
753 GNUNET_STRINGS_utf8_tolower(egoname, egoname);
692 for (ego_entry = handle->ego_head; 754 for (ego_entry = handle->ego_head;
693 NULL != ego_entry; ego_entry = ego_entry->next) 755 NULL != ego_entry; ego_entry = ego_entry->next)
694 { 756 {
695 if (0 == strcasecmp (egoname, ego_entry->identifier)) 757 if (0 == strcasecmp (egoname, ego_entry->identifier))
696 { 758 {
697 json_decref (data_js);
698 resp = GNUNET_REST_create_response (NULL); 759 resp = GNUNET_REST_create_response (NULL);
699 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); 760 handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
700 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle); 761 GNUNET_SCHEDULER_add_now (&cleanup_handle, handle);
762 json_decref (data_js);
701 return; 763 return;
702 } 764 }
703 } 765 }
704 GNUNET_asprintf (&handle->name, "%s", egoname); 766 handle->name = GNUNET_strdup(egoname);
705 json_decref (data_js); 767 json_decref (data_js);
706 handle->response_code = MHD_HTTP_CREATED; 768 handle->response_code = MHD_HTTP_CREATED;
707 handle->op = GNUNET_IDENTITY_create (handle->identity_handle, handle->name, 769 handle->op = GNUNET_IDENTITY_create (handle->identity_handle, handle->name,
@@ -750,7 +812,7 @@ ego_delete (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
750 egoname = GNUNET_CONTAINER_multihashmap_get ( 812 egoname = GNUNET_CONTAINER_multihashmap_get (
751 handle->rest_handle->url_param_map, &key); 813 handle->rest_handle->url_param_map, &key);
752 //LOWERCASE ego names? 814 //LOWERCASE ego names?
753 GNUNET_STRINGS_utf8_tolower(egoname, egoname); 815 //GNUNET_STRINGS_utf8_tolower(egoname, egoname);
754 } 816 }
755 817
756 if (NULL != keystring) 818 if (NULL != keystring)
@@ -769,7 +831,7 @@ ego_delete (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
769 for (ego_entry = handle->ego_head; 831 for (ego_entry = handle->ego_head;
770 NULL != ego_entry; ego_entry = ego_entry->next) 832 NULL != ego_entry; ego_entry = ego_entry->next)
771 { 833 {
772 if (0 != strcasecmp (egoname, ego_entry->identifier)) 834 if (0 != strcmp (egoname, ego_entry->identifier))
773 continue; 835 continue;
774 ego_exists = GNUNET_YES; 836 ego_exists = GNUNET_YES;
775 break; 837 break;