Identity+GNS Rest changed and fixed
authorPhil <phil.buschmann@tum.de>
Sun, 24 Jun 2018 22:17:06 +0000 (00:17 +0200)
committerPhil <phil.buschmann@tum.de>
Sun, 24 Jun 2018 22:17:06 +0000 (00:17 +0200)
src/gns/plugin_rest_gns.c
src/identity/plugin_rest_identity.c
src/identity/test_plugin_rest_identity.sh [new file with mode: 0755]

index 57fdfc1d5314793563dbb34c797c0ef26b44ed78..22c908275b33f99424f66b3ac7bc2cc3068583fa 100644 (file)
    */
 /**
  * @author Philippe Buschmann
- * @file gns1/plugin_rest_gns1.c
- * @brief GNUnet Gns1 REST plugin
+ * @file gns/plugin_rest_gns.c
+ * @brief GNUnet Gns REST plugin
  */
 
 #include "platform.h"
 #include "gnunet_rest_plugin.h"
 #include "gnunet_rest_lib.h"
 #include "gnunet_gnsrecord_lib.h"
+#include "gnunet_gns_service.h"
 #include "microhttpd.h"
 #include <jansson.h>
 
 #define GNUNET_REST_API_NS_GNS "/gns"
 
-//TODO define other variables
 #define GNUNET_REST_PARAMETER_GNS_NAME "name"
 
 #define GNUNET_REST_PARAMETER_GNS_RECORD_TYPE "record_type"
 
-#define GNUNET_REST_PARAMETER_GNS_NAME "name"
-
 /**
  * The configuration handle
  */
@@ -57,13 +55,10 @@ struct Plugin
   const struct GNUNET_CONFIGURATION_Handle *cfg;
 };
 
-//TODO add specific structs
-
 
 
 struct RequestHandle
 {
-  //TODO add specific entries
 
   /**
    * Connection to GNS
@@ -160,8 +155,6 @@ cleanup_handle (struct RequestHandle *handle)
     GNUNET_free (handle->name);
   if (NULL != handle->emsg)
     GNUNET_free (handle->emsg);
-    
-  //TODO add specific cleanup
   
   GNUNET_free (handle);
 }
@@ -212,6 +205,10 @@ handle_gns_response (void *cls,
   struct MHD_Response *resp;
   json_t *result_array;
   json_t *record_obj;
+  char *record_value;
+  char *result;
+
+  handle->gns_lookup = NULL;
 
   if (GNUNET_NO == was_gns)
   {
@@ -219,7 +216,6 @@ handle_gns_response (void *cls,
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-
   if (0 == rd_count)
   {
     handle->emsg = GNUNET_strdup("No result found");
@@ -228,10 +224,6 @@ handle_gns_response (void *cls,
   }
 
   result_array = json_array();
-  //TODO test break!
-  GNUNET_break (NULL != handle->gns_lookup);
-  handle->gns_lookup = NULL;
-
   for (uint32_t i=0;i<rd_count;i++)
   {
     if ((rd[i].record_type != handle->record_type) &&
@@ -240,7 +232,10 @@ handle_gns_response (void *cls,
       continue;
     }
 
-    record_obj = gnsrecord_to_json (&(rd[i]));
+    record_value = GNUNET_GNSRECORD_value_to_string (rd->record_type,
+                                                    rd->data,
+                                                    rd->data_size);
+    record_obj = json_string(record_value);
     json_array_append (result_array, record_obj);
     json_decref (record_obj);
   }
@@ -256,7 +251,7 @@ handle_gns_response (void *cls,
 
 
 /**
- * Handle gns1 GET request
+ * Handle gns GET request
  *
  * @param con_handle the connection handle
  * @param url the url
@@ -269,6 +264,7 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
 {
   struct RequestHandle *handle = cls;
   struct GNUNET_HashCode key;
+  int conversion_state;
 
   GNUNET_CRYPTO_hash (GNUNET_REST_PARAMETER_GNS_NAME,
                      strlen (GNUNET_REST_PARAMETER_GNS_NAME),
@@ -295,8 +291,22 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  handle->record_type = GNUNET_strdup(
-      GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map,&key));
+  conversion_state = sscanf (
+      GNUNET_CONTAINER_multihashmap_get (con_handle->url_param_map, &key),"%u",
+      &(handle->record_type));
+
+  if((EOF == conversion_state) || (0 == conversion_state))
+  {
+    handle->record_type = GNUNET_GNSRECORD_TYPE_ANY;
+  }
+
+  handle->gns = GNUNET_GNS_connect (cfg);
+  if (NULL == handle->gns)
+  {
+    handle->emsg = GNUNET_strdup ("GNS not available");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    return;
+  }
 
   handle->gns_lookup = GNUNET_GNS_lookup_with_tld (handle->gns,
                                                 handle->name,
@@ -304,6 +314,7 @@ get_gns_cont (struct GNUNET_REST_RequestHandle *con_handle,
                                                 GNUNET_NO,
                                                 &handle_gns_response,
                                                 handle);
+
   if (NULL == handle->gns_lookup)
   {
     handle->emsg = GNUNET_strdup("GNS lookup failed");
@@ -395,19 +406,8 @@ rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
     handle->url[strlen (handle->url)-1] = '\0';
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
 
-
-  handle->gns = GNUNET_GNS_connect (cfg);
-  if (NULL == handle->gns)
-  {
-    handle->emsg = GNUNET_strdup ("GNS not available");
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
-    return;
-  }
-
   init_cont(handle);
-  //TODO connect to specific service
-  //connect ( cfg, [..., &callback_function, handle]);
-  //TODO callback then init_cont(handle)
+
   handle->timeout_task =
     GNUNET_SCHEDULER_add_delayed (handle->timeout,
                                   &do_error,
@@ -424,7 +424,7 @@ rest_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
  * @return NULL on error, otherwise the plugin context
  */
 void *
-libgnunet_plugin_rest_gns1_init (void *cls)
+libgnunet_plugin_rest_gns_init (void *cls)
 {
   static struct Plugin plugin;
   struct GNUNET_REST_Plugin *api;
@@ -447,7 +447,7 @@ libgnunet_plugin_rest_gns1_init (void *cls)
                    MHD_HTTP_METHOD_OPTIONS);
 
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              _("Gns1 REST API initialized\n"));
+              _("Gns REST API initialized\n"));
   return api;
 }
 
@@ -459,7 +459,7 @@ libgnunet_plugin_rest_gns1_init (void *cls)
  * @return always NULL
  */
 void *
-libgnunet_plugin_rest_gns1_done (void *cls)
+libgnunet_plugin_rest_gns_done (void *cls)
 {
   struct GNUNET_REST_Plugin *api = cls;
   struct Plugin *plugin = api->cls;
@@ -468,9 +468,9 @@ libgnunet_plugin_rest_gns1_done (void *cls)
   GNUNET_free_non_null (allow_methods);
   GNUNET_free (api);
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Gns1 REST plugin is finished\n");
+              "Gns REST plugin is finished\n");
   return NULL;
 }
 
-/* end of plugin_rest_gns1.c */
+/* end of plugin_rest_gns.c */
 
index fd6562f1dbb648ae9a8978783e2f3334fd710284..8d525b950412bbc593a7ee30bd7bbda23e5f2b9d 100644 (file)
@@ -1,26 +1,27 @@
 /*
-   This file is part of GNUnet.
-   Copyright (C) 2012-2015 GNUnet e.V.
-
-   GNUnet is free software: you can redistribute it and/or modify it
-   under the terms of the GNU Affero General Public License as published
-   by the Free Software Foundation, either version 3 of the License,
-   or (at your option) any later version.
-
-   GNUnet is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Affero General Public License for more details.
-  
-   You should have received a copy of the GNU Affero General Public License
-   along with this program.  If not, see <http://www.gnu.org/licenses/>.
-   */
+ This file is part of GNUnet.
+ Copyright (C) 2012-2015 GNUnet e.V.
+
+ GNUnet is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GNUnet is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GNUnet; see the file COPYING.  If not, write to the
+ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+ */
 /**
  * @author Martin Schanzenbach
  * @author Philippe Buschmann
  * @file identity/plugin_rest_identity.c
- * @brief GNUnet Namestore REST plugin
- *
+ * @brief GNUnet Identity REST plugin
  */
 
 #include "platform.h"
 #include "gnunet_rest_lib.h"
 #include "microhttpd.h"
 #include <jansson.h>
-#include "gnunet_signatures.h"
 
-/**
- * REST root namespace
- */
 #define GNUNET_REST_API_NS_IDENTITY "/identity"
 
 /**
- * State while collecting all egos
- */
-#define ID_REST_STATE_INIT 0
-
-/**
- * Done collecting egos
- */
-#define ID_REST_STATE_POST_INIT 1
-
-/**
- * Resource type
- */
-#define GNUNET_REST_JSON_IDENTITY_EGO "ego"
-
-/**
- * Name attribute
- */
-#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"
+ * Parameter names
  */
-#define GNUNET_REST_JSON_IDENTITY_NEWNAME "newname"
-
-/**
- * URL parameter to change the subsytem for ego
- */
-#define GNUNET_REST_JSON_IDENTITY_SUBSYSTEM "subsystem"
-
+#define GNUNET_REST_PARAM_PUBKEY "pubkey"
+#define GNUNET_REST_PARAM_SUBSYSTEM "subsystem"
+#define GNUNET_REST_PARAM_NAME "name"
+#define GNUNET_REST_PARAM_NEWNAME "newname"
 
 /**
  * Error messages
  */
+#define GNUNET_REST_ERROR_UNKNOWN "Unknown Error"
 #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
+ * State while collecting all egos
+ */
+#define ID_REST_STATE_INIT 0
+
+/**
+ * Done collecting egos
  */
-#define GNUNET_GNUID_TOKEN_EXPIRATION_MICROSECONDS 300000000
+#define ID_REST_STATE_POST_INIT 1
 
 /**
  * The configuration handle
@@ -129,28 +108,37 @@ struct EgoEntry
   struct GNUNET_IDENTITY_Ego *ego;
 };
 
-
 struct RequestHandle
 {
   /**
-   * Ego list
+   * The data from the REST request
    */
-  struct EgoEntry *ego_head;
+  const char* data;
 
   /**
-   * Ego list
+   * The name to look up
    */
-  struct EgoEntry *ego_tail;
+  char *name;
 
   /**
-   * Handle to the rest connection
+   * the length of the REST data
    */
-  struct GNUNET_REST_RequestHandle *conndata_handle;
+  size_t data_size;
 
   /**
-   * response code
+   * Requested Subsystem
    */
-  int response_code;
+  char *subsystem;
+
+  /**
+   * Ego list
+   */
+  struct EgoEntry *ego_head;
+
+  /**
+   * Ego list
+   */
+  struct EgoEntry *ego_tail;
 
   /**
    * The processing state
@@ -158,7 +146,7 @@ struct RequestHandle
   int state;
 
   /**
-   * Handle to GNS service.
+   * Handle to Identity service.
    */
   struct GNUNET_IDENTITY_Handle *identity_handle;
 
@@ -167,6 +155,11 @@ struct RequestHandle
    */
   struct GNUNET_IDENTITY_Operation *op;
 
+  /**
+   * Rest connection
+   */
+  struct GNUNET_REST_RequestHandle *rest_handle;
+
   /**
    * Desired timeout for the lookup (default is no timeout).
    */
@@ -175,7 +168,7 @@ struct RequestHandle
   /**
    * ID of a task associated with the resolution process.
    */
-  struct GNUNET_SCHEDULER_Task * timeout_task;
+  struct GNUNET_SCHEDULER_Task *timeout_task;
 
   /**
    * The plugin result processor
@@ -187,44 +180,23 @@ struct RequestHandle
    */
   void *proc_cls;
 
-  /**
-   * The name to look up
-   */
-  char *name;
-
-  /**
-   * The subsystem set from REST
-   */
-  char *subsys;
-
   /**
    * The url
    */
   char *url;
 
   /**
-   * The data from the REST request
-   */
-  const char* data;
-
-  /**
-   * the length of the REST data
-   */
-  size_t data_size;
-
-  /**
-   * HTTP method
+   * Error response message
    */
-  const char* method;
+  char *emsg;
 
   /**
-   * Error response message
+   * Reponse code
    */
-  char *emsg;
+  int response_code;
 
 };
 
-
 /**
  * Cleanup lookup handle
  * @param handle Handle to clean up
@@ -234,35 +206,37 @@ cleanup_handle (struct RequestHandle *handle)
 {
   struct EgoEntry *ego_entry;
   struct EgoEntry *ego_tmp;
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Cleaning up\n");
-  if (NULL != handle->name)
-    GNUNET_free (handle->name);
+
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
   if (NULL != handle->timeout_task)
   {
     GNUNET_SCHEDULER_cancel (handle->timeout_task);
     handle->timeout_task = NULL;
   }
-  if (NULL != handle->identity_handle)
-    GNUNET_IDENTITY_disconnect (handle->identity_handle);
-  if (NULL != handle->subsys)
-    GNUNET_free (handle->subsys);
+
+  if (NULL != handle->subsystem)
+    GNUNET_free(handle->subsystem);
   if (NULL != handle->url)
-    GNUNET_free (handle->url);
+    GNUNET_free(handle->url);
   if (NULL != handle->emsg)
-    GNUNET_free (handle->emsg);
+    GNUNET_free(handle->emsg);
+  if (NULL != handle->name)
+    GNUNET_free (handle->name);
+  if (NULL != handle->identity_handle)
+    GNUNET_IDENTITY_disconnect (handle->identity_handle);
+
   for (ego_entry = handle->ego_head;
-       NULL != ego_entry;)
+  NULL != ego_entry;)
   {
     ego_tmp = ego_entry;
     ego_entry = ego_entry->next;
-    GNUNET_free (ego_tmp->identifier);
-    GNUNET_free (ego_tmp->keystring);
-    GNUNET_free (ego_tmp);
+    GNUNET_free(ego_tmp->identifier);
+    GNUNET_free(ego_tmp->keystring);
+    GNUNET_free(ego_tmp);
   }
-  GNUNET_free (handle);
-}
 
+  GNUNET_free(handle);
+}
 
 /**
  * Task run on errors.  Reports an error and cleans up everything.
@@ -277,10 +251,12 @@ do_error (void *cls)
   char *json_error;
 
   if (NULL == handle->emsg)
-    handle->emsg = GNUNET_strdup("Unknown Error");
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_UNKNOWN);
 
   GNUNET_asprintf (&json_error, "{\"error\": \"%s\"}", handle->emsg);
-  handle->response_code = MHD_HTTP_OK;
+
+  if (0 == handle->response_code)
+    handle->response_code = MHD_HTTP_OK;
 
   resp = GNUNET_REST_create_response (json_error);
   handle->proc (handle->proc_cls, resp, handle->response_code);
@@ -288,9 +264,8 @@ do_error (void *cls)
   GNUNET_free(json_error);
 }
 
-
 /**
- * Callback for IDENTITY_get()
+ * Callback for GET Request with subsystem
  *
  * @param cls the RequestHandle
  * @param ego the Ego found
@@ -298,173 +273,153 @@ do_error (void *cls)
  * @param name the id of the ego
  */
 static void
-get_ego_for_subsys (void *cls,
-                    struct GNUNET_IDENTITY_Ego *ego,
-                    void **ctx,
-                    const char *name)
+ego_get_for_subsystem (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx,
+                      const char *name)
 {
   struct RequestHandle *handle = cls;
-  struct EgoEntry *ego_entry;
   struct MHD_Response *resp;
+  struct GNUNET_CRYPTO_EcdsaPublicKey public_key;
   json_t *json_root;
-  json_t *json_ego;
-  json_t *name_json;
   char *result_str;
-  size_t index;
-
-  json_root = json_array();
+  char *public_key_string;
 
-  for (ego_entry = handle->ego_head;
-       NULL != ego_entry;
-       ego_entry = ego_entry->next)
+  if(NULL == ego)
   {
-    if ( (NULL != name) && (0 != strcmp (name, ego_entry->identifier)) )
-      continue;
-    if (NULL == name)
-      continue;
-
-    json_ego = json_object();
-    name_json = json_string (ego_entry->identifier);
-    json_object_set_new(json_ego, GNUNET_REST_JSON_IDENTITY_EGO, name_json);
-    json_array_append(json_root, json_ego);
-
-    break;
-  }
-
-  if (0 == json_array_size(json_root))
-  {
-    json_decref(json_root);
-    handle->emsg = GNUNET_strdup("No identity matches results!");
+    handle->emsg = GNUNET_strdup("No identity found for subsystem");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
 
-  result_str = json_dumps(json_root, 0);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str);
+  GNUNET_IDENTITY_ego_get_public_key(ego,&public_key);
+  public_key_string = GNUNET_CRYPTO_ecdsa_public_key_to_string(&public_key);
+
+  // create json with subsystem identity
+  json_root = json_object ();
+  json_object_set_new (json_root, GNUNET_REST_PARAM_PUBKEY, json_string(public_key_string));
+  json_object_set_new (json_root, GNUNET_REST_PARAM_NAME, json_string(name));
+
+  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);
 
-  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);
+  GNUNET_free(result_str);
+  GNUNET_free(public_key_string);
   cleanup_handle (handle);
 }
 
-
 /**
- * Create a response with requested ego(s)
+ * Handle identity GET request
  *
- * @param con the Rest handle
- * @param url the requested url
- * @param cls the request handle
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
  */
-static void
-ego_info_response (struct GNUNET_REST_RequestHandle *con,
-                   const char *url,
-                   void *cls)
+void
+ego_get (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
+        void *cls)
 {
-  const char *egoname;
-  char *result_str;
-  char *subsys_val;
-  char *keystring;
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
   struct GNUNET_HashCode key;
   struct MHD_Response *resp;
+  char *keystring;
+  const char *egoname;
   json_t *json_root;
   json_t *json_ego;
-  json_t *name_str;
+  char *result_str;
   size_t index;
 
-  if (GNUNET_NO == GNUNET_REST_namespace_match (handle->url, GNUNET_REST_API_NS_IDENTITY))
-  {
-    resp = GNUNET_REST_create_response (NULL);
-    handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
-    cleanup_handle (handle);
+  //if subsystem
+  GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_SUBSYSTEM,
+                     strlen (GNUNET_REST_PARAM_SUBSYSTEM), &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (
+         handle->rest_handle->url_param_map, &key))
+  {
+    handle->subsystem = GNUNET_strdup(
+       GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map,
+                                          &key));
+    GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n",
+              handle->subsystem);
+
+    handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
+                                     handle->subsystem, &ego_get_for_subsystem,
+                                     handle);
+    if (NULL == handle->op)
+    {
+      handle->emsg = GNUNET_strdup("No identity found for subsystem");
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
+    }
     return;
   }
   egoname = NULL;
   keystring = NULL;
-  if (strlen (GNUNET_REST_API_NS_IDENTITY) < strlen (handle->url))
+
+  //if only one identity requested
+  GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_PUBKEY,
+                     strlen (GNUNET_REST_PARAM_PUBKEY), &key);
+  if ( GNUNET_YES
+      == GNUNET_CONTAINER_multihashmap_contains (
+         handle->rest_handle->url_param_map, &key))
   {
-    keystring = &handle->url[strlen (GNUNET_REST_API_NS_IDENTITY)+1];
-    //Return all egos
+    keystring = GNUNET_CONTAINER_multihashmap_get (
+       handle->rest_handle->url_param_map, &key);
+
     for (ego_entry = handle->ego_head;
-         NULL != ego_entry;
-         ego_entry = ego_entry->next)
+    NULL != ego_entry; ego_entry = ego_entry->next)
     {
-      if ( (NULL != keystring) && (0 != strcmp (keystring, ego_entry->keystring)) )
-        continue;
+      if ((NULL != keystring)
+         && (0 != strcmp (keystring, ego_entry->keystring)))
+       continue;
       egoname = ego_entry->identifier;
     }
   }
 
-  if ( NULL == egoname ) {
-    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,
-                                                 &key) )
-    {
-      subsys_val = GNUNET_CONTAINER_multihashmap_get (handle->conndata_handle->url_param_map,
-                                                      &key);
-      if (NULL != subsys_val)
-      {
-        GNUNET_asprintf (&handle->subsys, "%s", subsys_val);
-        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Looking for %s's ego\n", subsys_val);
-        handle->op = GNUNET_IDENTITY_get (handle->identity_handle,
-                                          handle->subsys,
-                                          &get_ego_for_subsys,
-                                          handle);
-        return;
-      }
-    }
-  }
-
-  json_root = json_array();
-
-  //Return all egos
+  json_root = json_array ();
+  //Return ego/egos
   for (ego_entry = handle->ego_head;
-       NULL != ego_entry;
-       ego_entry = ego_entry->next)
+  NULL != ego_entry; ego_entry = ego_entry->next)
   {
-    if ( (NULL != egoname) && (0 != strcmp (egoname, ego_entry->identifier)) )
-      continue;
-
-    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);
-    json_object_set_new( json_ego, "name", name_str);
+    //if only one ego requested
+    if ((NULL != egoname)){
+      if(0 != strcmp (egoname, ego_entry->identifier)){
+       continue;
+      }
+    }
 
-    json_array_append( json_root, json_ego );
+    json_ego = json_object ();
+    json_object_set_new (json_ego,
+    GNUNET_REST_PARAM_PUBKEY,
+                        json_string (ego_entry->keystring));
+    json_object_set_new (json_ego,
+    GNUNET_REST_PARAM_NAME,
+                        json_string (ego_entry->identifier));
+    json_array_append (json_root, json_ego);
   }
 
-  if ((size_t)0 == json_array_size(json_root))
+  if ((size_t) 0 == json_array_size (json_root))
   {
     json_decref (json_root);
-    handle->emsg = GNUNET_strdup ("No identities found!");
+    handle->emsg = GNUNET_strdup("No identities found!");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
 
-  result_str = json_dumps(json_root, 0);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", 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);
 
   //delete json_objects in json_array with macro
   json_array_foreach(json_root, index, json_ego )
   {
-    json_decref(json_ego);
+    json_decref (json_ego);
   }
   json_decref (json_root);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
-  GNUNET_free (result_str);
+  GNUNET_free(result_str);
   cleanup_handle (handle);
 }
 
@@ -483,7 +438,7 @@ do_finished (void *cls, const char *emsg)
   handle->op = NULL;
   if (NULL != emsg)
   {
-    handle->emsg = GNUNET_strdup (emsg);
+    handle->emsg = GNUNET_strdup(emsg);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
@@ -493,288 +448,280 @@ do_finished (void *cls, const char *emsg)
 }
 
 /**
- * Create a new ego
+ * Handle identity PUT request
  *
- * @param con rest handle
- * @param url url
- * @param cls request handle
+ * @param con_handle the connection handle
+ * @param url the url
+ * @param cls the RequestHandle
  */
-static void
-ego_create_cont (struct GNUNET_REST_RequestHandle *con,
-                 const char *url,
-                 void *cls)
+void
+ego_edit (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
+           void *cls)
 {
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
+  struct EgoEntry *ego_entry_tmp;
   struct MHD_Response *resp;
-  json_t *egoname_json;
+  json_t *subsys_json;
+  json_t *name_json;
+  json_t *key_json;
   json_t *data_js;
   json_error_t err;
-  const char* egoname;
-  char term_data[handle->data_size+1];
-
-  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;
-  }
+  const char *keystring;
+  const char *subsys;
+  const char *newname;
+  char term_data[handle->data_size + 1];
+  int ego_exists = GNUNET_NO;
 
+  //if no data
   if (0 >= handle->data_size)
   {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA);
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
+  //if not json
   term_data[handle->data_size] = '\0';
-  GNUNET_memcpy (term_data, handle->data, handle->data_size);
-  data_js = json_loads (term_data,
-                        JSON_DECODE_ANY,
-                        &err);
-
-
+  GNUNET_memcpy(term_data, handle->data, handle->data_size);
+  data_js = json_loads (term_data,JSON_DECODE_ANY,&err);
   if (NULL == data_js)
   {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID);
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  //instead of parse
   if (!json_is_object(data_js))
   {
-    json_decref(data_js);
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID);
+    json_decref (data_js);
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-
-  if (1 != json_object_size (data_js))
+  //json must contain pubkey and (subsystem or name)
+  if (2 != json_object_size (data_js))
   {
     json_decref (data_js);
-    handle->emsg = GNUNET_strdup("Provided resource count invalid");
+    handle->emsg = GNUNET_strdup("Resource amount invalid");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
 
-  egoname_json = json_object_get (data_js, GNUNET_REST_JSON_IDENTITY_NAME);
-  if (!json_is_string (egoname_json))
+  key_json = json_object_get (data_js, GNUNET_REST_PARAM_PUBKEY);
+  if ((NULL == key_json) || !json_is_string(key_json))
   {
     json_decref (data_js);
-    handle->emsg = GNUNET_strdup ("No name provided");
+    handle->emsg = GNUNET_strdup("Missing element pubkey");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-  egoname = json_string_value (egoname_json);
-  if(0 >= strlen(egoname))
+  keystring = json_string_value (key_json);
+
+  for (ego_entry = handle->ego_head;
+  NULL != ego_entry; ego_entry = ego_entry->next)
+  {
+    if (0 != strcasecmp (keystring, ego_entry->keystring))
+      continue;
+    ego_exists = GNUNET_YES;
+    break;
+  }
+
+  if (GNUNET_NO == ego_exists)
   {
     json_decref (data_js);
-    handle->emsg = GNUNET_strdup ("No name provided");
-    GNUNET_SCHEDULER_add_now (&do_error, handle);
+    resp = GNUNET_REST_create_response (NULL);
+    handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
+    cleanup_handle (handle);
     return;
   }
-  for (ego_entry = handle->ego_head;
-       NULL != ego_entry;
-       ego_entry = ego_entry->next)
+  //This is a rename
+  name_json = json_object_get (data_js, GNUNET_REST_PARAM_NEWNAME);
+  if ((NULL != name_json) && json_is_string(name_json))
   {
-    if (0 == strcasecmp (egoname, ego_entry->identifier))
+    newname = json_string_value (name_json);
+    if (0 >= strlen (newname))
     {
       json_decref (data_js);
-      resp = GNUNET_REST_create_response (NULL);
-      handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
-      cleanup_handle (handle);
+      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)
+    {
+      if (0 == strcasecmp (newname, ego_entry_tmp->identifier)
+         && 0 != strcasecmp (keystring, ego_entry_tmp->keystring))
+      {
+       //Ego with same name not allowed
+       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);
+    json_decref (data_js);
+    return;
+  }
+
+  //Set subsystem
+  subsys_json = json_object_get (data_js, GNUNET_REST_PARAM_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("Invalid subsystem name");
+      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      return;
+    }
+    GNUNET_asprintf (&handle->subsystem, "%s", subsys);
+    json_decref (data_js);
+    handle->response_code = MHD_HTTP_NO_CONTENT;
+    handle->op = GNUNET_IDENTITY_set (handle->identity_handle, handle->subsystem,
+                                     ego_entry->ego, &do_finished, handle);
+    return;
   }
-  GNUNET_asprintf (&handle->name, "%s", egoname);
   json_decref (data_js);
-  handle->response_code = MHD_HTTP_CREATED;
-  handle->op = GNUNET_IDENTITY_create (handle->identity_handle,
-                                       handle->name,
-                                       &do_finished,
-                                       handle);
+  handle->emsg = GNUNET_strdup("Subsystem not provided");
+  GNUNET_SCHEDULER_add_now (&do_error, handle);
 }
 
-
 /**
- * Handle ego edit request
+ * Handle identity POST request
  *
- * @param con rest connection handle
- * @param url the url that is requested
+ * @param con_handle the connection handle
+ * @param url the url
  * @param cls the RequestHandle
  */
-static void
-ego_edit_cont (struct GNUNET_REST_RequestHandle *con,
-               const char *url,
-               void *cls)
+void
+ego_create (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
+           void *cls)
 {
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
-  struct EgoEntry *ego_entry_tmp;
   struct MHD_Response *resp;
-  json_t *subsys_json;
-  json_t *name_json;
+  json_t *egoname_json;
   json_t *data_js;
   json_error_t err;
-  const char *keystring;
-  const char *subsys;
-  const char *newname;
-  char term_data[handle->data_size+1];
-  int ego_exists = GNUNET_NO;
+  const char* egoname;
+  char term_data[handle->data_size + 1];
 
-  if (strlen (GNUNET_REST_API_NS_IDENTITY) > strlen (handle->url))
+  if (strlen (GNUNET_REST_API_NS_IDENTITY) != strlen (handle->url))
   {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID);
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_RESOURCE_INVALID);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
 
-  keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY)+1];
-
-  for (ego_entry = handle->ego_head;
-       NULL != ego_entry;
-       ego_entry = ego_entry->next)
-  {
-    if (0 != strcasecmp (keystring, ego_entry->keystring))
-      continue;
-    ego_exists = GNUNET_YES;
-    break;
-  }
-
-  if (GNUNET_NO == ego_exists)
-  {
-    resp = GNUNET_REST_create_response (NULL);
-    handle->proc (handle->proc_cls, resp, MHD_HTTP_NOT_FOUND);
-    cleanup_handle (handle);
-    return;
-  }
-
   if (0 >= handle->data_size)
   {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA);
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_NO_DATA);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-
   term_data[handle->data_size] = '\0';
-  GNUNET_memcpy (term_data, handle->data, handle->data_size);
+  GNUNET_memcpy(term_data, handle->data, handle->data_size);
   data_js = json_loads (term_data,
-                        JSON_DECODE_ANY,
-                        &err);
+  JSON_DECODE_ANY,
+                       &err);
+
   if (NULL == data_js)
   {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_NO_DATA);
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
+  //instead of parse
   if (!json_is_object(data_js))
   {
     json_decref (data_js);
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_DATA_INVALID);
+    handle->emsg = GNUNET_strdup(GNUNET_REST_ERROR_DATA_INVALID);
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
 
-  if (1 != json_object_size(data_js))
+  if (1 != json_object_size (data_js))
   {
     json_decref (data_js);
-    handle->emsg = GNUNET_strdup ("Resource amount invalid");
+    handle->emsg = GNUNET_strdup("Provided resource count invalid");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
 
-  //This is a rename
-  name_json = json_object_get (data_js, GNUNET_REST_JSON_IDENTITY_NEWNAME);
-  if ((NULL != name_json) && json_is_string (name_json))
+  egoname_json = json_object_get (data_js, GNUNET_REST_PARAM_NAME);
+  if (!json_is_string(egoname_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)
-    {
-      if (0 == strcasecmp (newname, ego_entry_tmp->identifier) &&
-          0 != strcasecmp (keystring, ego_entry_tmp->keystring))
-      {
-        //Ego with same name not allowed
-       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);
     json_decref (data_js);
+    handle->emsg = GNUNET_strdup("No name provided");
+    GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
-
-  //Set subsystem
-  subsys_json = json_object_get (data_js, GNUNET_REST_JSON_IDENTITY_SUBSYSTEM);
-  if ( (NULL != subsys_json) && json_is_string (subsys_json))
+  egoname = json_string_value (egoname_json);
+  if (0 >= strlen (egoname))
   {
-    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;
+  }
+  for (ego_entry = handle->ego_head;
+  NULL != ego_entry; ego_entry = ego_entry->next)
+  {
+    if (0 == strcasecmp (egoname, ego_entry->identifier))
     {
       json_decref (data_js);
-      handle->emsg = GNUNET_strdup ("No name provided");
-      GNUNET_SCHEDULER_add_now (&do_error, handle);
+      resp = GNUNET_REST_create_response (NULL);
+      handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT);
+      cleanup_handle (handle);
       return;
     }
-    GNUNET_asprintf (&handle->subsys, "%s", subsys);
-    json_decref (data_js);
-    handle->response_code = MHD_HTTP_NO_CONTENT;
-    handle->op = GNUNET_IDENTITY_set (handle->identity_handle,
-                                      handle->subsys,
-                                      ego_entry->ego,
-                                      &do_finished,
-                                      handle);
-    return;
   }
+  GNUNET_asprintf (&handle->name, "%s", egoname);
   json_decref (data_js);
-  handle->emsg = GNUNET_strdup ("Subsystem not provided");
-  GNUNET_SCHEDULER_add_now (&do_error, handle);
+  handle->response_code = MHD_HTTP_CREATED;
+  handle->op = GNUNET_IDENTITY_create (handle->identity_handle, handle->name,
+                                      &do_finished, handle);
 }
 
 /**
- * Handle ego delete request
+ * Handle identity 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,
-                 void *cls)
+ego_delete (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
+           void *cls)
 {
   const char *keystring;
   struct EgoEntry *ego_entry;
+  struct GNUNET_HashCode key;
   struct MHD_Response *resp;
   struct RequestHandle *handle = cls;
   int ego_exists = GNUNET_NO;
 
-  if (strlen (GNUNET_REST_API_NS_IDENTITY) >= strlen (handle->url))
+  //if only one identity requested
+  GNUNET_CRYPTO_hash (GNUNET_REST_PARAM_PUBKEY,
+                     strlen (GNUNET_REST_PARAM_PUBKEY), &key);
+  if ( GNUNET_NO
+      == GNUNET_CONTAINER_multihashmap_contains (
+         handle->rest_handle->url_param_map, &key))
   {
-    handle->emsg = GNUNET_strdup (GNUNET_REST_ERROR_RESOURCE_INVALID);
+    handle->emsg = GNUNET_strdup("Missing parameter pubkey");
     GNUNET_SCHEDULER_add_now (&do_error, handle);
     return;
   }
 
-  keystring = &handle->url[strlen(GNUNET_REST_API_NS_IDENTITY)+1];
+  keystring = GNUNET_CONTAINER_multihashmap_get (
+      handle->rest_handle->url_param_map,&key);
   for (ego_entry = handle->ego_head;
-       NULL != ego_entry;
-       ego_entry = ego_entry->next)
+  NULL != ego_entry; ego_entry = ego_entry->next)
   {
     if (0 != strcasecmp (keystring, ego_entry->keystring))
       continue;
@@ -790,13 +737,11 @@ ego_delete_cont (struct GNUNET_REST_RequestHandle *con_handle,
   }
   handle->response_code = MHD_HTTP_NO_CONTENT;
   handle->op = GNUNET_IDENTITY_delete (handle->identity_handle,
-                                       ego_entry->identifier,
-                                       &do_finished,
-                                       handle);
+                                      ego_entry->identifier, &do_finished,
+                                      handle);
 
 }
 
-
 /**
  * Respond to OPTIONS request
  *
@@ -805,18 +750,15 @@ ego_delete_cont (struct GNUNET_REST_RequestHandle *con_handle,
  * @param cls the RequestHandle
  */
 static void
-options_cont (struct GNUNET_REST_RequestHandle *con_handle,
-              const char* url,
-              void *cls)
+options_cont (struct GNUNET_REST_RequestHandle *con_handle, const char* url,
+             void *cls)
 {
   struct MHD_Response *resp;
   struct RequestHandle *handle = cls;
 
   //For now, independent of path return all options
   resp = GNUNET_REST_create_response (NULL);
-  MHD_add_response_header (resp,
-                           "Access-Control-Allow-Methods",
-                           allow_methods);
+  MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods);
   handle->proc (handle->proc_cls, resp, MHD_HTTP_OK);
   cleanup_handle (handle);
   return;
@@ -832,18 +774,17 @@ init_cont (struct RequestHandle *handle)
 {
   struct GNUNET_REST_RequestHandlerError err;
   static const struct GNUNET_REST_RequestHandler handlers[] = {
-    {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_info_response},
-    {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create_cont},
-    {MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY, &ego_edit_cont},
-    {MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_IDENTITY, &ego_delete_cont},
-    {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont},
-    GNUNET_REST_HANDLER_END
+      { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY, &ego_get },
+      { MHD_HTTP_METHOD_PUT, GNUNET_REST_API_NS_IDENTITY, &ego_edit },
+      { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY, &ego_create },
+      { MHD_HTTP_METHOD_DELETE, GNUNET_REST_API_NS_IDENTITY, &ego_delete },
+      { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY, &options_cont },
+      GNUNET_REST_HANDLER_END
   };
 
-  if (GNUNET_NO == GNUNET_REST_handle_request (handle->conndata_handle,
-                                                  handlers,
-                                                  &err,
-                                                  handle))
+  if (GNUNET_NO
+      == GNUNET_REST_handle_request (handle->rest_handle, handlers, &err,
+                                    handle))
   {
     handle->response_code = err.error_code;
     GNUNET_SCHEDULER_add_now (&do_error, handle);
@@ -884,10 +825,8 @@ init_cont (struct RequestHandle *handle)
  *                   must thus no longer be used
  */
 static void
-list_ego (void *cls,
-          struct GNUNET_IDENTITY_Ego *ego,
-          void **ctx,
-          const char *identifier)
+init_egos (void *cls, struct GNUNET_IDENTITY_Ego *ego, void **ctx,
+          const char *identifier)
 {
   struct RequestHandle *handle = cls;
   struct EgoEntry *ego_entry;
@@ -899,16 +838,16 @@ list_ego (void *cls,
     init_cont (handle);
     return;
   }
-  if (ID_REST_STATE_INIT == handle->state) {
-    ego_entry = GNUNET_new (struct EgoEntry);
+  if (ID_REST_STATE_INIT == handle->state)
+  {
+    ego_entry = GNUNET_new(struct EgoEntry);
     GNUNET_IDENTITY_ego_get_public_key (ego, &pk);
-    ego_entry->keystring =
-      GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
+    ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk);
     ego_entry->ego = ego;
     GNUNET_asprintf (&ego_entry->identifier, "%s", identifier);
-    GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry);
+    GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head, handle->ego_tail,
+                                    ego_entry);
   }
-
 }
 
 /**
@@ -923,39 +862,30 @@ list_ego (void *cls,
  * @return GNUNET_OK if request accepted
  */
 static void
-rest_identity_process_request(struct GNUNET_REST_RequestHandle *conndata_handle,
-                              GNUNET_REST_ResultProcessor proc,
-                              void *proc_cls)
+rest_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
+                     GNUNET_REST_ResultProcessor proc, void *proc_cls)
 {
-  struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
-
-
+  struct RequestHandle *handle = GNUNET_new(struct RequestHandle);
 
+  handle->response_code = 0;
   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;
-  handle->conndata_handle = conndata_handle;
-  handle->data = conndata_handle->data;
-  handle->data_size = conndata_handle->data_size;
-  handle->method = conndata_handle->method;
-  GNUNET_asprintf (&handle->url, "%s", conndata_handle->url);
-  if (handle->url[strlen (handle->url)-1] == '/')
-    handle->url[strlen (handle->url)-1] = '\0';
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Connecting...\n");
-  handle->identity_handle = GNUNET_IDENTITY_connect (cfg,
-                                                     &list_ego,
-                                                     handle);
-  handle->timeout_task =
-    GNUNET_SCHEDULER_add_delayed (handle->timeout,
-                                  &do_error,
-                                  handle);
-
-
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Connected\n");
+  handle->rest_handle = rest_handle;
+  handle->data = rest_handle->data;
+  handle->data_size = rest_handle->data_size;
+
+  handle->url = GNUNET_strdup(rest_handle->url);
+  if (handle->url[strlen (handle->url) - 1] == '/')
+    handle->url[strlen (handle->url) - 1] = '\0';
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
+
+  handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &init_egos, handle);
+
+  handle->timeout_task = GNUNET_SCHEDULER_add_delayed (handle->timeout,
+                                                      &do_error, handle);
+
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
 }
 
 /**
@@ -972,27 +902,24 @@ libgnunet_plugin_rest_identity_init (void *cls)
 
   cfg = cls;
   if (NULL != plugin.cfg)
-    return NULL;                /* can only initialize once! */
-  memset (&plugin, 0, sizeof (struct Plugin));
+    return NULL; /* can only initialize once! */
+  memset (&plugin, 0, sizeof(struct Plugin));
   plugin.cfg = cfg;
-  api = GNUNET_new (struct GNUNET_REST_Plugin);
+  api = GNUNET_new(struct GNUNET_REST_Plugin);
   api->cls = &plugin;
   api->name = GNUNET_REST_API_NS_IDENTITY;
-  api->process_request = &rest_identity_process_request;
-  GNUNET_asprintf (&allow_methods,
-                   "%s, %s, %s, %s, %s",
-                   MHD_HTTP_METHOD_GET,
-                   MHD_HTTP_METHOD_POST,
-                   MHD_HTTP_METHOD_PUT,
-                   MHD_HTTP_METHOD_DELETE,
-                   MHD_HTTP_METHOD_OPTIONS);
-
-  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
-              _("Identity REST API initialized\n"));
+  api->process_request = &rest_process_request;
+  GNUNET_asprintf (&allow_methods, "%s, %s, %s, %s, %s",
+                  MHD_HTTP_METHOD_GET,
+                  MHD_HTTP_METHOD_POST,
+                  MHD_HTTP_METHOD_PUT,
+                  MHD_HTTP_METHOD_DELETE,
+                  MHD_HTTP_METHOD_OPTIONS);
+
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, _("Identity REST API initialized\n"));
   return api;
 }
 
-
 /**
  * Exit point from the plugin.
  *
@@ -1004,13 +931,13 @@ libgnunet_plugin_rest_identity_done (void *cls)
 {
   struct GNUNET_REST_Plugin *api = cls;
   struct Plugin *plugin = api->cls;
-
   plugin->cfg = NULL;
-  GNUNET_free_non_null (allow_methods);
-  GNUNET_free (api);
-  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
-              "Identity REST plugin is finished\n");
+
+  GNUNET_free_non_null(allow_methods);
+  GNUNET_free(api);
+  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Identity REST plugin is finished\n");
   return NULL;
 }
 
-/* end of plugin_rest_gns.c */
+/* end of plugin_rest_identity.c */
+
diff --git a/src/identity/test_plugin_rest_identity.sh b/src/identity/test_plugin_rest_identity.sh
new file mode 100755 (executable)
index 0000000..b48becc
--- /dev/null
@@ -0,0 +1,216 @@
+#!/usr/bin/bash
+
+#First, start gnunet-arm and the rest-service. Make sure, no identity exists
+#Exit 0 means success, exit 1 means failed test
+
+#No test for subsystem available
+
+link_to_api="http://localhost:7776/identity"
+wrong_link="http://localhost:7776/idenmmmy"
+wrong_link2="http://localhost:7776/identityandmore"
+
+#Test GET (multiple identities) for error when no identity exists
+#The next test case can be ignored if you have already added identities
+cache="$(curl --silent "$link_to_api" | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+#Test POST success code, error response code and error json
+#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
+    exit 1
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":\"Test\"}" 2>&1 | grep "HTTP/1.1 409")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "wrong" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "[{}]" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":\"Test\",\"other\":\"Test\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"nam\":\"Test\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":123}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "POST" "$link_to_api" --data "{\"name\":""}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+
+#Test GET (multiple identities) for success and error json
+cache="$(curl --silent "$link_to_api" | grep "error")"
+if [ "" != "$cache" ]
+then
+    exit 1
+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}?pubkey=$id" | grep "error")"
+if [ "" != "$cache" ]
+then
+    exit 1
+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}?pubkey=$id" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" != "$cache" ]
+then
+    exit 1
+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}?pubkey=df1" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "DELETE" "${link_to_api}?pubke=$id" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+#Test PUT success code, error response codes and error json
+cache="$(curl -v -X "PUT" "${link_to_api}" --data "{\"newname\":\"NewTest\",\"pubkey\":\"${id}\"}" 2>&1 | grep "HTTP/1.1 204")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "PUT" "${link_to_api}" --data "{\"newname\":\"NewNewTest\",\"pubkey\":\"${id}1\"}" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+# feature: you can rename your identity with its own name.
+# cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newname\":\"NewTest\",\"pubkey\":\"${id}\"}" 2>&1 | grep "error")"
+# if [ "" == "$cache" ]
+# then
+#     exit 1
+# fi
+
+
+cache="$(curl -v -X "PUT" "$link_to_api" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api" --data "wrong" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api" --data "[{}]" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newname\":\"Test\",\"other\":\"Test\",\"pubkey\":\"${id}\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newnam\":\"Test\",\"pubkey\":\"${id}\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newname\":\"Test\",\"pubke\":\"${id}\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newname\":123,\"pubkey\":\"${id}\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -v -X "PUT" "$link_to_api" --data "{\"newname\":"",\"pubkey\":\"${id}\"}" 2>&1 | grep "error")"
+if [ "" == "$cache" ]
+then
+    exit 1
+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
+    exit 1
+fi
+
+cache="$(curl -X "PUT" -v "$wrong_link" --data "{\"newname\":\"Testing\",\"pubkey\":\"${id}\"}" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -X "POST" -v "$wrong_link?pubkey=$id" --data "{\"name\":\"Test\"}" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+cache="$(curl -X "DELETE" -v "${wrong_link}?pubkey=$id" 2>&1 | grep "HTTP/1.1 404")"
+if [ "" == "$cache" ]
+then
+    exit 1
+fi
+
+gnunet-identity -D NewTest
+
+exit 0