-Merge branch 'master' of ssh://gnunet.org/gnunet into gsoc2018/rest_api
authorPhil <phil.buschmann@tum.de>
Mon, 11 Jun 2018 20:10:32 +0000 (22:10 +0200)
committerPhil <phil.buschmann@tum.de>
Mon, 11 Jun 2018 20:10:32 +0000 (22:10 +0200)
src/gns/plugin_rest_gns.c
src/identity/plugin_rest_identity.c
src/identity/test_plugin_identity_rest.sh [new file with mode: 0755]

index 2b729db543b589e3bf2404b6d6c1b53af938473e..82d62744c50786680749d25f380a600c442c9381 100644 (file)
@@ -17,6 +17,7 @@
    */
 /**
  * @author Martin Schanzenbach
+ * @author Philippe Buschmann
  * @file gns/plugin_rest_gns.c
  * @brief GNUnet GNS REST plugin
  *
@@ -38,6 +39,8 @@
 
 #define GNUNET_REST_JSONAPI_GNS_RECORD_TYPE "record_type"
 
+#define GNUNET_REST_PARAMETER_GNS_NAME "name"
+
 #define GNUNET_REST_JSONAPI_GNS_TYPEINFO "gns_name"
 
 #define GNUNET_REST_JSONAPI_GNS_RECORD "records"
@@ -162,6 +165,11 @@ struct LookupHandle
    */
   int response_code;
 
+  /**
+   * HTTP response code
+   */
+  char* emsg;
+
 };
 
 
@@ -180,6 +188,8 @@ cleanup_handle (struct LookupHandle *handle)
 
   if (NULL != handle->name)
     GNUNET_free (handle->name);
+  if (NULL != handle->emsg)
+      GNUNET_free (handle->emsg);
   if (NULL != handle->el)
   {
     GNUNET_IDENTITY_ego_lookup_cancel (handle->el);
@@ -225,10 +235,18 @@ do_error (void *cls)
 {
   struct LookupHandle *handle = cls;
   struct MHD_Response *resp;
+  char *json_error;
 
-  resp = GNUNET_REST_create_response (NULL);
+  if (NULL == handle->emsg)
+    handle->emsg = GNUNET_strdup("Unknown Error");
+
+  GNUNET_asprintf (&json_error, "{\"error\": \"%s\"}", handle->emsg);
+  handle->response_code = MHD_HTTP_OK;
+
+  resp = GNUNET_REST_create_response (json_error);
   handle->proc (handle->proc_cls, resp, handle->response_code);
   cleanup_handle (handle);
+  GNUNET_free(json_error);
 }
 
 
@@ -294,16 +312,12 @@ process_lookup_result (void *cls, uint32_t rd_count,
 {
   struct LookupHandle *handle = cls;
   struct MHD_Response *resp;
-  struct GNUNET_JSONAPI_Document *json_document;
-  struct GNUNET_JSONAPI_Resource *json_resource;
   uint32_t i;
   char *result;
   json_t *result_array;
   json_t *record_obj;
 
   result_array = json_array();
-  json_document = GNUNET_JSONAPI_document_new ();
-  json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_GNS_TYPEINFO, handle->name);
   handle->lookup_request = NULL;
   for (i=0; i<rd_count; i++)
   {
@@ -314,17 +328,12 @@ process_lookup_result (void *cls, uint32_t rd_count,
     json_array_append (result_array, record_obj);
     json_decref (record_obj);
   }
-  GNUNET_JSONAPI_resource_add_attr (json_resource,
-                                         GNUNET_REST_JSONAPI_GNS_RECORD,
-                                         result_array);
-  GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
-  GNUNET_JSONAPI_document_serialize (json_document, &result);
+  result = json_dumps(result_array, 0);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result);
-  json_decref (result_array);
-  GNUNET_JSONAPI_document_delete (json_document);
   resp = GNUNET_REST_create_response (result);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
   GNUNET_free (result);
+  json_decref (result_array);
   cleanup_handle (handle);
 }
 
@@ -356,6 +365,7 @@ lookup_with_public_key (struct LookupHandle *handle)
   }
   else
   {
+    handle->emsg = GNUNET_strdup("Parameter name is missing");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
@@ -380,6 +390,7 @@ identity_zone_cb (void *cls,
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 _("Ego for not found, cannot perform lookup.\n"));
+    handle->emsg = GNUNET_strdup ("Ego for not found, cannot perform lookup.");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
@@ -418,6 +429,7 @@ identity_master_cb (void *cls,
   {
     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                 _("Ego for `gns-master' not found, cannot perform lookup.  Did you run gnunet-gns-import.sh?\n"));
+    handle->emsg = GNUNET_strdup("Ego for `gns-master' not found, cannot perform lookup.  Did you run gnunet-gns-import.sh?");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
@@ -436,35 +448,10 @@ identity_master_cb (void *cls,
 }
 
 /**
- * Parse REST uri for name and record type
+ * Handle get request
  *
- * @param url Url to parse
- * @param handle lookup handle to populate
- * @return GNUNET_SYSERR on error
+ * @param handle the lookup handle
  */
-static int
-parse_url (const char *url, struct LookupHandle *handle)
-{
-  char *name;
-  char tmp_url[strlen(url)+1];
-  char *tok;
-
-  strcpy (tmp_url, url);
-  tok = strtok ((char*)tmp_url, "/");
-  if (NULL == tok)
-    return GNUNET_SYSERR;
-  name = strtok (NULL, "/");
-  if (NULL == name)
-    return GNUNET_SYSERR;
-  GNUNET_asprintf (&handle->name,
-                   "%s",
-                   name);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Got name: %s\n", handle->name);
-  return GNUNET_OK;
-}
-
-
 static void
 get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
               const char* url,
@@ -472,40 +459,48 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
 {
   struct LookupHandle *handle = cls;
   struct GNUNET_HashCode key;
+  long int enum_test;
+  char *temp_val;
 
-  //parse name and type from url
-  if (GNUNET_OK != parse_url (url, handle))
+  //check for /gns otherwise 404
+  if (strlen (GNUNET_REST_API_NS_GNS) > strlen (url))
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Error parsing url...\n");
+    handle->emsg = GNUNET_strdup("Wrong URL");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Connecting...\n");
+
+  //connect to gns
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
   handle->gns = GNUNET_GNS_connect (cfg);
   handle->identity = GNUNET_IDENTITY_connect (cfg, NULL, NULL);
   handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
-                                                       &do_error, handle);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Connected\n");
+                                                      &do_error, handle);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
   if (NULL == handle->gns)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Connecting to GNS failed\n");
+    GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Connecting to GNS failed\n");
+    handle->emsg = GNUNET_strdup("Connecting to GNS failed");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_OPTIONS,
-                      strlen (GNUNET_REST_JSONAPI_GNS_OPTIONS),
-                      &key);
-  handle->options = GNUNET_GNS_LO_DEFAULT;
-  if ( GNUNET_YES ==
-       GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
-                                               &key) )
+
+  //check parameter name -> BAD_REQUEST
+  GNUNET_CRYPTO_hash (GNUNET_REST_PARAMETER_GNS_NAME,
+                     strlen (GNUNET_REST_PARAMETER_GNS_NAME),
+                     &key);
+  if ( GNUNET_NO
+      == GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
+                                                &key))
   {
-    handle->options = GNUNET_GNS_LO_DEFAULT;//TODO(char*) GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
-    //&key);
+    handle->emsg = GNUNET_strdup("Parameter name is missing");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
   }
+  handle->name = GNUNET_strdup(GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
+                                                   &key));
+
+  //check parameter record_type, optional
   GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE,
                       strlen (GNUNET_REST_JSONAPI_GNS_RECORD_TYPE),
                       &key);
@@ -513,34 +508,66 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
        GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
                                                &key) )
   {
-    handle->type = GNUNET_GNSRECORD_typename_to_number
-      (GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
+    handle->type = GNUNET_GNSRECORD_typename_to_number(
+       GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
                                           &key));
   }
   else
+  {
     handle->type = GNUNET_GNSRECORD_TYPE_ANY;
+  }
 
+  //check parameter options, optional
+  GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_OPTIONS,
+                     strlen (GNUNET_REST_JSONAPI_GNS_OPTIONS),
+                     &key);
+  handle->options = GNUNET_GNS_LO_DEFAULT;
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
+                                                &key))
+  {
+    temp_val = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map, &key);
+    if (1 < strlen(temp_val))
+    {
+      handle->options = GNUNET_GNS_LO_DEFAULT;
+    }
+    else
+    {
+      //atoi because no valid conversion is default local option
+      enum_test = atoi(temp_val);
+      if (2 < enum_test)
+       handle->options = GNUNET_GNS_LO_DEFAULT;
+      else
+       handle->options = enum_test;
+    }
+  }
+  else
+    handle->options = GNUNET_GNS_LO_DEFAULT;
+
+  //check parameter pkey, shortcut to lookup
   GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_PKEY,
-                      strlen (GNUNET_REST_JSONAPI_GNS_PKEY),
-                      &key);
-  if ( GNUNET_YES ==
-       GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
-                                               &key) )
+                     strlen (GNUNET_REST_JSONAPI_GNS_PKEY),
+                     &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (conndata_handle->url_param_map,
+                                                &key))
   {
     handle->pkey_str = GNUNET_CONTAINER_multihashmap_get (conndata_handle->url_param_map,
-                                                          &key);
-    GNUNET_assert (NULL != handle->pkey_str);
-    if (GNUNET_OK !=
-        GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->pkey_str,
-                                                    strlen(handle->pkey_str),
-                                                    &(handle->pkey)))
+                                                         &key);
+    GNUNET_assert(NULL != handle->pkey_str);
+    if (GNUNET_OK
+       != GNUNET_CRYPTO_ecdsa_public_key_from_string (
+           handle->pkey_str, strlen (handle->pkey_str), &(handle->pkey)))
     {
+      handle->emsg = GNUNET_strdup("Parameter pkey has a wrong format");
       GNUNET_SCHEDULER_add_now (&do_error, handle);
       return;
     }
     lookup_with_public_key (handle);
     return;
   }
+
+  //check parameter ego, lookup public key of ego
   GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_GNS_EGO,
                       strlen (GNUNET_REST_JSONAPI_GNS_EGO),
                       &key);
@@ -556,24 +583,23 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *conndata_handle,
                                              handle);
     return;
   }
+
+  //if name ends with .zkey then get public key
   if ( (NULL != handle->name) &&
        (strlen (handle->name) > 4) &&
        (0 == strcmp (".zkey",
                      &handle->name[strlen (handle->name) - 4])) )
   {
-    GNUNET_CRYPTO_ecdsa_key_get_public
-      (GNUNET_CRYPTO_ecdsa_key_get_anonymous (),
-       &(handle->pkey));
+    GNUNET_CRYPTO_ecdsa_key_get_public( GNUNET_CRYPTO_ecdsa_key_get_anonymous (),
+                                       &(handle->pkey));
     lookup_with_public_key (handle);
   }
-  else
+  else //else use gns-master identity
   {
-    GNUNET_break (NULL == handle->id_op);
     handle->id_op = GNUNET_IDENTITY_get (handle->identity,
                                          "gns-master",
                                          &identity_master_cb,
                                          handle);
-    GNUNET_assert (NULL != handle->id_op);
   }
 }
 
@@ -631,10 +657,10 @@ rest_gns_process_request (struct GNUNET_REST_RequestHandle *conndata_handle,
   handle->proc = proc;
   handle->rest_handle = conndata_handle;
 
-  if (GNUNET_NO == GNUNET_JSONAPI_handle_request (conndata_handle,
-                                                  handlers,
-                                                  &err,
-                                                  handle))
+  if (GNUNET_NO == GNUNET_REST_handle_request (conndata_handle,
+                                               handlers,
+                                               &err,
+                                               handle))
   {
     handle->response_code = err.error_code;
     GNUNET_SCHEDULER_add_now (&do_error, handle);
index 52685c52e2d3f832fcf14b4b2c9b1596c7cb2de4..fd6562f1dbb648ae9a8978783e2f3334fd710284 100644 (file)
@@ -17,6 +17,7 @@
    */
 /**
  * @author Martin Schanzenbach
+ * @author Philippe Buschmann
  * @file identity/plugin_rest_identity.c
  * @brief GNUnet Namestore REST plugin
  *
@@ -26,8 +27,6 @@
 #include "gnunet_rest_plugin.h"
 #include "gnunet_identity_service.h"
 #include "gnunet_rest_lib.h"
-#include "gnunet_jsonapi_lib.h"
-#include "gnunet_jsonapi_util.h"
 #include "microhttpd.h"
 #include <jansson.h>
 #include "gnunet_signatures.h"
 /**
  * Resource type
  */
-#define GNUNET_REST_JSONAPI_IDENTITY_EGO "ego"
+#define GNUNET_REST_JSON_IDENTITY_EGO "ego"
 
 /**
  * Name attribute
  */
-#define GNUNET_REST_JSONAPI_IDENTITY_NAME "name"
+#define GNUNET_REST_JSON_IDENTITY_NAME "name"
 
 /**
  * Attribute to rename "name" TODO we changed id to the pubkey
  * so this can be unified with "name"
  */
-#define GNUNET_REST_JSONAPI_IDENTITY_NEWNAME "newname"
+#define GNUNET_REST_JSON_IDENTITY_NEWNAME "newname"
 
 /**
  * URL parameter to change the subsytem for ego
  */
-#define GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM "subsystem"
+#define GNUNET_REST_JSON_IDENTITY_SUBSYSTEM "subsystem"
 
 
 /**
@@ -74,6 +73,7 @@
  */
 #define GNUNET_REST_ERROR_RESOURCE_INVALID "Resource location invalid"
 #define GNUNET_REST_ERROR_NO_DATA "No data"
+#define GNUNET_REST_ERROR_DATA_INVALID "Data invalid"
 
 /**
  * GNUid token lifetime
@@ -276,16 +276,16 @@ do_error (void *cls)
   struct MHD_Response *resp;
   char *json_error;
 
-  GNUNET_asprintf (&json_error,
-                   "{Error while processing request: %s}",
-                   &handle->emsg);
+  if (NULL == handle->emsg)
+    handle->emsg = GNUNET_strdup("Unknown Error");
+
+  GNUNET_asprintf (&json_error, "{\"error\": \"%s\"}", handle->emsg);
+  handle->response_code = MHD_HTTP_OK;
 
   resp = GNUNET_REST_create_response (json_error);
-  handle->proc (handle->proc_cls,
-               resp,
-               handle->response_code);
+  handle->proc (handle->proc_cls, resp, handle->response_code);
   cleanup_handle (handle);
-  GNUNET_free (json_error);
+  GNUNET_free(json_error);
 }
 
 
@@ -304,14 +304,15 @@ get_ego_for_subsys (void *cls,
                     const char *name)
 {
   struct RequestHandle *handle = cls;
-  struct GNUNET_JSONAPI_Document *json_document;
-  struct GNUNET_JSONAPI_Resource *json_resource;
   struct EgoEntry *ego_entry;
   struct MHD_Response *resp;
+  json_t *json_root;
+  json_t *json_ego;
   json_t *name_json;
   char *result_str;
+  size_t index;
 
-  json_document = GNUNET_JSONAPI_document_new ();
+  json_root = json_array();
 
   for (ego_entry = handle->ego_head;
        NULL != ego_entry;
@@ -321,32 +322,38 @@ get_ego_for_subsys (void *cls,
       continue;
     if (NULL == name)
       continue;
-    json_resource = GNUNET_JSONAPI_resource_new
-      (GNUNET_REST_JSONAPI_IDENTITY_EGO, ego_entry->keystring);
+
+    json_ego = json_object();
     name_json = json_string (ego_entry->identifier);
-    GNUNET_JSONAPI_resource_add_attr (json_resource,
-                                           GNUNET_REST_JSONAPI_IDENTITY_NAME,
-                                           name_json);
-    json_decref (name_json);
-    GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
+    json_object_set_new(json_ego, GNUNET_REST_JSON_IDENTITY_EGO, name_json);
+    json_array_append(json_root, json_ego);
+
     break;
   }
-  if (0 == GNUNET_JSONAPI_document_resource_count (json_document))
+
+  if (0 == json_array_size(json_root))
   {
-    GNUNET_JSONAPI_document_delete (json_document);
+    json_decref(json_root);
     handle->emsg = GNUNET_strdup("No identity matches results!");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  GNUNET_JSONAPI_document_serialize (json_document, &result_str);
+
+  result_str = json_dumps(json_root, 0);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
   resp = GNUNET_REST_create_response (result_str);
-  GNUNET_JSONAPI_document_delete (json_document);
+
+  json_array_foreach(json_root, index, json_ego )
+  {
+    json_decref(json_ego);
+  }
+  json_decref (json_root);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
   GNUNET_free (result_str);
   cleanup_handle (handle);
 }
 
+
 /**
  * Create a response with requested ego(s)
  *
@@ -367,9 +374,10 @@ ego_info_response (struct GNUNET_REST_RequestHandle *con,
   struct EgoEntry *ego_entry;
   struct GNUNET_HashCode key;
   struct MHD_Response *resp;
-  struct GNUNET_JSONAPI_Document *json_document;
-  struct GNUNET_JSONAPI_Resource *json_resource;
+  json_t *json_root;
+  json_t *json_ego;
   json_t *name_str;
+  size_t index;
 
   if (GNUNET_NO == GNUNET_REST_namespace_match (handle->url, GNUNET_REST_API_NS_IDENTITY))
   {
@@ -395,8 +403,8 @@ ego_info_response (struct GNUNET_REST_RequestHandle *con,
   }
 
   if ( NULL == egoname ) {
-    GNUNET_CRYPTO_hash (GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM,
-                        strlen (GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM),
+    GNUNET_CRYPTO_hash (GNUNET_REST_JSON_IDENTITY_SUBSYSTEM,
+                        strlen (GNUNET_REST_JSON_IDENTITY_SUBSYSTEM),
                         &key);
     if ( GNUNET_YES ==
          GNUNET_CONTAINER_multihashmap_contains (handle->conndata_handle->url_param_map,
@@ -417,7 +425,7 @@ ego_info_response (struct GNUNET_REST_RequestHandle *con,
     }
   }
 
-  json_document = GNUNET_JSONAPI_document_new ();
+  json_root = json_array();
 
   //Return all egos
   for (ego_entry = handle->ego_head;
@@ -426,27 +434,35 @@ ego_info_response (struct GNUNET_REST_RequestHandle *con,
   {
     if ( (NULL != egoname) && (0 != strcmp (egoname, ego_entry->identifier)) )
       continue;
-    json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_EGO,
-                                                      ego_entry->keystring);
+
+    json_ego = json_object();
+
+    json_object_set_new( json_ego, "id", json_string (ego_entry->keystring));
+    json_object_set_new( json_ego, "type", json_string (GNUNET_REST_JSON_IDENTITY_EGO));
     name_str = json_string (ego_entry->identifier);
-    GNUNET_JSONAPI_resource_add_attr (
-                                           json_resource,
-                                           GNUNET_REST_JSONAPI_IDENTITY_NAME,
-                                           name_str);
-    json_decref (name_str);
-    GNUNET_JSONAPI_document_resource_add (json_document, json_resource);
+    json_object_set_new( json_ego, "name", name_str);
+
+    json_array_append( json_root, json_ego );
   }
-  if (0 == GNUNET_JSONAPI_document_resource_count (json_document))
+
+  if ((size_t)0 == json_array_size(json_root))
   {
-    GNUNET_JSONAPI_document_delete (json_document);
+    json_decref (json_root);
     handle->emsg = GNUNET_strdup ("No identities found!");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  GNUNET_JSONAPI_document_serialize (json_document, &result_str);
+
+  result_str = json_dumps(json_root, 0);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
   resp = GNUNET_REST_create_response (result_str);
-  GNUNET_JSONAPI_document_delete (json_document);
+
+  //delete json_objects in json_array with macro
+  json_array_foreach(json_root, index, json_ego )
+  {
+    json_decref(json_ego);
+  }
+  json_decref (json_root);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
   GNUNET_free (result_str);
   cleanup_handle (handle);
@@ -472,7 +488,7 @@ do_finished (void *cls, const char *emsg)
     return;
   }
   resp = GNUNET_REST_create_response (NULL);
-  handle->proc (handle->proc_cls, resp, MHD_HTTP_NO_CONTENT);
+  handle->proc (handle->proc_cls, resp, handle->response_code);
   cleanup_handle (handle);
 }
 
@@ -491,23 +507,19 @@ ego_create_cont (struct GNUNET_REST_RequestHandle *con,
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
   struct MHD_Response *resp;
-  struct GNUNET_JSONAPI_Document *json_obj;
-  struct GNUNET_JSONAPI_Resource *json_res;
   json_t *egoname_json;
   json_t *data_js;
   json_error_t err;
   const char* egoname;
   char term_data[handle->data_size+1];
-  struct GNUNET_JSON_Specification docspec[] = {
-    GNUNET_JSON_spec_jsonapi_document (&json_obj),
-    GNUNET_JSON_spec_end()
-  };
+
   if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url))
   {
     handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
+
   if (0 >= handle->data_size)
   {
     handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA);
@@ -519,50 +531,54 @@ ego_create_cont (struct GNUNET_REST_RequestHandle *con,
   data_js = json_loads (term_data,
                         JSON_DECODE_ANY,
                         &err);
-  GNUNET_assert (NULL != data_js);
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_JSON_parse (data_js, docspec,
-                                    NULL, NULL));
 
-  json_decref (data_js);
 
-  if (NULL == json_obj)
+  if (NULL == data_js)
   {
+    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  if (1 != GNUNET_JSONAPI_document_resource_count (json_obj))
+  //instead of parse
+  if (!json_is_object(data_js))
   {
-    GNUNET_JSONAPI_document_delete (json_obj);
-    handle->emsg = GNUNET_strdup ("Provided resource count invalid");
+    json_decref(data_js);
+    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0);
-  if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, GNUNET_REST_JSONAPI_IDENTITY_EGO))
+
+  if (1 != json_object_size (data_js))
   {
-    GNUNET_JSONAPI_document_delete (json_obj);
-    resp = GNUNET_REST_create_response (NULL);
-    handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
-    cleanup_handle (handle);
+    json_decref (data_js);
+    handle->emsg = GNUNET_strdup("Provided resource count invalid");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  egoname_json = GNUNET_JSONAPI_resource_read_attr (json_res, GNUNET_REST_JSONAPI_IDENTITY_NAME);
+
+  egoname_json = json_object_get (data_js, GNUNET_REST_JSON_IDENTITY_NAME);
   if (!json_is_string (egoname_json))
   {
-    GNUNET_JSONAPI_document_delete (json_obj);
+    json_decref (data_js);
     handle->emsg = GNUNET_strdup ("No name provided");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
   egoname = json_string_value (egoname_json);
+  if(0 >= strlen(egoname))
+  {
+    json_decref (data_js);
+    handle->emsg = GNUNET_strdup ("No name provided");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
   for (ego_entry = handle->ego_head;
        NULL != ego_entry;
        ego_entry = ego_entry->next)
   {
     if (0 == strcasecmp (egoname, ego_entry->identifier))
     {
-      GNUNET_JSONAPI_document_delete (json_obj);
+      json_decref (data_js);
       resp = GNUNET_REST_create_response (NULL);
       handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
       cleanup_handle (handle);
@@ -570,7 +586,8 @@ ego_create_cont (struct GNUNET_REST_RequestHandle *con,
     }
   }
   GNUNET_asprintf (&handle->name, "%s", egoname);
-  GNUNET_JSONAPI_document_delete (json_obj);
+  json_decref (data_js);
+  handle->response_code = MHD_HTTP_CREATED;
   handle->op = GNUNET_IDENTITY_create (handle->identity_handle,
                                        handle->name,
                                        &do_finished,
@@ -590,8 +607,6 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con,
                const char *url,
                void *cls)
 {
-  struct GNUNET_JSONAPI_Document *json_obj;
-  struct GNUNET_JSONAPI_Resource *json_res;
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
   struct EgoEntry *ego_entry_tmp;
@@ -605,10 +620,6 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con,
   const char *newname;
   char term_data[handle->data_size+1];
   int ego_exists = GNUNET_NO;
-  struct GNUNET_JSON_Specification docspec[] = {
-    GNUNET_JSON_spec_jsonapi_document (&json_obj),
-    GNUNET_JSON_spec_end()
-  };
 
   if (strlen (GNUNET_REST_API_NS_IDENTITY) > strlen (handle->url))
   {
@@ -649,43 +660,40 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con,
   data_js = json_loads (term_data,
                         JSON_DECODE_ANY,
                         &err);
-  GNUNET_assert (NULL != data_js);
-  GNUNET_assert (GNUNET_OK ==
-                 GNUNET_JSON_parse (data_js, docspec,
-                                    NULL, NULL));
-
-  json_decref (data_js);
-
-  if (NULL == json_obj)
+  if (NULL == data_js)
   {
-    handle->emsg = GNUNET_strdup ("Data invalid");
+    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-
-  if (1 != GNUNET_JSONAPI_document_resource_count (json_obj))
+  if (!json_is_object(data_js))
   {
-    GNUNET_JSONAPI_document_delete (json_obj);
-    handle->emsg = GNUNET_strdup ("Resource amount invalid");
+    json_decref (data_js);
+    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0);
 
-  if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, GNUNET_REST_JSONAPI_IDENTITY_EGO))
+  if (1 != json_object_size(data_js))
   {
-    GNUNET_JSONAPI_document_delete (json_obj);
-    handle->emsg = GNUNET_strdup ("Resource type invalid");
+    json_decref (data_js);
+    handle->emsg = GNUNET_strdup ("Resource amount invalid");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
 
   //This is a rename
-  name_json = GNUNET_JSONAPI_resource_read_attr (json_res,
-                                                 GNUNET_REST_JSONAPI_IDENTITY_NEWNAME);
+  name_json = json_object_get (data_js, GNUNET_REST_JSON_IDENTITY_NEWNAME);
   if ((NULL != name_json) && json_is_string (name_json))
   {
     newname = json_string_value (name_json);
+    if(0 >= strlen(newname))
+    {
+      json_decref (data_js);
+      handle->emsg = GNUNET_strdup ("No name provided");
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
+    }
     for (ego_entry_tmp = handle->ego_head;
          NULL != ego_entry_tmp;
          ego_entry_tmp = ego_entry_tmp->next)
@@ -694,29 +702,38 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con,
           0 != strcasecmp (keystring, ego_entry_tmp->keystring))
       {
         //Ego with same name not allowed
-        GNUNET_JSONAPI_document_delete (json_obj);
+       json_decref (data_js);
         resp = GNUNET_REST_create_response (NULL);
         handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
         cleanup_handle (handle);
         return;
       }
     }
+    handle->response_code = MHD_HTTP_NO_CONTENT;
     handle->op = GNUNET_IDENTITY_rename (handle->identity_handle,
                                          ego_entry->identifier,
                                          newname,
                                          &do_finished,
                                          handle);
-    GNUNET_JSONAPI_document_delete (json_obj);
+    json_decref (data_js);
     return;
   }
 
   //Set subsystem
-  subsys_json = GNUNET_JSONAPI_resource_read_attr (json_res, GNUNET_REST_JSONAPI_IDENTITY_SUBSYSTEM);
+  subsys_json = json_object_get (data_js, GNUNET_REST_JSON_IDENTITY_SUBSYSTEM);
   if ( (NULL != subsys_json) && json_is_string (subsys_json))
   {
     subsys = json_string_value (subsys_json);
+    if(0 >= strlen(subsys))
+    {
+      json_decref (data_js);
+      handle->emsg = GNUNET_strdup ("No name provided");
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
+    }
     GNUNET_asprintf (&handle->subsys, "%s", subsys);
-    GNUNET_JSONAPI_document_delete (json_obj);
+    json_decref (data_js);
+    handle->response_code = MHD_HTTP_NO_CONTENT;
     handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
                                       handle->subsys,
                                       ego_entry->ego,
@@ -724,11 +741,18 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con,
                                       handle);
     return;
   }
-  GNUNET_JSONAPI_document_delete (json_obj);
+  json_decref (data_js);
   handle->emsg = GNUNET_strdup ("Subsystem not provided");
   GNUNET_SCHEDULER_add_now (&do_error, handle);
 }
 
+/**
+ * Handle ego delete request
+ *
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
+ */
 void
 ego_delete_cont (struct GNUNET_REST_RequestHandle *con_handle,
                  const char* url,
@@ -764,6 +788,7 @@ ego_delete_cont (struct GNUNET_REST_RequestHandle *con_handle,
     cleanup_handle (handle);
     return;
   }
+  handle->response_code = MHD_HTTP_NO_CONTENT;
   handle->op = GNUNET_IDENTITY_delete (handle->identity_handle,
                                        ego_entry->identifier,
                                        &do_finished,
@@ -815,7 +840,7 @@ init_cont (struct RequestHandle *handle)
     GNUNET_REST_HANDLER_END
   };
 
-  if (GNUNET_NO == GNUNET_JSONAPI_handle_request (handle->conndata_handle,
+  if (GNUNET_NO == GNUNET_REST_handle_request (handle->conndata_handle,
                                                   handlers,
                                                   &err,
                                                   handle))
@@ -907,7 +932,7 @@ rest_identity_process_request(struct GNUNET_REST_RequestHandle *conndata_handle,
 
 
   handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
-
+  handle->response_code = MHD_HTTP_OK;
   handle->proc_cls = proc_cls;
   handle->proc = proc;
   handle->state = ID_REST_STATE_INIT;
diff --git a/src/identity/test_plugin_identity_rest.sh b/src/identity/test_plugin_identity_rest.sh
new file mode 100755 (executable)
index 0000000..d43f420
--- /dev/null
@@ -0,0 +1,252 @@
+#!/usr/bin/bash
+
+#First, start gnunet-arm and the rest-service. Make sure, no identity exists
+
+link_to_api="http://localhost:7776/identity"
+wrong_link="http://localhost:7776/idenmmmy"
+
+#Test GET (multiple identities) for error when no identity exists
+
+echo "No test for subsystem available"
+echo "The next test case can be ignored if you have already added identities"
+cache="$(curl --silent "$link_to_api" | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for GET request when missing identity\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for GET request when missing identity\n"
+fi
+
+#Test POST success code, error response code and error json
+echo "The next test case can be ignored if you have already added an identity with the name Test"
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":\"Test\"}" 2>&1 | grep "HTTP/1.1 201")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Error for good POST request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Success for good POST request\n"
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":\"Test\"}" 2>&1 | grep "HTTP/1.1 409")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for duplicate name POST request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for duplicate name POST request\n"
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for no data POST request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for no data POST request\n"
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "wrong" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong data POST request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong data POST request\n"
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "[{}]" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for json array input POST request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for json array input POST request\n"
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":\"Test\",\"other\":\"Test\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for multi element json POST request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for multi element json POST request\n"
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"nam\":\"Test\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong json POST request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong json POST request\n"
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":123}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong json type POST request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong json type POST request\n"
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":""}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for no name POST request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for no name POST request\n"
+fi
+
+
+#Test GET (multiple identities) for success and error json
+cache="$(curl --silent "$link_to_api" | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Success for good GET request (multiple identities)\n"
+else
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Error for good GET request (multiple identities)\n"
+fi
+
+
+id="$(gnunet-identity -d | grep "Test - " | sed  "s/Test - //g")"
+#Test GET (one identity) for success and error json
+cache="$(curl --silent "${link_to_api}/$id" | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Success for good GET request (one identity)\n"
+else
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Error for good GET request (one identity)\n"
+fi
+
+
+#Test DELETE success code, error response code and error json
+echo "Next tests for DELETE will probably fail when POST fails"
+cache="$(curl -v -X "DELETE" "${link_to_api}/$id" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Success for good DELETE request\n"
+else
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Error for good DELETE request\n"
+fi
+
+curl --silent -X "POST" "$link_to_api" --data "{\"name\":\"Test\"}"
+id="$(gnunet-identity -d | grep "Test - " | sed  "s/Test - //g")"
+
+cache="$(curl -v -X "DELETE" "${link_to_api}/df1" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong DELETE request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong DELETE request\n"
+fi
+
+#Test PUT success code, error response codes and error json
+cache="$(curl -v -X "PUT" "${link_to_api}/$id" --data "{\"newname\":\"NewTest\"}" 2>&1 | grep "HTTP/1.1 204")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Error for good PUT request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Success for good PUT request\n"
+fi
+
+cache="$(curl -v -X "PUT" "${link_to_api}/${id}1" --data "{\"newname\":\"NewNewTest\"}" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong identity PUT request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong identity PUT request\n"
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api/$id" --data "{\"newname\":\"NewTest\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for duplicate name PUT request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for duplicate name PUT request\n"
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api/$id" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for no data PUT request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for no data PUT request\n"
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api/$id" --data "wrong" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong data PUT request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong data PUT request\n"
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api/$id" --data "[{}]" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for json array input PUT request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for json array input PUT request\n"
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api/$id" --data "{\"newname\":\"Test\",\"other\":\"Test\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for multi element json PUT request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for multi element json PUT request\n"
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api/$id" --data "{\"newnam\":\"Test\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong json PUT request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong json PUT request\n"
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api/$id" --data "{\"newname\":123}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong json type PUT request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong json type PUT request\n"
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api/$id" --data "{\"newname\":""}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for no name PUT request\n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for no name PUT request\n"
+fi
+#TODO Missing subsystem test
+
+#Missing OPTIONS success - nothing can really go wrong here
+
+#Test wrong url
+cache="$(curl -v "$wrong_link" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong url GET request \n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong url GET request \n"
+fi
+
+cache="$(curl -X "PUT" -v "$wrong_link/$id" --data "{\"newname\":\"Testing\"}" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong url GET request \n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong url GET request \n"
+fi
+
+cache="$(curl -X "POST" -v "$wrong_link/$id" --data "{\"name\":\"Test\"}" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong url POST request \n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong url POST request \n"
+fi
+
+cache="$(curl -X "DELETE" -v "${wrong_link}/$id" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    echo -n -e "[\033[0;31m FAILURE\033[0m ] Success for wrong url DELETE request \n"
+else
+    echo -n -e "[\033[0;32m SUCCESS\033[0m ] Error for wrong url DELETE request \n"
+fi