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